php反序列化漏洞之pop链

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

目录

POP链简介

pop面向属性编程

pop chain

pop链利用技巧

1、在pop链中出现的方法

2、反序列化中为了避免信息丢失可以使用大写S支持字符串的编码

3、深浅copy

4、利用php伪协议

POP键构造复现

例子1

分析

大概payload为

最后我们的payload为

结果phpinfo();内容可以改为木马代码


POP链简介

pop面向属性编程

常用于上层语言构造特定调用链的方法与二进制利用中的面向返回编程Return-Oriented Programing的原理相似都是从现有运行环境中寻找一系列的代码或者指令调用然后根据需求构成一组连续的调用链最终达到攻击者邪恶的目的。类似于PWN中的ROP有时候反序列化一个对象时由它调用的__wakeup()中又去调用了其他的对象由此可以溯源而上利用一次次的  " gadget " 找到漏洞点。

pop chain

把魔术方法作为最开始的小组件然后在魔术方法中调用其他函数(小组件)通过寻找相同名字的函数再与类中的敏感函数和属性相关联就是POP CHAIN 。此时类中所有的敏感属性都属于可控的。当unserialize()传入的参数可控便可以通过反序列化漏洞控制POP CHAIN达到利用特定漏洞的效果。

pop链利用技巧

1、在pop链中出现的方法

- 命令执行exec()、passthru()、popen()、system()

- 文件操作file_put_contents()、file_get_contents()、unlink()

- 代码执行eval()、assert()、call_user_func()

2、反序列化中为了避免信息丢失可以使用大写S支持字符串的编码

PHP 为了更加方便进行反序列化 Payload 的 传输与显示(避免丢失某些控制字符等信息)我们可以在序列化内容中用大写S表示字符串此时这个字符串就支持将后面的字符串用16进制表示使用如下形式即可绕过即

s:4:"user"; -> S:4:"use\72";

3、深浅copy

在php中如果我们使用 & 对变量A的值指向变量B这个时候是属于浅拷贝当变量B改变时变量A也会跟着改变。在被反序列化的对象的某些变量被过滤了但是其他变量可控的情况下就可以利用浅拷贝来绕过过滤。

$A = &$B; 

4、利用php伪协议

配合PHP伪协议实现文件包含、命令执行等漏洞。

php伪协议_奋斗的小智的博客-CSDN博客_php伪协议写文件PHP伪协议也是php支持的协议和封装协议。file:// 访问本地文件系统php:// 访问各个输入/输出流data:// 数据zip:// 压缩流 不过有些伪协议需要allow_url_fopen和allow_url_include的支持。allow_url_fopen On/Off 允许或禁止打开URL文件allow_url_include On/Off 允许或禁止引用URL文件。https://blog.csdn.net/weixin_60719780/article/details/128773811

POP键构造复现

例子1

<?php
class main {
    protected $ClassObj;

    function __construct() {
        $this->ClassObj = new normal();
    }

    function __destruct() {
        $this->ClassObj->action();
    }
}

class normal {
    function action() {
        echo "hello bmjoker";
    }
}

class evil {
    private $data;
    function action() {
        eval($this->data);
    }
}
//$a = new main();
unserialize($_GET['a']);
?>

分析

代码审计针对以上代码我首先看到 eval这个危险函数 它是命令执行方法函数而且不在魔术方法中的eval 在action 函数中的而action函数又在evil类中也就是说要执行eval那必须要执行action函数那我们继续看代码发现action函数也在normal类中的而我们的__destruct()析构函数执行方式是析构函数和构造函数相反在对象不再被使用时(将所有该对象的引用设为null)或者程序退出时自动调用这个函数是必须执行的__destruct()在程序结束时会去调用normal类中的action()方法而我们最终的目的是去调用evil类中的action()方法并伪造evil类中的变量$data达成任意代码执行的目的。

大概payload为

class main {
    protected  $ClassObj = new evil();
}

class evil {
    private $date = 'phpinfo();';
}

特别注意我在构建payload时候提交的时候为空\x00显示为%20 它是空格的意思第一次提交出现无法解析我没有注意到这里我说出来大家可以避免这个问题

1. 受Private修饰的私有成员序列化时: \x00 +  [私有成员所在类名]  + \x00 [变量名]

2. 受Protected修饰的成员序列化时\x00 + * + \x00 + [变量名]

其中"\x00"代表ASCII为0的值即空字节" * " 必不可少。

最后我们的payload为

O%3A4%3A%22main%22%3A1%3A%7Bs%3A11%3A%22%00%2A%00ClassObj%22%3BO%3A4%3A%22evil%22%3A1%3A%7Bs%3A10%3A%22%00evil%00data%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D

结果phpinfo();内容可以改为木马代码

还有几道有特点的题我还没搞明白掌握后我再整理。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: php