HTB Flujab
10.10.10.124 | 40 pts
PART 1 : INITIAL RECON
$ nmap --min-rate 1000 -p- -v 10.10.10.124
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https
8080/tcp open http-proxy
$ nmap -oN flujab.nmap -p22,80,443,8080 -sC -sV -v 10.10.10.124
PORT STATE SERVICE VERSION
22/tcp open ssh?
80/tcp open http nginx
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: ClownWare Proxy
|_http-title: Did not follow redirect to https://10.10.10.124/
443/tcp open ssl/http nginx
| http-methods:
|_ Supported Methods: GET HEAD POST
|_http-server-header: ClownWare Proxy
|_http-title: Direct IP access not allowed | ClownWare
| ssl-cert: Subject: commonName=ClownWare.htb/organizationName=ClownWare Ltd/stateOrProvinceName=LON/countryName=UK
| Subject Alternative Name: DNS:clownware.htb, DNS:sni147831.clownware.htb, DNS:*.clownware.htb, DNS:proxy.clownware.htb, DNS:console.flujab.htb, DNS:sys.flujab.htb, DNS:smtp.flujab.htb, DNS:vaccine4flu.htb, DNS:bestmedsupply.htb, DNS:custoomercare.megabank.htb, DNS:flowerzrus.htb, DNS:chocolateriver.htb, DNS:meetspinz.htb, DNS:rubberlove.htb, DNS:freeflujab.htb, DNS:flujab.htb
| Issuer: commonName=ClownWare Certificate Authority/organizationName=ClownWare Ltd./stateOrProvinceName=LON/countryName=UK
| Public Key type: rsa
| Public Key bits: 4096
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2018-11-28T14:57:03
| Not valid after: 2023-11-27T14:57:03
| MD5: 1f22 1ef7 c8bf d110 dfe6 2b6f 0765 2245
|_SHA-1: 7013 803a 92b3 f1f0 735d 404b 733c 712b bea6 ffcc
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
| tls-nextprotoneg:
|_ http/1.1
8080/tcp open ssl/http nginx
| http-methods:
|_ Supported Methods: GET HEAD POST
|_http-server-header: ClownWare Proxy
|_http-title: Direct IP access not allowed | ClownWare
| ssl-cert: Subject: commonName=ClownWare.htb/organizationName=ClownWare Ltd/stateOrProvinceName=LON/countryName=UK
| Subject Alternative Name: DNS:clownware.htb, DNS:sni147831.clownware.htb, DNS:*.clownware.htb, DNS:proxy.clownware.htb, DNS:console.flujab.htb, DNS:sys.flujab.htb, DNS:smtp.flujab.htb, DNS:vaccine4flu.htb, DNS:bestmedsupply.htb, DNS:custoomercare.megabank.htb, DNS:flowerzrus.htb, DNS:chocolateriver.htb, DNS:meetspinz.htb, DNS:rubberlove.htb, DNS:freeflujab.htb, DNS:flujab.htb
| Issuer: commonName=ClownWare Certificate Authority/organizationName=ClownWare Ltd./stateOrProvinceName=LON/countryName=UK
| Public Key type: rsa
| Public Key bits: 4096
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2018-11-28T14:57:03
| Not valid after: 2023-11-27T14:57:03
| MD5: 1f22 1ef7 c8bf d110 dfe6 2b6f 0765 2245
|_SHA-1: 7013 803a 92b3 f1f0 735d 404b 733c 712b bea6 ffcc
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
| tls-nextprotoneg:
|_ http/1.1PART 2 : PORT ENUMERATION
Various domains and subdomains were captured during the nmap scan and I added them to the /etc/hosts file:
From initial observations, most of the domains contain either an embedded image or video and bestmedsupply.htb and flowerzrus.htb only contains static .html pages. Three domains, however, seem worth exploring -- https://custoomercare.megabank.htb, smtp.flujab.htb, and freeflujab.htb
TCP PORT 443 (https://custoomercare.megabank.htb)
https://custoomercare.megabank.htb)Opening https://custoomercare.megabank.htb on your browser loads the following and it explicitly says: "The site ahead may contain harmful programs"

Running gobuster:
All 404 requests are redirected (301) to https://clownware.htb/cwerror_pages.php which contains the following error page:

Now, running gobuster but limiting response codes to only 200 :
And hidden in https://custoomercare.megabank.htb/shell.php's page source:
The webpage seems to accept shell commands -- ?cmd=id returns uid=0(root) gid=0(root) groups=0(root) and ?cmd=ls returns root.txt but ?cmd=cat root.txt returns:

The webpage is just a troll.
TCP PORT 443 (https://smtp.flujab.htb/)
https://smtp.flujab.htb/)Now moving on to https://smtp.flujab.htb/ brings you to:

With the following page source:
The "free service application" being referred to must be https://freeflujab.htb which we'll get to in a bit.
Examining the do_login() function referenced as a form action:
api() is referenced by the included js file but is not defined anywhere so t he login functionality might be a RABBIT HOLE
TCP PORT 443 (https://freeflujab.htb/)
https://freeflujab.htb/)Lastly, we visit the referenced free service from earlier. Opening https://freeflujab.htb/ on your browser leads you to:

One thing you'll notice is that the favicon.ico image doesn't load and viewing its contents reveal:
The favicon.ico is not an image and it seems to be the structure or template of the site's webpages.
While the other links seem to work fine,
/?cancelredirects to/?ERROR=NOT_REGISTERED
/?remindredirects to/?ERROR=NOT_REGISTERED
Attempting to book an appointment for a free flujab in /?book:

But first checking page source to see how the form works:
Now, booking with the following values:
And the HTML Response after booking:
The form requires a registered patient and nhsnum is not a required field.
In the /?info page, there is a section dedicated to patient feedbacks formatted with a remark then first initial and surname:
In order to use the services given, a patient must be registered in the system and the register option doesn't really seem to work and educated guesses might be necessary for a valid patient name.
Educated guesses for a registered patient: Johnnie Walker, Johny Walker, John Walker, Jay Walker.
Examining cookies might also prove useful when validating users:
HTTP Request:
The base64 decoded
Registeredcookie isdaf23866abcb8e29ecee6d3da0caa992=Nullwhich seems connected to thePatientcookie
HTTP Response:
The base64 decoded
Moduscookie isConfigure=NullThere is a path set in the cookie
/?smtp_config. This must be the one referenced earlier byhttps://smtp.flujab.htb(This function has been integrated into the new free service application)
Modus,Patient, andRegisteredare set in the response if not requested.
Checking for the response headers of https://freeflujab.htb/?smtp_config:
The page redirects to /?denied... maybe the cookie needs to be set correctly to access the page.
PART 3 : EXPLOITATION
Re-booking an appointment using educated guesses for a registered patient:
HTML Response:
Response Cookies:
John Walker is a registered patient however it seems that the booked appointment sends to a SMTP server (default port: 25). Since /?smtp_config was found/set in the cookies, perhaps the cookie is also the way to set a mailserver.
With a registered patient, the decoded base64 Registered cookie is now set to True (daf23866abcb8e29ecee6d3da0caa992=True). What if the Modus cookie is also set to True.
Encoded (Base64) "
Configure=True" :Q29uZmlndXJlPVRydWU=URL Encoded cookie:
Modus=Q29uZmlndXJlPVRydWU%3D
Accessing /?smtp_config with the properly set cookies now returns the following responses:
The mailserver parameter only accepts a certain pattern which could be bypassed by changing the input value to anything you want or by intercepting the request and changing the values there.
All that is left is to set-up an SMTP server locally and wait for messages after booking an appointment:
From the Python smtpd documentation:
DebuggingServer Objects
class smtpd.DebuggingServer(localaddr, remoteaddr)
Create a new debugging server. Arguments are as per SMTPServer. Messages will be discarded, and printed on stdout.
Checking the started mailserver after booking:
An NHS Number was supplied in the email even though it was left empty during the request. This proves that the setup works. Now checking if the response after booking an appointment is different from asking for a reminder.
Now, the request requires an email parameter:
After sending the request, the mailserver responds with:
Asking for a reminder cancels an appointment... something might be up with this page.
Since the nhsnum parameter is not really required during requests, maybe it could be used for "injection":
TEST #1 : Fuzzing
The
Subjectheader changed:Subject: Flu Jab Appointment - Ref:The
REFchanged:REF : test
TEST #2 : Header Injection using CRLF
Flu Jab Appointment - Ref:at theSubjectheader still remains empty"
\r\n" was only passed inREF
TEST #3 : SQL Injection
Ref:NHS-943-475-5911appears in theSubjectheader which is different from the initial queries (Ref:NHS-921-376-3922)It's now highly probable that the server is vulnerable to SQL injection
SQL #1 : DATABASE TYPE
Checking what database the service is using using the vulnerability found in the nhsnum parameter:
No message was sent to the mailserver.
It returns a successful query (Subject: Flu Jab Appointment - Ref:NHS-943-475-5911) which means the service is using MySQL
SQLite will use
sqlite_masterto enumerate database contentMySQL will use
information_schemato enumerate database content
SQL #2 : QUERY COLUMNS
In order to perform UNION based SQL injections, it is essential to know how many columns are being returned by the original query.
SQL #3 : INFORMATION LEAKS
Now checking which column leaks information during query:
The third column is output to the Subject header
SQL #4 : DATABASE INFORMATION
The system is using MariaDB (just the same as MySQL) and is being hosted by the root user which meand that using high privilege commands should not be a problem.
The current database used by the service is vaccinations
SQL #5 : DATA EXFILTRATION
Now that we have everything we need to perform UNION based SQL injections, let's start by enumerating table names in the vaccinations database:
There is an admin table which might contain useful credentials.
Dumping all values based on the column names listed above for the admin table:
COLUMN
VALUE
id
1
loginname
sysadm
namelc
administrator
access
sysadmin-console-01.flujab.htb
created
2018-07-02 08:45:19
modified
2018-12-02 00:01:02
modifiedby
password
a3e30cce47580888f1f185798aca22ff10be617f4a982d67643bb56448508602
passwordchanged
2018-07-02
superuser
1
disabled
0
privileges
A new subdomain presents itself (
sysadmin-console-01.flujab.htb)The
passwordis encrypted using SHA-256:
The password for sysadm is th3doct0r
PART 4 : GENERATE USER SHELL
Add sysadmin-console-01.flujab.htb to local /etc/hosts:
Accessing https://sysadmin-console-01.flujab.htb:

Accessing over port 8080 (https://sysadmin-console-01.flujab.htb:8080):

And checking the server response by requesting over curl:
The page has a Permanent Redirect(301) to .../cwerror_denied.php and it may be suffering from a cached redirect:
Cached redirects could be bypassed by adding a trailing slash ("/") or a unique parameter that hasn't been cached (
/?,/?something_unique, or/?unique=something)
There was a urlcache table in the vaccinations database which may give a lead on how to proceed.
Check the urlcache table in vaccinations using nhsnum in /?remind
There doesn't seem to be anything cached on the server. Clearing the browser cache (Ctrl + Shift + Del for FireFox) might help.
Revisit https://sysadmin-console-01.flujab.htb:8080/?:

The redirect no longer goes to .../cwerror/denied.php. Instead, it now redirects to an Ajenti login page and using sysadm:th3doct0r redirects you to:

There is a Notepad plugin in the Ajenti service and the first thing I did was to enumerate the system users https://...:8080/view/notepad//etc/passwd:
There are a lot of system users and all but root has a restricted shell (/bin/rbash) and a mismatch of uids and gids
Listing the contents of all the user directories, most are inaccessible except for the current user (sysadm) and drno which has an ~/.ssh directory which contains a userkey file:
Exporting the found private key and then connecting to 10.10.10.124 via ssh:
The connection should work but it doesn't. Opening the /etc/ssh/sshd_config file in the Ajenti Notepad to see how private keys are read:
Public keys are read from .ssh/authorized_keys and/or access and reading from /home/drno/.ssh/authorized_keys:
It reveals that the remote connections must be whitelisted and that the public key requires a passphrase
Editing /etc/hosts.allow to whitelist your own IP address:
Then retry the connection via ssh:
No credentials for drno has been found so far but what if a newly generated RSA key pair was written to .ssh/authorized_keys or access
Writing the id_rsa.pub file then changing its permissions using the Ajenti API:
The user, sysadm, has a writable home directory and the id_rsa.pub file is written to a file named, access. (referring to sshd_config)
According to the ajenti.filesystem documentation, chmod accepts 2 arguments -- (path, mode) where mode accepts an integer value.
chmoduses octal values for user, group, global, and other permissionsThe octal value for
-r--r--r--is0444wchi in decimal (or integer value),0444is292.
Now, reconnecting to 10.10.10.124 via ssh using the generated RSA key pair and as user, sysadm:
All users are trapped in a restricted shell (/bin/rbash):
But luckily, the shell accepts python instructions which could be leveraged for proper command execution:
PART 5 : PRIVILEGE ESCALATION (sysadm -> root)
Check for SUID files owned by root:
There are two binaries with the same name (screen) which can write files to the system using its -L Turn on output logging. option and checking the binaries' version:
Both are running version 4.05.00 but /usr/local/share is not in the PATH variable which might mean that /usr/local/share/screen/screen might be a modified binary with an SUID bit.
Searching for available exploits using searchsploit:
The exploit (41154.sh) contains:
The exploit works like this:
It two files --
libhax.candrootshell.c
libhax.cis compiled as a shared object file (libhax.so)
rootshell.cis compiled as an executable (rootshell)
libhax.sois wriiten to/etc/ld.so.preload
The screen binary is used to append to the /etc/ld.so.preload file which is only writable as root. shared objects written in /etc/ld.so.preload are loaded before everything else which is even capable of overwriting libc functions and since libhax.so gives SUID permissions to the created /tmp/rootshell executable, a root shell should be spawned upon successful exploit.
Enumerating the system using sysadm shell to see how the exploit will be compiled:
The system runs on a 64-bit architecture and gcc is not available in the system.
Instead, create and compile libhax.c and rootshell.c locally:
EXPLOIT #1 : libhax.c
EXPLOIT #2 : rootshell.c
EXPLOIT #3 : COMPILING THE BINARIES
Upload the binaries using a python
SimpleHTTPServerto thesysadmshell then execute the exploit:EXPLOIT #4 : EXECUTING THE EXPLOIT
Last updated