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 語句,爲什麼呢?可大膽推斷:
where
與order by
都
是子句,and
是操作符,用於where
子句。
在MySQL的執行順序中,where
是遠在order by
前面的。在第1個查詢語句中,
order by
在where
的條件中,在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
特別注意:這裏的or
和
and
作爲了聯合查詢第二個語句的條件而不是第一個語句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 +--------+
所以 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我會混合使用,來驗證我上面的說法是正確的:
待續....