写在前面:
- Ok,guys!那么从现在开始,我就会尝试写一下ctf比赛的解题攻略了,那么这是第一篇!
easyphp:
首先第一步获取在线场景,得到网址。我们进入之后发现是php的代码。
接下来,老样子,对代码进行审计。
源代码是这样子的:<?php highlight_file(__FILE__); $key1 = 0; $key2 = 0; $a = $_GET['a']; $b = $_GET['b']; 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..."); } $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"); } if($key1 && $key2){ include "Hgfks.php"; echo "You're right"."\n"; echo $flag; } ?> Emmm...
我们首先来看最终的条件,发现最终要包含Hgfks.php的话,必须要条件
$key1 && $key2
,而key1=1以及key2=1的条件是由上面两个函数决定的。那么,我们来重点看上面的判断条件。
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)
当变量a被设置,那么返回true,否则返回false。
第二个函数:intval($a)
把变量a变成整数,那么如果是字符串呢?我们不妨实践一下:
首先在本地用phpstudy开一个服务器,新建一个ok.php用来实验。这里测试用的代码是这样的:
<?php
$a = $_GET['a'];
echo intval($a);
echo '<br>';
echo strlen($a);
?>
我们发现:
1.如果.index.php?a=abc
,那么就会结果是0 3
,就是说如果a是字符串,那么intval均为0.
2.如果.index.php?a=123
,那么就会结果是123 3
,就是说a如果是数字,那么strlen会强制转换为字符串.
而括号中的判断条件很苛刻,既要intval($a)>6000000
又要strlen($a)<=3
这显然是野猪行为!
那么我们就换个思路,看看能否将它多余的进行闭合掉。