题目描述:小宁听说php是最好的语言,于是她简单学习之后写了几行php代码。
解题思路
-
分析代码逻辑:
show_source(__FILE__);
:显示当前文件的源代码,这通常是CTF题目中用于帮助选手理解代码逻辑的功能。include("config.php");
:引入配置文件,可能包含$flag1
和$flag2
的定义。$a=@$_GET['a'];
:从GET参数中获取a
的值,@
符号用于抑制错误提示。$b=@$_GET['b'];
:从GET参数中获取b
的值。- 第一个条件:
这个条件看似矛盾,因为if($a==0 and $a){ echo $flag1; }
$a==0
和$a
(即$a
为真)不能同时成立。但在PHP中,==
是弱比较,可能会有类型转换的漏洞。 - 第二个条件:
如果if(is_numeric($b)){ exit(); }
$b
是数值类型,程序会直接退出。我们需要确保$b
不是数值类型。 - 第三个条件:
如果if($b>1234){ echo $flag2; }
$b
大于1234,会输出$flag2
。
-
寻找漏洞点:
- 第一个条件漏洞:
$a==0 and $a
。在PHP中,0
、""
、null
等值会被认为是“假值”,而"0"
(字符串形式的0)会被认为是“真值”。因此,如果$a
是字符串"0"
,$a==0
会成立(因为松散比较会将字符串"0"
转换为数值0
),同时$a
(字符串"0"
)也会被认为是“真值”。因此,$a="0"
可以触发输出$flag1
。 - 第二个条件漏洞:
is_numeric($b)
会检查$b
是否为数值类型。我们需要确保$b
不是数值类型,但同时又要满足$b>1234
的条件。在PHP中,字符串和数值比较时,字符串会被尝试转换为数值。如果字符串以数字开头,会按照数字部分进行比较。例如,字符串"12345abc"
会被转换为12345
,因此"12345abc" > 1234
会成立。同时,"12345abc"
不是数值类型,不会触发is_numeric($b)
的退出。
- 第一个条件漏洞:
构造Payload
根据上述分析,我们可以构造以下payload来获取`$flag:
http://61.147.171.105:57553/?a=null&b=1235abc
最终flag
Cyberpeace{647E37C7627CC3E4019EC69324F66C7C}
知识点
- is_numeric()函数
绕过方法一:
is_numeric($b)
会检查$b
是否为数值类型。我们需要确保$b
不是数值类型,但同时又要满足$b>1234
的条件。在PHP中,字符串和数值比较时,字符串会被尝试转换为数值。如果字符串以数字开头,会按照数字部分进行比较。例如,字符串"12345abc"
会被转换为12345
,因此"12345abc" > 1234
会成立。同时,"12345abc"
不是数值类型,不会触发is_numeric($b)
的退出。
绕过方法二:
可以通过设置 $b
为一个数组来满足条件。
$b = array(1235);