TwoMillion是HackThebox上的Linux靶机,难度为Easy。完成靶机攻击除了基础知识之外,需要一些js和加解密的知识。

靶场信息

靶场涉及到的一些技术:

  • Linux探测
  • js分析
  • 加解密知识
  • 字典扫描
  • API测试
  • Linux提权(CVE-2023-0386)

信息收集

端口扫描

root@kali > nmap -n --min-rate 2000 -T4 -p- --max-retries 10 -Pn -sC -sV 10.129.229.66
Starting Nmap 7.93 ( https://nmap.org ) at 2023-06-10 13:30 CST
Stats: 0:01:23 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan
Connect Scan Timing: About 44.11% done; ETC: 13:33 (0:01:45 remaining)
Nmap scan report for 10.129.229.66
Host is up (0.26s latency).
Not shown: 63980 filtered tcp ports (no-response), 1553 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open tcpwrapped
|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)
80/tcp open tcpwrapped

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 262.61 seconds

靶机环境开放了22和80端口。

WEB服务

直接访问IP地址时,会跳转至域名,添加到hosts文件之后可以访问。
10.129.229.66 2million.htb

注册账户

尝试注册用户时,会提示需要邀请码。看网页源代码会将邀请码存入本地存储,随机输入邀请码时提示验证码无效。

js文件inviteapi.min.js中存在混淆的代码,将eval替换为alert可以查看原始内容。

js代码定义了verifyInviteCode函数和makeInviteCode函数。

function makeInviteCode() {
$.ajax({
type: "POST",
dataType: "json",
url: '/api/v1/invite/how/to/generate',
success: function(response) {
console.log(response)
},
error: function(response) {
console.log(response)
}
})
}

直接在浏览器console里调用makeInviteCode函数。

得到响应如下:

{
"0": 200,
"success": 1,
"data": {
"data": "Va beqre gb trarengr gur vaivgr pbqr, znxr n CBFG erdhrfg gb \/ncv\/i1\/vaivgr\/trarengr",
"enctype": "ROT13"
},
"hint": "Data is encrypted ... We should probbably check the encryption type in order to decrypt it..."
}

使用ROT13解密出data字段内容为:
In order to generate the invite code, make a POST request to /api/v1/invite/generate

按内容提示,发送POST包,成功得到邀请码,并进行注册。
获取邀请码

注册

登录之后的尝试

登录之后界面大部分连接无效,我做了如下尝试、但都没有成功:

  • 用户名字段的XSS,确实可以获取信息,但更多的类似于Self-XSS,无实质用途
  • 用户名字段的SSTI,失败
  • 使用ffuf,带Cookie的WEB目录扫描,扫描了根目录、home目录和api目录,均没有结果
  • 使用ffuf,对2million.htb的子域名进行扫描
  • 对登录后网页的js文件htb-backend.min.js中提到的各类API接口进行测试

ffuf扫描记录

后端接口信息

官方题解里给的线索

上一部分花了很长时间,却没有什么收获,内心沮丧,跑完步之后看了下官方题解。

官方题解里给的思路是直接访问/api,会给出API的路径信息。

扫描失败复盘

我前面扫描过带Cookies扫描过根目录,但是没有得到信息,我猜测有两种可能性:

  1. 字典里面有logout,相当于是注销登录了,导致后面请求都是登录失败的状态。这个问题确实遇到了,实际扫描时也得注意。
  2. 字典里面压根就没有api,后面发现确实没有这个值,有点离谱😭

raft-medium-files.txt扫描结果

后面我换了个字典扫描了下,结果都出来了🤣。
common.txt字典扫描结果

这两个结果的对比,得到的体会是在扫描路径、文件时,字典的选择特别重要

管理员API接口

访问/api时提示查看/api/v1,其中感兴趣的和管理员相关的接口。
管理员接口信息

直接访问鉴权时会提示不是管理员:

尝试生成VPN时返回401状态码:

管理员接口提权

/api/v1/admin/settings/update数据时提示数据类型不对,改为json之后提示缺少内容。
content type 错误

缺少字段

按照提示,设置好邮箱和是否为管理员字段后,成功将当前用户设置为管理员。

此时,再次尝试生成VPN证书已不再返回401错误。

按上面步骤重新设置内容格式为json、补全字段后,可成功生成VPN证书。

猜测生成证书的方式可能直接拼接Linux命令、存在命令注入。直接尝试用ls命令时失败,curl跑OOB时成功得到信息,确认存在命令注入。

初始权限

使用上述命令注入漏洞成功得到反弹shell,查看/etc/passwd发现一般用户是admin

当前用户为www-data,使用grep命令查找是否存在硬编码的密码信息。

成功发现密码,尝试以该密码登录admin用户的SSH,成功。

用户权限

SSH登录后,发现无法使用sudo。

查找当前用户组的文件,查看邮箱发现有漏洞修复的邮件。

根据提示找到对应的exp,进行提权。

root权限

exp说明,成功提权为root。

总结

回顾整个过程,总感觉差一点什么东西,很可惜,特别是路径扫描那里。
类似于我原来使用john爆破密码时遇到的问题一样,同样的字典为什么别人可以猜解出来
都是一些特别细节的地方,不是很宏观、抽象地认为应该怎么去做,也有点类似于攻防演练的防守。

就靶机而言,拿到初始权限部分稍微有点复杂,其他部分相对来说还是很容易的。