
0X01:前言
近期刷了挺多的ctf題,總結了一些ctf中常見的騷姿勢,
0X02:來啦來啦,騷姿勢總結
一. 弱型別比較
ctf中見怪不怪了,經常已經知道題目要考察的是什么知識了,傳參都要用個弱型別比較來為難一下我們,
-
‘=’,‘’,‘=’
一個等于是賦值,兩個等于是將兩個變數轉相同的型別再比較,三個等于先比較變數型別是否相同再比較值, -
非相同型別比較
如果比較一個數字和字串或者比較涉及到數字內容的字串,則字串會被轉換成數值并且比較按照數值來進行
先看幾組比較結果:




當我們用字串與數值型別比較時會將字符轉變為數值,與C語言不同的是,他這里并不會轉變為ascii碼,而是將開頭的數字轉為對應的數值,開頭沒有數字則轉為0,”0e123456”==”0e456789”相互比較的時候,會將0e這類字串識別為科學技術法的數字,0的無論多少次方都是零,所以相等,
PHP手冊是這么說明的:
當一個字串欸當作一個數值來取值,其結果和型別如下:如果該字串沒有包含’.’,‘e’,'E’并且其數值值在整形的范圍之內 該字串被當作int來取值,其他所有情況下都被作為float來取值,該字串的開始部分決定了它的值,如果該字串以合法的數值開始,則使用該數值,否則其值為0,
0X03弱型別比較的利用
1.md5繞過,當傳入的引數哈希值為0e開頭時有可能觸發,
2.json繞過,當我們不知道鍵的名字時可以嘗試傳入0,嘗試能否滿足形似0==“admin”
3.array_search is_array繞過,
4.strcmp漏洞繞過,要求PHP版本<5.3
0X04總結
正如所說,我們和開發最大的不同就是學習這些冷門的奇技淫巧,還有就是,代碼功底正是很重要,后悔浪費了前兩年,走馬觀花式學習,現在開始惡補java和PHP,
最后附上一句正在某互聯網大廠做PM的前輩對我說過得的話:互聯網是現在為數不多的可以靠努力改變現狀的機會,年輕的時候不拼一把,簡直是浪費,
耳聽為虛,眼見為實,用代碼說話
1.MD5繞過
<?php
use phpDocumentor\Reflection\Types\Null_;
header('Content-type:text/html;charset=utf-8');
show_source(__FILE__);
?>
<html>
<body>
<title>md5繞過</title>
<meta charset="utf-8">
</body>
<body>
<form method="POST">
Str1:<input type="text" name="str1"><br>
Str2:<input type="text" name="str2"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
<?php
$var1 = $_POST["str1"];
$var2 = $_POST["str2"];
if (isset($var1) && isset($var2) && $var1 !== Null && $var2 !== Null) {
if (md5($var1) == md5($var2)) {
echo ("bypass success!!!<br>");
echo ("md5_1 = " . md5($var1) . "<br>");
echo ("md5_2 = " . md5($var2));
} else {
echo ("sorry,please hack me again!");
}
}

這邊傳入的值不一樣,md5值也不同但是都是0exxxxxx格式的,在比較前做型別轉換時會被當作科學計數法值為0所以bypass成功
2.json繞過
<html>
<head>
<title>json繞過</title>
<meta charset="uft-8">
</head>
<body>
<form method="POST">
message:<input type="test" name="message">
<input type="submit" name="提交">
</form>
</body>
</html>
<?php
show_source(__FILE__);
header('Content-type:text/html;charset="utf-8"');
if (isset($_POST['message'])) {
$message = json_decode($_POST['message']);
$key = "admin";
if ($message->key == $key) {
echo "success";
} else {
echo "fail";
}
}

輸入一個陣列進行json解碼,如果解碼后的message與key值相同,會得到flag,主要思想還是弱型別進行繞過,我們不知道key值是什莫,但是我們知道一件事就是它肯定是字串,這樣就可以了,上文講過,兩個等號時會轉化成同一型別再進行比較,直接構造一個0就可以相等了,最終payload message={“key”:0}
3.array_search is_array繞過
<?php
if(!is_array($_GET['test'])){exit();}
$test=$_GET['test'];
for($i=0;$i<count($test);$i++){
if($test[$i]==="admin"){
echo "error";
exit();
}
$test[$i]=intval($test[$i]);
}
if(array_search("admin",$test)===0){
echo "flag";
}
else{
echo "false";
}
?>
這段代碼的意思就是先判斷是不是陣列,然后在把陣列中的內容一個個進行遍歷,所有內容都不能等于admin,型別也必須相同,然后轉化成int型,然后再進行比較如果填入值與admin相同,則回傳flag,如何繞過呢?
基本思路還是不變,因為用的是三個等于號,所以說“= =”號這個方法基本不能用,那就用第二條思路,利用函式接入到了不符合的型別回傳“0”這個特性,直接繞過檢測,所以payload:test[]=0,
在PHP手冊中,in_array()函式的解釋是bool in_array ( mixed needle,arrayhaystack [, bool strict=FALSE]),如果strict引數沒有提供或者是false(true會進行嚴格的過濾),那么inarray就會使用松散比較來判斷needle是否在$haystack中,當strince的值為true時,in_array()會比較needls的型別和haystack中的型別是否相同,
$array=[0,1,2,'3'];
var_dump(in_array('abc', $array)); //true
var_dump(in_array('1bc', $array)); //true
4.strcmp漏洞繞過(PHP版本<5.3)
<?php
show_source(__FILE__);
error_reporting(0);
$var1 = $_REQUEST['string1'];
$var2 = $_REQUEST['string2'];
echo ("String1:" . $var1 . " " . "type:" . gettype($var1));
?>
<br>
<?php
echo ("String2:" . $var2 . " " . "type:" . gettype($var2));`
?>
<br>
<?php
$bool = strcmp($var1, $var2);
if ($bool < 0) {
echo $bool . '<br>';
echo ("str1<str2");
} elseif ($bool == 0) {
echo $bool . '<br>';
echo ("str1=str2");
} else {
echo $bool . '<br>';
echo ("str1>str2");
}

語法:strcmp(string1,string2)
回傳值:
0 - 如果兩個字串相等
0 - 如果 string1 小于 string2
0 - 如果 string1 大于 string2
漏洞:在PHP5.3之前,傳入非String型別的會回傳0,即相等,
為了回饋讀者,我整理了一些CTF相關的資源供大家閱讀,【點我查看檔案】

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/289181.html
標籤:其他
