BugKu——No one knows regex better than me
一、解題思路
1.繞過第一層循環比對
将源代碼擋下來,在本地測試
<?php
$second =$_REQUEST['second'];
if(preg_match_all("/Yeedo|wants|a|girl|friend|or|a|flag/i",$second)){
echo '比對成功!';}
else
echo '比對失敗!';
?>

本地搭建的方式也是,使用request的請求方式,因為get的方式比較簡單,就直接使用get的請求方式
上述代碼主要使用的是preg_match_all()函數比對,其中隻要我們在變量second中含有Yeedo,wants,a,girl,friend,or,a,flag等字元就可以比對成功。
2.繞過第二層循環比對
<?php
$key =$_REQUEST['key'];
if(preg_match("/\.\.|flag/",$key)){
die("Noooood hacker!");
}
else
echo "跳出比對!";
?>
這個循環使用的是preg_match()比對函數
隻要我們傳入的參數中不要有flag或兩個連續的點(…)時,即可跳出比對,這兩裡的話輸入單個點的話,會被轉義
而當我們輸入兩個點時,被轉譯了一個剩下一個就會被比對到
線上base64加解密
因為後面提到base64解密,我們可以選擇使用base64加密的方式,進行繞過
3.繞過第三層循環比對
<?php
$third=$_REQUEST['third'];
if(preg_match("/\\|\056\160\150\x70/i",$third)){ ##\數字八進制;##\x十六進制;
echo '比對成功!';
}
else
echo '比對失敗!';
?>
這裡有兩個反斜杠(\),而php在解析字元串的過程中,會把兩個反斜杠(\)轉換成一個(),是以這裡的管道符(|)沒有被解析,就會和後面的編碼組合成被比對的對象
在Php和Python中的編碼中
(\+數字)
-------->屬于八進制編碼
(\x+數字)
------->屬于十六進制編碼
後面的編碼,轉換出來就是——
.php
繞過三層循環後,構造payload為:
http://114.67.246.176:12532/?zero=ZmxhZw==&first=aaaa|.php
二、知識點總結
1.涉及到的函數
·preg_match_all()函數
·preg_match()函數
·base64_decode()函數
2.請求方式
GET
POST
REQUEST
三、PS
這類型的題目,屬于代碼審計,從這道題中我學會了使用本地測試的方式,構造payload,就是要大膽的去嘗試,沒有人天生就會的,報錯了,失敗了,不要氣餒,堅持自己的選擇,總有一天會成功的!
如果上述部落格中存在錯誤,請大佬批評指正。