[题目信息]:
题目名称 | 题目难度 |
---|---|
PHP-三目运算(练习1) | 2 |
[题目考点]:
PHP三目运算
[Flag格式]:
SangFor{Php_speciALHHH}
[环境部署]:
docker-compose.yml文件或者docker tar原始文件。
http://分配ip:2028
[题目writeup]:
<?php
show_source(FILE);
$v1=0;$v2=0;$v3=0;
$a=(array)json_decode(@$_GET[‘foo’]);
if(is_array($a)){
var_dump($a);
is_numeric(@$a["bar1"])?die("nope"):NULL;
if(@$a["bar1"]){
($a["bar1"]>2016)?$v1=1:NULL;
}
if(is_array(@$a["bar2"])){
if(count($a["bar2"])!5 OR !is_array($a["bar2"][0])) die("nope");
$pos = array_search("nudt", $a["bar2"]);
$pos=false?die("nope"):NULL;
foreach($a["bar2"] as $key=>$val){
$val==="nudt"?die("nope"):NULL;
}
$v2=1;
}
}
$c=@$_GET[‘cat’];
$d=@$_GET[‘dog’];
if(@$c[1]){
if(!strcmp($c[1],$d) && $c[1]!==$d){
echo $c[0];
eregi(“3|1|c”,$d.$c[0])?die(“nope”):NULL;
strpos(($c[0].$d), “sangfor”)?$v3=1:NULL;
}
}
if($v1 && $v2 && $v3){
include “flag.php”;
echo $flag;
}
?>
分析代码逻辑,可以看出foo是一个json对象,经过json_decode()函数解析之后,变量bar1不能为数字,但又要大于2016。所以这里要用到PHP弱类型的一个特性,当一个整形和一个其他类型行比较的时候,会先把其他类型intval再比。 bar1为2017a即可。
变量bar2,首先判断$a[“bar2”]是否是一个数组,长度是否为5,数组中第一个元素是否又为数组,令bar2为[[0],0,1,2,3]即可。
然后还通过GET方法传入了变量cat和dog,而array和string进行strcmp比较的时候会返回一个null,令cat为array变量即可。然后将$d和$c[0]进行拼接,然后通过eregi()来做正则匹配,若出现“3”、“1”、“c”则匹配成功直接die,最后进行两个拼接后字符串的查找,利用eregi()函数的的%00截断漏洞即可绕过。
最后是strpos(($c[0].$d), “sangfor”)?$v3=1:NULL;这里就是一个字符串查找工作,但是不能在首位找到,因此构造$cat[0]=00sangfor。
综上最终构造出来的url为:
?foo={"bar1":"2017e","bar2":[[0],1,2,3,0]}&cat[0]=00sangfor&cat[1][]=1234&dog=%00
[题目信息]:
题目名称 | 题目难度 |
---|---|
PHP-三目运算 | 2 |
[题目考点]:
PHP三目运算
[Flag格式]:
SangFor{mPahxsW_SgP58cdqVmR-0wtGNavwVUs_}
[环境部署]:
docker-compose.yml文件或者docker tar原始文件。
http://分配ip:2045
[题目writeup]:
1、实验主页
2、源码分析
<?php
include("flag.php");
$_GET?$_GET=&$_POST:'flag';
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
?>
分析代码,使用到了三目运算符,其语法格式如下:
(expr1)?(expr2):(expr3); //表达式1?表达式2:表达式3
如果条件“expr1”成立,则执行语句“expr2”,否则执行“expr3”。
再回到题目代码,进行分析
$_GET?$_GET=&$_POST:'flag';
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
第一行:如果存在get传参,则把post传参地址给get,可以简单理解为post覆盖了get。
第四行: 如果get参数HTTP_FLAG
的值为flag,就读取文件,也就是输出flag。
所以可构造如下payload:
?1=2
post:
HTTP_FLAG=flag