Hackthebox - Backend

Backend

10.10.11.161

7fba42c064abfed01ea2a27fe8d353d4.png

nmap

8378f46af87bda078129b2551dc8c898.png

gobuster 扫描结果

f982042cafbced3a56e023b1f01cc593.png

还是第一次在 API 上用这种工具,如果真的需要这样测试 API 的话,应该需要一层一层地扫吧。

b148d72ce513f8809d4682bc818e975a.png

但是这里就给出了一些提示信息,不需要那么繁琐了。

8efeddcc3dfa63169c7564b659d1cd9e.png

曾经开发过 API 的经验告诉我,这里后面还可以接 URL 的 param,放进扫描器扫一下。

/api/user/FUZZ 扫描结果

POST

f1143d975375469e2ace6b7e4d662689.png

扫到了两个 API,登录和注册。response 中有这个 API 的参数,或许我可以尝试注册一个用户试试。

GET

c64442c47fbfb5038b4e49032edb858c.png

GET 扫到了一个用户

对 /api/v1/user/signup 的测试

49f88b011b97fe785275f9b5c9fb829b.png

一开始并没有告诉我们应该传哪些参数,那么我们随便构造一个试试。

6977de36ee4a5ff21ac42caec12abf24.png

可以看到有 jsondecode 的错误,我们构造一个 json格式的试试。

003c2bf236fda00cbeaed48a9c4336c5.png

这次总算告诉我们应该传哪些参数了,构造一个。

601c2c376f1ed4e1dfb6b71ab5a283fa.png

201 Created,我们去登录 API 登录一下试试。

对 /api/v1/user/login 的测试

7de283009d3cb9e2620f2065cf6c4626.png

成功登录,返回了 jwt 的 bearer token,带上这个 token 我们去试试看 /docs。

/docs

在 burp 中拦截了 /docs 的请求,在其中加上 Token 后,我们来到了这个页面。

f83f168d380bdff13f44fc7b7e13f2e5.png

这样我们就可以看到 API 文档了,对后面的渗透非常有帮助。

6b8f53f0d38070a7bdd088483fe6f841.png

非常方便的登录

/api/v1/admin 接口测试

9c5628441f657fd04112fc321c4abc05.png

这个接口注册的用户不可以访问

260b6bfa4ebee5a55260e3acbdec56dc.png

我发现更新密码的接口似乎并不在 admin 的路由下,难道说所有的用户都可以更新密码?那么这里就存在越权漏洞了。
我更新一下 admin 用户的密码是不是就可以用 /admin 的接口了?我来试试。

02742a6f091cc9485d58a015e55ae8b1.png

首先这个接口需要用户的 guid,我来看看 admin 的 guid 是多少。

2cfdca482d6fe2480b0e9b425443d32d.png

可以看到 admin 用户的 guid,更新一下密码。

dfae4d42e1a70f12977d5d5d3027521b.png

成功更新了 admin 用户的密码,我来登录一下试试。

5f247dac23b131ae7cb03a1ad7ab9132.png

成功登录了,那么。

646a37e129c671ef9d63a6c6ee0fe4b4.png

读取文件的接口可以用了,我有了一个任意文件读取的漏洞。

a01dcd47ee33995b1f1a6640c3e90cc4.png

看来这个接口的权限还不够高,我需要进一步的提权。
下面还有一个命令执行的接口,我来调用一下试试。

b45b22333e7d20b265a4d9cb76b02cef.png

看来还需要我改一改这个 JWT,那么应该从何入手呢?或许可以在上面那个读文件的点找找源码看看。

任意文件读取

ac341de4fc25ae746edcd3cd5a507038.png

读到了这个应用的运行目录,再找找源码文件。

45619f1ffe813cf7244d93d23f7c89a7.png

app.main,那么入口文件名就是 main.py,组合起来就是 /home/htb/uhc/app/main.py,我读一下试试。

fccb93c3118c5c3be1eff67ec474f91f.png

拿到了 main.py 的源码,这里看起来很乱,我的诀窍就是,既然文件是 python 读出来的,那么就用 python 写回去。

e679b53e3526dee32d0957d4d276f352.png

a8f430f0fbbb6751e2af7886e6b97e46.png

完美。

读源码,根据引入的包一路跟进到 /home/htb/uhc/app/api/v1/endpoints/admin.py,可以看到这个 debug key 的校验逻辑:

627e95448757dff2951f411fce23ca3b.png

只要有 debug 这个键就可以了,那么我生成一个有这个键的 token 就可以了,生成 token 需要用到 jwt 的 key,我来找一下。

e1052f1f147fd9f33b4be19c4fcee1a8.png

于是在 /home/htb/uhc/app/core/config.py 中,我找到了 jwt_secret:SuperSecretSigningKey-HTB,接下来去 jwt.io 改一下 token。

d4bc5a5e33fbc3611f61f4fa911819c1.png

4f4bd4827ba91b8066744252f6fe367f.png

成功 RCE。

RCE 反弹 shell

我在任意文件读取漏洞中获取到了 JWT SECRET,成功调用了可以 RCE 的 API,接下来反弹一个 shell。
因为参数是在 url 中传递的,这里需要进行一个 base64 编码减少不能使用的特殊字符。

51be65c7da38ea567f8f584d71963cd6.png

6c21b060e3a82e7c69e0374615397db8.png

提权

反弹 shell 后,看一下目录结构。

abb0730d86334d11ed661e63bd8d08dd.png

在 auth.log 中可以找到一次登录失败的记录。

9cce44be87df1be59d6113b0e103008d.png

这里要想到的是,登录失败可能是错将用户名填为了密码。

b17603fb12fcaa640d705a01fc02ff3e.png

成功用 Tr0ub4dor&3 登录 root 账户,这台机器到这里就结束了。

223df3ccaa987a8b21dd3538473ead39.png

一点感受

这台机器不同于以往做过的所有 web 相关的机器,这台机器是直接对 API 做测试。
不像有前端页面的程序,没有了前端代码写好的请求操作,API 具体怎么用还是要看 API 在调用错误的时候有没有提示。
这个 API 如果没有提示信息,就需要我一层一层地扫进去,应该会非常的耗时间。
对这类 API 的渗透测试,一旦找到了调用文档,那么后面就会事半功倍。
这个 API 还好,是用 Python 写的,而且有读文件的点可以直接读到源码,如果是其他编译型的语言比如 Golang,
就算是有读文件的点,也需要进行逆向的工作,应该会比这个有难度的多。
还有就是可以在 /proc/self 下面读到很多信息,之前在做一个 ctfshow 的题的时候用到过这个点,就没有很陌生了。
除了最后提权部分这个密码不太好想到,还是第一次做这种 web 程序渗透,以后面对这种也有了一个大体的思路。