CISP-PTE靶机基础实训之代码审计
代码分析:
<?php
$v1 = 0;
$v2 = 0;
//使用get方法传递一个w的参数,这个参数的内容是一个json格式的数组
$a = (array)json_decode(@$_GET['w']); #json特征是自定义键值使用{},自定义值使用[]
if (is_array($a)) {
is_numeric(@$a["bar1"]) ? die("nope") : NULL; #is_numeric判断bar1是否是数字,是就退出 ,不是就什么都不做
if (@$a["bar1"]) {
($a["bar1"] > 2020) ? $v1 = 1 : NULL; //bar1这个元素要大于2020,才会输出v1=1
}
if (is_array(@$a["bar2"])) #is_array判断bar2是否是数组
{
if (count($a["bar2"]) != 5 or !is_array($a["bar2"][0])) #判断如果bar2数组中元素的个数不等于5或者bar2数组中的第0个元素不是数组,退出循环
{
die("nope");
}
$pos = array_search("cisp-pte", $a["bar3"]); # 在bar3中使用array_search在数组中去寻找元素"cisp-pte"
$pos === false ? die("nope") : NULL; # 找不到,退出循环
foreach ($a["bar2"] as $key => $val) # foreach对数组中的数据进行遍历
{
$val == "cisp-pte" ? die("nope") : NULL; #在bar2中如果出现了cisp-pte,则退出循环
}
$v2 = 1;
}
}
#v1与v2都为真时,输出key
if ($v1 && $v2)
{
include "key.php";
echo $key;
}
highlight_file(__file__);
分析结果:
目标:v1与v2都为真时,输出key
获取一个w参数,参数里的内容是数组形式,数组是json格式,json特征是自定义键值使用{},自定义值使用[]
数组中有三个元素bar1,bar2,bar3
bar1分析结果:元素不能是数字,且必须大于2020,才会输出v1=1
构造bar1:"bar1":"8023x"来进行绕过,在判断是否大于2020时,电脑会进行隐式类型转换,将字符型的8023x,转换成8023与2020作比较,发现8023大于2020,最后输出v1=1
bar2分析结果:元素的内容是一个数组,数组元素的个数为5,且数组中第0个元素必须是数组,数组中也不能有"cisp-pte"这个元素,满足条件输出v2=1
构造bar2:"bar2":[[0],1,2,3,4]
bar3分析结果:元素的内容是一个数组,数组里面必须要有一个"cisp-pte"元素
构造bar3:"bar3":["cisp-pte"]
解决方法:
根据分析结果,拼接bar1,bar2,bar3,使得v1=1,v2=1,最后输出key
拼接结果:(类似于键值形式)
{"bar1":"8023x","bar2":[[0],1,2,3,4],"bar3":[cisp-pte]} # "bar1"(键),"8023x"(值)
将结果填入到w参数中,成功获取到key
?w={"bar1":"8023x","bar2":[[0],1,2,3,4],"bar3":["cisp-pte"]}