PHP-弱类型解题

这是ZCTF线下关于php弱类型的题目

先po一下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
$l01o=0;
$o1l0=0;
$o10l=0;
$lo10=0;
if (isset($_GET['vhghf']))
{
$vhghf = $_GET['vhghf'];
$vhghf=="1"?die("ha?"):NULL;
switch ($vhghf)
{
case 0:
case 1:
$l01o=1;
break;
}
}
$dfgdf=(array)json_decode(@$_GET['dfgdf']);
if(is_array($dfgdf)){
is_numeric(@$dfgdf["gvnghdjk"])?die("ha?"):NULL;
if(@$dfgdf["gvnghdjk"]){
($dfgdf["gvnghdjk"]>2017)?$o1l0=1:NULL;
}
if(is_array(@$dfgdf["uxcndffznb"])){
if(count($dfgdf["uxcndffznb"])!==2 OR !is_array($dfgdf["uxcndffznb"][0])) die("ha?");
$kghdhfghdfgbcvhgffg = array_search("ZCTF", $dfgdf["uxcndffznb"]);
$kghdhfghdfgbcvhgffg===false?die("ha?"):NULL;
foreach($dfgdf["uxcndffznb"] as $key=>$val){
$val==="ZCTF"?die("ha?"):NULL;
}
$o10l=1;
}
}
$cdggjydcnfsdyjaq = $_GET['cdggjydcnfsdyjaq'];
if ($cdggjydcnfsdyjaq != '15562') {
if (strstr($cdggjydcnfsdyjaq, '2017ZCTF')) {
if (substr(md5($cdggjydcnfsdyjaq),8,16) == substr(md5('15562'),8,16)) {
$lo10=1;
}
}
}
if($l01o && $o1l0 && $o10l && $lo10){
include "flag.php";
echo $flag;
}
?>

目的

从大体上看得出,是要求($l01o && $o1l0 && $o10l && $lo10)都符合要求了就出flag,而具体看就是要求这四个值都为1

以下是一段一段代码来进行分析

l01o

1
2
3
4
5
6
7
8
9
10
11
12
if (isset($_GET['vhghf']))
{
$vhghf = $_GET['vhghf'];
$vhghf=="1"?die("ha?"):NULL;
switch ($vhghf)
{
case 0:
case 1:
$l01o=1;
break;
}
}

经过测试,将vhghf与1进行比较,而且是双等号,直接1+任意字母绕过(手工fuzz,除了1#不能出结果之外,哪位知道的告知一声)。

o1l0+o10l

而第二和第三个,因为是数组关系,就放一起讲

dfgdf["gvnghdjk"]>2017与第一个相似,用大于2017的数值加任意字母绕过。
下面是官方手册对array_search的介绍

1
mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] )

$needle$haystack必需,$strict可选 函数判断$haystack中的值是存在$needle,存在则返回该值的键值 第三个参数默认为false,如果设置为true则会进行严格过滤

1
2
3
4
5
<?php
$a=array(0,1);
var_dump(array_search("admin",$a)); // int(0) => 返回键值0
var_dump(array_seach("1admin",$a)); // int(1) ==>返回键值1
?>

array_search函数 类似于== 也就是$a==”admin” 当然是$a=0 当然如果第三个参数为true则就不能绕过
数字0双等于所有的无数字开头的字符串,可以用0去绕过array_search的比较。

lo10

= $_GET['cdggjydcnfsdyjaq'];link
1
2
3
4
5
6
7
8
if ($cdggjydcnfsdyjaq != '15562') {
if (strstr($cdggjydcnfsdyjaq, '2017ZCTF')) {
if (substr(md5($cdggjydcnfsdyjaq),8,16) == substr(md5('15562'),8,16)) {
echo "4"."<br>";
$lo10=1;
}
}
}

最后一部分,规则已经制定好,$cdggjydcnfsdyjaq != '15562'

下来看到

1
(substr(md5($cdggjydcnfsdyjaq),8,16) == substr(md5('15562'),8,16))

线上赛的时候已经有过md5碰撞

最后的payload:

?vhghf=1w&dfgdf={“gvnghdjk”:”2018w”,”uxcndffznb”:[[“ZCTF”],0]}&cdggjydcnfsdyjaq=x2017ZCTF24834

!坚持技术分享,您的支持将鼓励我继续创作!