原理
SQL隱碼攻擊是一種攻擊方式,在這種攻擊方式中,惡意程式碼被插入到字串中,然後該字串傳遞到SQL Server的例項以進行分析和執行。任何構成SQL語句的過程都應進行注入檢查,因為SQL Server將執行其接收到的所有語法有效的查詢。
(摘自微軟 SQL隱碼攻擊,但要注意的是,SQL隱碼攻擊並不限於SQL Server,幾乎任何資料庫引擎都存在這個問題)
一般利用步驟
1.判斷注入點
判斷注入點有方面的含義,一是找到可能存在注入的位置,二十判斷該處能否進行注入。在靶場環境下,我們已經知道,GET的引數id是與資料庫進行互動的點,接下來判斷能夠進行注入。
id為1,成功查詢,回顯正常
id為1',資料庫報錯,由報錯資訊猜測閉合方式為單引號
id為1' --+,成功查詢,回顯正常,印證猜測,
id分別為1' and 1=1 --+和1' and 1=2--+,通過回顯情況,進一步判斷能否注入
1=1為永真,當1成功查詢,若1=1也成功查詢,則頁面返回正常,1=2為永假,因此若1=2得到執行,則頁面必返回不正常。通過對比二者返回結果,可知改點能否進行注入。
2.判斷查詢欄位數
為了將我們想要的結果能夠顯示在頁面上,我們需要用到聯合查詢,聯合查詢的條件之一是必須保證前後查詢語句的欄位數相等,因此,我們需要判斷查詢的欄位數。
一般採用order by或union select如下:
order by 大於3的數時頁面返回不正常,小於等於3時返回正常,得知原查詢語句的欄位數為3。或
當我們聯合查詢4列時,得到了查詢語句由不同的列的錯誤,查詢3列時:
成功查詢,得原查詢語句只有三列。
3.查資料庫名、版本號、使用者名稱等資訊
union聯合查詢的規則是當前一個查詢失敗時執行第二個查詢,前面我們知道了查詢有三個欄位,接下來將傳入id為0,判斷是三個欄位的回顯位置。
再由資料庫內建的version()
、database()
、user()
查詢出版本號、資料庫當前名和當前使用者。
4.查詢表名
前面我們查詢得知,當前資料庫版本為5.5.53,在MySQL5.5後版本都內建了資料庫information_schema。它儲存了資料庫中所有的表名、欄位名等資訊。從而可以構造查詢語句,獲取表名。
payload:?id=0' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+
這裡的group_concat()
為SQL語句內建的聚合函式,用來將查詢的結果作為一個字串輸出。
(使用payload:?id=0' union select 1,(select group_concat(schema_name) from information_schema.schemata),3 --+
)
5.查詢欄位名
知道了所有的表名,接下來選擇一個表,查詢其中所有的欄位名。
payload:?id=0' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3--+
6.查詢記錄內容
有了表名和欄位名,便可以爆出資料庫中的記錄了。
payload:?id=0' union select 1,group_concat(username),group_concat(password) from users --+
以上是一般SQL隱碼攻擊的流程,當然還有一些像報錯注入,請求頭注入、select into outfile 寫入一句話木馬等姿勢未介紹。後續學習過程中再逐漸補充。