Vulnhub.com Bulldog CTF Solution

Leigh
SecurityBytes
Published in
4 min readNov 1, 2017

--

Here’s my write up of a solution to the Bulldog CTF VM by @frichette_n, and hosted on Vulnhub.com.

First step is to see what’s listening on our host:

nmap -A -O 10.0.2.5Starting Nmap 7.60 ( https://nmap.org ) at 2017–10–30 11:21 EDT
Nmap scan report for 10.0.2.5
Host is up (0.00037s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
23/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 20:8b:fc:9e:d9:2e:28:22:6b:2e:0e:e3:72:c5:bb:52 (RSA)
| 256 cd:bd:45:d8:5c:e4:8c:b6:91:e5:39:a9:66:cb:d7:98 (ECDSA)
|_ 256 2f:ba:d5:e5:9f:a2:43:e5:3b:24:2c:10:c2:0a:da:66 (EdDSA)
80/tcp open http WSGIServer 0.1 (Python 2.7.12)
|_http-server-header: WSGIServer/0.1 Python/2.7.12
|_http-title: Bulldog Industries
8080/tcp filtered http-proxy
MAC Address: 08:00:27:16:1D:5F (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2–4.8
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE
HOP RTT ADDRESS
1 0.37 ms 10.0.2.5
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 17.34 seconds

To the webserver.

Using dirb gives us a couple of folders to look at:

dirb http://10.0.2.5 /usr/share/wordlists/dirb/common.txt  — — — — — — — — -
DIRB v2.22
By The Dark Raver
— — — — — — — — -
START_TIME: Mon Oct 30 11:28:35 2017
URL_BASE: http://10.0.2.5/
WORDLIST_FILES: /usr/share/wordlists/dirb/common.txt
— — — — — — — — -GENERATED WORDS: 4612 — — Scanning URL: http://10.0.2.5/ — —
==> DIRECTORY: http://10.0.2.5/admin/
==> DIRECTORY: http://10.0.2.5/dev/
+ http://10.0.2.5/robots.txt (CODE:200|SIZE:1071)
>>SNIP<<

/admin reveals a log in page and /dev gives some text about the rebuild post-hack, and helpfully gives us some user names.

Theres a link on the page to /shell which tells me I need to be authenticated to get access.

A look at the source code gives us some hashes too (enumeration is key! ;) ).

These are SHA1 hashes, and online hash databases like Crack Station give us passwords for nick and sarah:

Back End: nick@bulldogindustries.com<br><br><! — ddf45997a7e18a25ad5f5cf222da64814dd060d5 → bulldog
Database: sarah@bulldogindustries.com<br><! — d8b8dd5e7f000b8dea26ef8428caf38c04466b3e → bulldoglover

Annoyingly I’d previously tried bruteforcing my way in using the usernames I found and a Cewl-generated password list…turns out that Bulldog is capitalised on the site so my custom password list didn’t get me in! If I’d persisted a little longer using rsmangler I might have gotten in without finding the hashes.

Using nick’s credentials I can now auth to the /admin page and getting to the /dev/shell page gives me a ‘Limited Web Shell’.

Breaking out of restricted shells is a fun little game in its own right. This page is defeated by judicious use of the mighty pipe:

Here I’m echo’ing a reverse bash shell and piping it into bash to execute it. The screenshot shows my listener picking up the reverse shell and showing that I now have a low privilege shell.

From here we need to escalate our privileges.

I did some more enumeration to find kernel versions and files with excessive permissions. I transferred unix-privesc-check onto the host from my machine via curl but wasn’t able to find anything useful there.

I attempted 4 different privilege escalation paths: 40759.rb, 40871.c, 41458.c, and 39772.txt but I couldn’t get any of them to work.

Finally, some more manual enumeration revealed a second user on the system — bulldoguser. And this user had a home folder with a note and binary in it.

The note talks about some custom privilege management prototype that the developer is writing. Sounds flaky!

I moved this file to the webserver page on the host and downloaded it to my attack box.

Running ‘strings’ against the binary told me a few things:

Firstly, the binary tries to run ‘sudo su root’ — this means that if I can get a password for djangouser I can presumably execute an ‘su root’ and then it’s game over.

Secondly, and slightly more helpfully, there’s a password hardcoded in the binary:

SUPERultimatePASSWORDyouCANTget

Wanna bet? ;)

So now, finally:

sudo -l

confirms that I can indeed run ALL commands as root.

sudo su root

makes me root, and looking in the /root folder gives us our flag:

Thanks to @frichette_n for this — it was a fun VM to break.

I’m curious as to the other route to root, but I’ll take the easy path on that one and let someone else find it!

--

--

Leigh
SecurityBytes

Father, husband, security architect, Guardian.