Hackthebox Season7 Code writeup
一、信息收集
先pingIP测试连通性,连通性正常的情况下使用nmap -sV -sC -A 10.10.11.62 -Pn 扫描ip,得到结果

发现开放了5000端口,网站标题写明了为python代码执行的页面,访问页面,十分干净的代码执行网站

使用dirsearch和whatweb收集信息,并没有发现有价值的东西,但能确定这是Gunicorn,一个python沙箱


测试右上角的登录注册无果,看来应该是需要利用执行代码来更进一步,试着进行沙盒逃逸绕过过滤限制。
输入常见的python代码生成reverseShell,但是很不幸的发现,import、eval、os、system、bulitins等关键字全都被过滤,由于本人能力问题实在不想去绕,直接丢给万能的AI问一下该怎么做
AI叫我可以试试print(globals()) # 查看所有全局变量 print(locals()) # 查看局部变量 ,输入并执行后发现globals和locals都没有被过滤。
将返回结果丢给AI,分析结果得出SQLAlchemy存在但User.query不可用,返回错误说明 session 可能未初始化但db和User模型已被加载(从globals()输出可见)。

于是可以试着利用SqlAlchemy进行查询,输入users = db.session.query(User).all() print([(u.id, u.username, u.password) for u in users]),得到查询结果

将密码进行解密,这里我使用了 https://crackstation.net/ 网站,解密得到martin用户密码 nafeelswordsmaster

进行ssh登录,成功获取到立足点

二、userFlag
进入家目录下的backups文件夹,并没有发现UserFlag

看来还需要别的手段,输入sudo -l查看拥有执行权限的命令

发现/usr/bin目录下的backy.sh文件,查看该文件具体内容
点击查看代码
#!/bin/bash
if [[ $# -ne 1 ]]; then
/usr/bin/echo "Usage: $0 <task.json>"
exit 1
fi
json_file="$1"
if [[ ! -f "$json_file" ]]; then
/usr/bin/echo "Error: File '$json_file' not found."
exit 1
fi
allowed_paths=("/var/" "/home/")
updated_json=$(/usr/bin/jq '.directories_to_archive |= map(gsub("\\.\\./"; ""))' "$json_file")
/usr/bin/echo "$updated_json" > "$json_file"
directories_to_archive=$(/usr/bin/echo "$updated_json" | /usr/bin/jq -r '.directories_to_archive[]')
is_allowed_path() {
local path="$1"
for allowed_path in "${allowed_paths[@]}"; do
if [[ "$path" == $allowed_path* ]]; then
return 0
fi
done
return 1
}
for dir in $directories_to_archive; do
if ! is_allowed_path "$dir"; then
/usr/bin/echo "Error: $dir is not allowed. Only directories under /var/ and /home/ are allowed."
exit 1
fi
done
/usr/bin/backy "$json_file"
内容大概为三个功能:
1.输入检查,必须传入一个 JSON 文件路径(如 task.json),否则报错。检查文件是否存在。
2.路径过滤使用,jq 移除 directories_to_archive 中所有 ../(防止目录遍历攻击)。允许的路径范围限定在 /var/ 和 /home/。
3.路径权限检查,is_allowed_path() 函数检查路径是否以 /var/ 或 /home/ 开头(防止访问敏感路径如 /root/)。
那么下一步的主题就是task.json文件,毕竟可以通过构造恶意json来绕过路径检查获取flag,查询backups目录下的task.json权限,发现martin用户拥有读写权限

查看task.json文件内容
点击查看代码
{
"destination": "/home/martin/backups/",
"multiprocessing": true,
"verbose_log": false,
"directories_to_archive": [
"/home/app-production/app"
],
"exclude": [
".*"
]
}

解压后发现其将/home/app-production/app目录内容全部备份到了压缩包内,代表可以通过这个命令来进行提取flag

使用grep查找userFlag,发现在app-production目录内,那么就可以通过修改task.json文件来获取到userFlag

输入sudo /usr/bin/backy.sh task.json执行命令,成功在backups目录下生成了一个压缩包,输入tar -xjf code_home_app-production_user.txt_2025_March.tar.bz2解压,即可得到userFlag

三、rootFlag
既然userFlag可以通过这种方式获取,那么rootFlag也同理,能够通过修改task.json文件得到root目录。
前面说到backy.sh会过滤掉../,那么可以修改task.json文件,将备份目录修改为/home/....//root

执行sudo /usr/bin/backy.sh task.json,但是与userFlag不同的是,解压后什么都没有得到

查看task.json,发现目录确实被过滤成了/home/../root

但是解压结果为空,这是为什么?
参考大佬的wp思路(来源https://blog.csdn.net/weixin_44368093/article/details/146541637)
发现原因可能是tar在压缩时,将目录过滤成了/home/root导致压缩失败,或是exclude: [".*"]导致/root文件夹被完全排除

删除掉"exclude": [".*"]

重新执行命令,此时发现成功将root目录带了出来,并且成功获取到了rootFlag


浙公网安备 33010602011771号