介绍
靶机链接: https://app.hackthebox.com/machines/Code
靶机 IP: 10.10.11.62
本次 Hackthebox 靶机 “Code” 的目标是利用一个运行在 5000 端口的 Python 代码编辑器,通过代码执行漏洞获取用户凭据,然后利用
backy.sh备份脚本的漏洞进行提权,最终获取 root 权限。
思路:
- 信息收集:使用Nmap发现开放的5000端口运行Python代码执行服务
- 漏洞发现:利用SQLAlchemy ORM进行数据库查询获取用户凭据
- 获取立足点:使用破解的用户凭据进行SSH登录
- 权限提升:利用备份脚本
backy.sh的路径解析漏洞访问受限目录
一、信息收集
首先使用 Nmap 进行端口扫描
Nmap 扫描结果:

- 发现开放的22(SSH)和5000(HTTP)端口。5000端口运行着"Python Code Execution Page"。
- 确定Web框架
- 尝试Django ORM语法:
User.objects.all()(失败) - 尝试SQLAlchemy语法:
User.query.all()(成功) - 确认目标使用SQLAlchemy作为ORM框架
- 尝试Django ORM语法:
1 | users = db.session.query(User).all() |
代码执行结果:

成功查询到用户 development 和 martin 的信息,包括用户名和密码哈希值
使用CrackStation在线破解获得明文密码
密码破解结果:

成功破解出两个用户的明文密码:
| 用户 ID | 用户名 | 密码哈希 (Password Hash) | 哈希类型 (Hash Type) | 已破解密码 (Cracked Password) |
|---|---|---|---|---|
| 1 | development | 759b74ce43947f5f4c91aeddc3e5bad3 |
md5 | development |
| 2 | martin | 3de6f30c4a09c27fc71932bfc68474be |
md5 | nafeelswordsmaster |
尝试使用破解的密码进行 SSH 登录。
1 | ssh development@10.10.11.62 # 失败 |

二、userFlag
登录 martin 用户后,首先查看用户目录下的文件,发现 backups 目录。
进入 backups 目录,查看目录内容,没有发现 user.txt 文件。
输入 sudo -l 命令查看当前用户可以以 sudo 权限执行的命令。



发现 martin 用户可以使用 sudo 权限执行 /usr/bin/backy.sh 脚本,这可能是一个提权点。
查看 /usr/bin/backy.sh 脚本的内容:
1 | cat /usr/bin/backy.sh |
分析 backy.sh 脚本,发现其主要功能如下:
- 参数检查: 必须传入 JSON 配置文件路径(例如
task.json)。 - 路径过滤: 使用
jq移除directories_to_archive中的../,防止目录遍历攻击,可以使用....//这样的序列,当../被移除后,会变成../ - 路径限制: 只允许备份
/var/和/home/开头的目录。 - 备份操作: 使用
tar命令将指定目录打包备份到指定目标路径。
进入 backups 目录,查看已存在的 task.json 文件内容。
查看 task.json 文件内容:

task.json 文件的内容配置了备份 /home/app-production/app 目录到 /home/martin/backups/ 目录。
尝试执行 sudo /usr/bin/backy.sh task.json 命令,测试备份脚本是否正常工作。


脚本成功执行,并在 /home/martin/backups/ 目录下生成了一个压缩包 code_home_app-production_app_xxxx_xxxx.tar.bz2。
解压该压缩包,验证备份内容。
解压备份文件:

解压后发现,备份脚本确实将 /home/app-production/app 目录下的所有内容都备份到了压缩包中。 这意味着我们可以通过修改 task.json 文件,让备份脚本备份其他目录,从而提取敏感信息。
修改 task.json 文件,将 directories_to_archive 修改为 "/home/app-production/",目标是备份 /home/app-production/ 目录,以获取 userFlag。
修改后的 task.json 文件内容 (获取 userFlag):

再次执行 sudo /usr/bin/backy.sh task.json 命令。
执行 sudo /usr/bin/backy.sh task.json (获取 userFlag):

脚本成功执行,并在 /home/martin/backups/ 目录下生成了新的压缩包。 解压该压缩包,找到 user.txt 文件,即可获取 userFlag。
三、rootFlag
既然 userFlag 可以通过修改 task.json 文件获取,那么 rootFlag 也同理,我们可以尝试修改 task.json 文件来备份 root 目录。
尝试将 task.json 文件修改为备份 /root 目录。 由于 backy.sh 脚本会过滤掉 ../,为了绕过路径检查,我们使用路径 /home/....//root/。 这个路径在 Linux 文件系统中会被解析为 /root 目录。
1 | { |
修改后的 task.json 文件内容,cat 进行查看发现 …/ 已经被过滤(获取 rootFlag):
可以看到,directories_to_archive 已经修改为 "/home/../root/"。

可以看到,backy.sh 脚本执行成功,并且 tar 命令开始打包 /home/../root/ 目录下的文件。从输出信息 Archiving: [/home/root] 和 tar: Removing leading '/home/../' 可以看出,backy.sh 和 tar 都正确地处理了这个路径,最终备份的目标是 /root 目录。

发现 root 目录!


安全建议
- 代码编辑器安全: 避免对外暴露不必要的服务,例如代码编辑器。如果必须使用,请确保代码编辑器本身的安全,并进行严格的权限控制和输入验证,防止代码执行漏洞。
- 脚本安全: 对于具有高权限 (sudo) 的脚本,必须进行严格的安全审计,防止被恶意利用。 特别是要仔细检查脚本对用户输入 (例如配置文件) 的处理,防止路径遍历、命令注入等漏洞。
- 最小权限原则: 运行脚本和服务的用户,应遵循最小权限原则,避免赋予不必要的权限。
- 安全配置: 对于备份脚本,应仔细配置备份策略,例如限制备份目录范围,避免备份敏感数据。