攻防世界web新手-easyphp
XCTF - easyphp
本題知識點匯總
本題的知識點相對來說比較簡單
總結來說題目結構分為兩部分
- 第一部分是對a、b變量進行獲取知識點主要有
- php弱類型比較
- md5爆破
- 第二部分為變量c的獲取,知識點
- json_decode函數使用方法
- is_numeric函數使用方法
- php數組相關知識
- php弱類型比較
對php功底比較深的大神來說,本題就很簡單了
原題截圖
php代碼解析
讀題,打開網頁后發現為比較簡單的php代碼審計問題,簡單分析下代碼如下
<?php highlight_file(__FILE__); $key1 = 0; $key2 = 0; //獲取get型變量、ab $a = $_GET['a']; $b = $_GET['b']; //對a、b的數值做了限制a>600萬并且a的長度小于等于3 if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){ //b的md5切片值為8b184bif(isset($b) && '8b184b' === substr(md5($b),-6,6)){$key1 = 1;}else{die("Emmm...再想想");}}else{die("Emmm..."); } //json_decode是php5.2.0之后新增的一個PHP內置函數,其作用是對JSON格式的字符串進行編碼, //json_decode接受一個JSON格式的字符串并且把它轉換為PHP變量 ,當該參數$assoc為TRUE時,將返回array,否則返回object。 $c=(array)json_decode(@$_GET['c']); //is_numeric — 檢測變量是否為數字或數字字符串 //{'m':xx,'n':{[],xx}} if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){//DGGJ是否存在于$c["n"]中$d = array_search("DGGJ", $c["n"]);$d === false?die("no..."):NULL;遍歷數組,如果存在字符串DGGJ則出現報錯foreach($c["n"] as $key=>$val){$val==="DGGJ"?die("no......"):NULL;}$key2 = 1;}else{die("no hack");} }else{die("no"); } //如果$key1 && $key2都成立,輸出flag if($key1 && $key2){include "Hgfks.php";echo "You're right"."\n";echo $flag; }?> Emmm...分步解題
a變量獲取
if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){if(isset($b) && '8b184b' === substr(md5($b),-6,6)){$key1 = 1;}else{die("Emmm...再想想");}}else{die("Emmm..."); }isset($a) && intval($a) > 6000000 && strlen($a) <= 3 變量a存在并且滿足下面的條件,長度小,內容大,很容易想到科學計數法,解析如下
- (int)“1e2”==100,在PHP中若像這種格式的字符串轉化成數字,PHP會將其視為科學計數法
通過分析,可以將a用科學技術法表示一個大于6000000的數字 并且長度不能大于三位,直接來個最大的9e9
b變量獲取
isset($b) && '8b184b' === substr(md5($b),-6,6)分析可得b變量的md5值后6位是8b184b,沒什么巧,直接上腳本爆破
import hashlib def get_md5(password):#1- 實例化加密對象md5 = hashlib.md5()#2- 進行加密操作md5.update(password.encode('utf-8'))#3- 返回加密后的結果return md5.hexdigest() for i in range(1,100000):md51=get_md5(str(i))if md51[-6:]=='8b184b':print(i)爆破得b為53724
c變量的獲取
c變量的獲取相對比較麻煩,依次分析
c=(array)json_decode(@$_GET['c']); if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){$d = array_search("DGGJ", $c["n"]);$d === false?die("no..."):NULL;foreach($c["n"] as $key=>$val){$val==="DGGJ"?die("no......"):NULL;}$key2 = 1;}else{die("no hack");} }else{die("no"); }-
(array)json_decode(@$_GET['c']):變量c為josn格式的字符串
- json_decode是php5.2.0之后新增的一個PHP內置函數,其作用是對JSON格式的字符串進行編碼,json_decode接受一個JSON格式的字符串并且把它轉換為PHP變量 ,當該參數$assoc為TRUE時,將返回array,否則返回object。
-
is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022:變量c為數組并且c中的m值不是數字或者字符串,并且值大于2022
- is_numeric() 函數用于檢測變量是否為數字或數字字符串,如果指定的變量是數字和數字字符串則返回 TRUE,否則返回 FALSE,注意浮點型返回 1,即 TRUE。
-
is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0]):變量c的n值為數組,并且n數組有兩個值,并且c變量n值中的第一個值為數組,此時我們可以獲取c變量的格式為{‘m’:xx,‘n’:[[xx,xx…],xx]}
-
$d = array_search("DGGJ", $c["n"]);:變量c的n值中查找是否有DGGJ
- 遍歷n數組中是否有DGGJ,如果有,則返回no…
分析到這里,題目的兩個難點出來了
- m的取值
- n的取值
m的取值
關于m的取值,可以先看一個知識點。
PHP是一門弱類型語言,當涉及“”判斷時,它的表現是有一些奇特的。
例如,“a0”將會得到true,“a==1”將會得到false。
原理:PHP語言中在涉及“==”判斷時,如果運算符兩邊分別為字符串(不以數字開頭的字符串),會將字符串轉化為數字0,再進行比較。如果是以數字開頭的字符串,那么它將會轉化成開頭的數字(即第一個字母前的所有數字)。
唯一的例外就是上面我們提到的科學計數法9e9這種會直接被認定為科學計數法
由此,我們可以得出m的值可以為2023a
n的取值
剛開始,通過分析,我以為只需要再n中有DGGJ字符即可,但是后面遍歷數組后卻又反回了no…,這里我們需要學習另外一個知識點,array_search 的繞過,相當于弱比較,我們直接賦值為 0,即可繞過。
由此可以對n進行賦值,“n”:[[0,2],0]
綜上分析,獲取payload
?a=9e9&b=53724&c={“m”:“2023a”,“n”:[[0,2],0]}
http://xxx:xx/?a=9e9&b=53724&c={“m”:“2023a”,“n”:[[0,2],0]} ,獲得flag
總結
以上是生活随笔為你收集整理的攻防世界web新手-easyphp的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信小程序“网络出错,轻触屏幕重新加载”
- 下一篇: Qt 字体字号和字体像素关系