Sqli-labs之Less-23

                                                   Less-23

基於錯誤的,過濾註釋的GET型

判斷注入類型:

?id=1  ?id=1'  ?id=1" 發現第二條語句報錯:

翻譯:

警告:mysql_fetch_array()期望參數1爲資源,布爾值在第38行的C:\ phpStudy \ WWW \ sqli \ Less-23 \ index.php中給出
您的SQL語法有誤。 檢查與您的MySQL服務器版本對應的手冊以獲取正確的語法,以在第1行的“ 1” LIMIT 0,1'附近使用

從這裏可以看出是單引號閉合的查詢,這裏報錯還把站點路徑爆出來了。

這與我們在第一關中的報錯是有點區別的

至於區別在哪,下面會通過源碼進行講解。

接下來我們還是按照原先的方法進行猜解字段數:

http://192.168.33.1/sqli/Less-23/index.php?id=1' or 1=1 -- #

http://192.168.33.1/sqli/Less-23/index.php?id=1' or 1=1 --+

http://192.168.33.1/sqli/Less-23/index.php?id=1' or 1=1#

http://192.168.33.1/sqli/Less-23/index.php?id=1' or 1=1%23

。。。

上面的語句都沒有成功,全部報錯,發現報錯回顯中LIMIT語句仍在起作用,註釋沒有起作用,即使把註釋符進行URL編碼發現依舊不行,說明了,後臺源碼對其進行了過濾。

我們查看下源代碼:

 

preg_replace() 函數

preg_replace(pattern,replacement,subject[,limit=-1[,&count]])

參數

描述

pattern

要搜索的模式,可以是字符串或一個字符串數組

replacement

用於替換的字符串或字符串數組

subject

要搜索替換的目標字符串或字符串數組

limit

可選,對於每個模式用於每個 subject 字符串的最大可替換次數。 默認是-1(無限制)

count

可選,爲替換執行的次數

preg_replace()函數執行一個正則表達式的搜索和替換,搜索subject中匹配pattern的部分, 以replacement進行替換。

如果subject是一個數組,preg_replace()返回一個數組,其他情況下返回一個字符串。
如果匹配被查找到,替換後的subject被返回,其他情況下返回沒有改變的subject。如果發生錯誤,返回NULL

在這關中,也只是將#--替換成了空字符

從後臺的查詢語句中。我們看到:

SELECT * FROM table_name WHERE id='$id' LIMIT 0,1

我們知道注入點在id處,那麼我們要判斷字段數的同時閉合第二個單引號,就要這麼做:

SELECT * FROM users WHERE id='1' order by 4 and '1'='1' LIMIT 0,1

或者嘗試:SELECT * FROM users WHERE id='1' order by '4' LIMIT 0,1

提示:users表有3個字段

上面的語句應該是要報錯的,結果都沒報錯,我們在後臺數據庫進行查詢,

操作一:

操作二:再查詢兩個順序不同的語句

從上面的操作中,我們推斷出第一個操作中沒有報錯,說明order by語句沒有執行是因爲order by後面的字段(名,序號,別名)是不能加引號的,雖然不會報錯,但數據庫會不執行該語句。

那麼第二個操作中,order by語句也沒有報錯,說明沒有執行order by 語句,爲什麼呢?可大膽推斷:

whereorder by子句and是操作符,用於where子句。
在MySQL的執行順序中,where是遠在order by前面的。

在第1個查詢語句中,order bywhere的條件中,在where執行時被忽略了,結果集生成後並未再執行order by

在第2個查詢語句中,id='1' and '1'='1'作爲where的條件,先被執行,得到結果集;然後是order by,因結果集中無第四個字段所以報錯。

所以這關不能用order by來判斷字段數,可以直接使用union進行聯合查詢:

SELECT * FROM table_name WHERE id='1' union select 1,2,3,4 or '1'='1' LIMIT 0,1

或者

SELECT * FROM table_name WHERE id='1' union select 1,2,3,4 and '1'='1' LIMIT 0,1

特別注意:這裏的orand作爲了聯合查詢第二個語句的條件而不是第一個語句where的條件。

這裏使用and和or的效果一樣,是因爲在select在於and或or直接聯用時,只要查詢不到,就會報錯:

爲什麼會報錯?

邏輯運算符用來判斷表達式的真假。如果表達式是真,結果返回 1。如果表達式是假,結果返回 0。(即0是false)

運算符號 作用
NOT 或 ! 邏輯非
AND 邏輯與
OR 邏輯或
XOR 邏輯異或

1、與

mysql> select 2 and 0;     // select true and false
+---------+
| 2 and 0 |
+---------+
|       0 |                // false
+---------+

        
mysql> select 2 and 1;   // select true and true
+---------+     
| 2 and 1 |      
+---------+      
|       1 |              // true
+---------+

2、或

mysql> select 2 or 0;     //select true or false
+--------+
| 2 or 0 |
+--------+
|      1 |               // true
+--------+

mysql> select 2 or 1;    // select true or true
+--------+
| 2 or 1 |
+--------+
|      1 |               // true
+--------+

mysql> select 0 or 0;   // select false or false
+--------+
| 0 or 0 |
+--------+
|      0 |               // false
+--------+

mysql> select 1 || 0;   //select true || false
+--------+
| 1 || 0 |
+--------+
|      1 |               // true
+--------+

更多請看:https://www.runoob.com/mysql/mysql-operator.html

所以 id='1' union select 1,2,3,4 or '1'='1' LIMIT 0,1 就變成 id='1' union select 1,2,3,4 or true LIMIT 0,1    ====>所以select 1,2,3,4 如果爲true,頁面就能正確返回,否則就會報錯

同理:

id='1' union select 1,2,3,4 and '1'='1' LIMIT 0,1 就變成 id='1' union select 1,2,3,4 and true LIMIT 0,1 =====>只有當select 1,2,3,4 爲true時,頁面才能正確回顯,否則報錯。

The used SELECT statements have a different number of columns 翻譯:使用的SELECT語句具有不同數量的列。

(PS: sql1 union sql2  想使用union查詢必須保證查詢的字段數量一致,否則報錯

select加到4時報錯,得出共3個字段。

接下來,and和or我會混合使用,來驗證我上面的說法是正確的:

待續....

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