37-WEB漏洞-反序列化之PHP&JAVA全解(上)

这篇具有很好参考价值的文章主要介绍了37-WEB漏洞-反序列化之PHP&JAVA全解(上)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

一、PHP 反序列化原理

  • 未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL 注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。
serialize() //将一个对象转换成一个字符串
unserialize() //将字符串还原成一个对象

触发:unserialize 函数的变量可控,文件中存在可利用的类,类中有魔术方法:

参考:https://www.cnblogs.com/20175211lyz/p/11403397.html

__construct()	//创建对象时触发
__destruct() 	//对象被销毁时触发
__call() 			//在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() 			//用于从不可访问的属性读取数据
__set() 			//用于将数据写入不可访问的属性
__isset() 		//在不可访问的属性上调用 isset()或 empty()触发
__unset() 		//在不可访问的属性上使用 unset()时触发
__invoke() 		//当脚本尝试将对象调用为函数时触发

二、案例演示

37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

2.1、无类测试

2.1.1、本地

  • unserialize2.php
<?php
    error_reporting(0);
    include "flag.php";
    $KEY = "xiaodi";
    $str = $_GET['str'];
    if (unserialize($str) === "$KEY")
    {
        echo "$flag";
    }

    show_source(__FILE__);
  • flag.php
<?php
    $flag='flag{flag_is_here}';
?>
  • serialize37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

  • unserialize
    37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

  • 演示:
    37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

  • 一点改动:
    37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全
    37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

2.1.2、CTF 反序列化小真题

  • 链接:
  • 题目:点login咋没反应
    37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

1、可用发现登录按钮无法使用,只是一个摆设。
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

2、查看网页源代码,发现有一个href="admin.css"的可疑信息:

37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全
3、点进去查看,发现提示:
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全
4、在url后面加上?23727,发现有反馈。
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

5、分析代码,可以得出:要想得到flag的值,要让COOKIE的值与KEY的值相等。同时还要满足一个条件:URL上不能够出现23727这个参数,否则执行的是显示源文件的信息,而不是flag的值。

6、抓包,并添加Cookie
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

7、获得flag的值。
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

2.1.3、CTF 反序列化类似题

37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全
1、在URL后面添上?hint可以查看到代码。
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

2、比较COOKIE的值与KEY的值是否相等时,存在一个陷阱。
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全
3、使用KEY为空的值,进行反序列化。
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全
4、获得flag。
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

2.2、有类魔术方法触发

2.2.1、本地

  • unserialize3.php
<?php
    class ABC{
        public $test;
        function __construct(){
            $test = 1;
            echo '调用了构造函数<br>';
        }

        function __destruct(){
			echo '调用了析构函数<br>';
		}
		
        function __wakeup(){
			echo '调用了苏醒函数<br>';
		}
    }
    echo '创建对象a<br>';
    $a = new ABC;
    echo '序列化<br>';
    $a_ser=serialize($a);
    echo '反序列化<br>';
    $a_unser=unserialize($a_ser);
    echo '对象快死了<br>';

37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

2.2.2、网鼎杯 2020 青龙大真题

  • 题目链接:https://www.ctfhub.com/#/challenge
    37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

1、进入环境:
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

 <?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler {

    protected $op;
    protected $filename;
    protected $content;

    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    }

    public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }

    private function output($s) {
        echo "[Result]: <br>";
        echo $s;
    }

    function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }

}

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }

}

2、分析代码:

  • 主函数(传递参数有效就将参数反序列化):
function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }

}
  • 类之前(包含文件,高亮源代码):
include("flag.php");

highlight_file(__FILE__);
  • 类的源代码
// 	- 第一:获取 flag 存储 flag.php
//	- 第二:两个魔术方法__destruct __construct

class FileHandler {

    protected $op;
    protected $filename;
    protected $content;

    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    }
// 	- 第三:传输 str 参数数据后触发 destruct(反序列化之后,相当于添加了一个对象(但是不会触发construct方法,因为是反序列化得来的)。但是会在最后触发destruct方法),存在 is_valid 过滤(如果OP===2,赋值为1;否则就将content赋值为空,调用process方法) 
    
    function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }
// - 第四:__destruct 中会调用 process,其中 op=1 就写入, op=2 就调用读取方法并且赋值给res,再打印res(output()为打印),否则就输出坏黑客。

    public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

	// 写入(OP=1写入)
	// ---如果filename和content都存在,并且content的长度小于100,就将content写入filename,并且输出成功。否则输出失败。
	
    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

	// #读取(OP=2读取)
	// ---如果filename存在,就读取文件。并且打印读取的内容。

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }
	
 // - 第五:涉及对象 FileHandler,变量 op 及 filename,content,进行构造输出。
  • 原理解析(涉及:反序列化魔术方法调用,弱类型绕过,ascii 绕过)

    • 使用该类对 flag 进行读取,这里面能利用的只有__destruct 函数(析构函数)。
    • __destruct 函数对$this->op 进行了===判断并内容在 2 字符串时会赋值为 1(但是process 函数中使用==$this->op 进行判断(为 2 的情况下才能读取内容))
    • 因此这里存在弱类型比较,可以使用数字 2字符串' 2'绕过判断。
    • is_valid 函数还对序列化字符串进行了校验,因为成员被 protected 修饰,因此序列化字符串中会出现 ascii 为 0 的字符。经过测试,在 PHP7.2+的环境中,使用 public 修饰成员并序列化,反序列化后成员也会被 public 覆盖修饰。
  • 总结:

    • 传参str --> destruct方法(强类型对比)
    • op值对比 === 对比类型和值
    • op=’ 2’(字符串);op=‘2’ 两者不相等,不成立
    • 成立,强制op=1,反之op=自己设置的值
    • process()弱类型对比,将’ 2’‘2’对比是一致的

3、分析并构造payload:(protected会在前后加上 %00
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

?str=O:11:"FileHandler":3:{s:2:"op";s:2:" 2";s:8:"filename";s:8:"flag.php";s:7:"content";s:2:"xd";}
  • 如果使用protected
    37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

4、运行。
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

5、查看网页源代码,获得flag。
37-WEB漏洞-反序列化之PHP&JAVA全解(上),学习,web安全,小迪安全,前端,php,java,反序列化,小迪,php反序列化,web安全

5、更多解法。
https://blog.csdn.net/qq_36438489/article/details/106230811文章来源地址https://www.toymoban.com/news/detail-814343.html

三、参考资料

  • https://www.cnblogs.com/20175211lyz/p/11403397.html
  • http://www/dooccn.com/php/
  • https://www.ctfhub.com/#/challenge
  • http://php.jsrun.net/php/t/LWKKp

到了这里,关于37-WEB漏洞-反序列化之PHP&JAVA全解(上)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Day60:WEB攻防-PHP反序列化&POP链构造&魔术方法流程&漏洞触发条件&属性修改

    目录 PHP-DEMO1-序列化和反序列化 序列化操作 - 即类型转换 序列化案例 PHP-DEMO2-魔术方法触发规则 __construct(): //当对象new的时候会自动调用 __destruct()://当对象被销毁时会被自动调用 __sleep(): //serialize()执行时被自动调用 __wakeup(): //unserialize()时会被自动调用 __invoke(): //把对象当

    2024年04月27日
    浏览(39)
  • 反序列化漏洞(PHP)

    0x01. 序列化和反序列化是什么 序列化:变量转换为可保存或传输的字符串的过程; 反序列化:把序列化的字符串再转化成原来的变量使用 作用:可轻松地存储和传输数据,使程序更具维护性 0x02. 为什么会有序列化 序列化用于存储或传递 PHP 的值的过程中,同时不丢失其类型

    2024年02月06日
    浏览(48)
  • php反序列化漏洞基础

            序列化是将对象或类转换为字符串的过程 ,以便在程序运行过程中对其进行持久化存储或传输的操作。在PHP中,序列化主要用于将类对象或数组转换成字节流的形式,以便于存储在磁盘或传输到其他系统。         通过 序列化,可以将对象或类转换成一串字

    2024年01月20日
    浏览(63)
  • PHP反序列化漏洞原理

    1、原理: 序列化与反序列化是保证数据一致性的过程。 2、产生: 序列化与反序列化的过程中,用户可控 如果反序列化的参数受到攻击者的控制,就会产生漏洞。攻击者可以通过修改参数个数等方式来控制反序列化过程,从而导致代码执行、SQL注入、目录遍历等不可控后果。

    2024年01月16日
    浏览(61)
  • 小迪安全47WEB 攻防-通用漏洞&Java 反序列化&EXP 生成&数据提取&组件安全

    # 知识点: 1 、 Java 反序列化演示 - 原生 API 接口 2 、 Java 反序列化漏洞利用 -Ysoserial 使用 3 、 Java 反序列化漏洞发现利用点 - 函数 数据 4 、 Java 反序列化考点 - 真实 CTF 赛题 - 审计分析 # 内容点: 1 、明白 -Java 反序列化原理 2 、判断 -Java 反序列化漏洞 3 、学会 -Ysoserial 工具

    2024年04月10日
    浏览(63)
  • PHP反序列化漏洞-魔术方法绕过

    一、__wakeup()魔法函数绕过: 在PHP中,__wakeup()是一个魔术方法,用于在反序列化对象时自动调用。 当反序列化字符串中的对象属性个数大于实际属性个数时 ,可以利用这个漏洞进行绕过。 触发条件: PHP版本为5.6.25或早期版本,或者PHP7版本小于7.0.10。 反序列化字符串中的对

    2024年01月18日
    浏览(55)
  • 反序列化漏洞及PHP魔法函数

    目录 1、漏洞原理 2、序列化(以PHP语言为例) 3、反序列化 4、PHP魔法函数 (1)__wakeup() (2)__destruct() (3)__construct() (4)__toString() (5)__get() (6)__call() PHP反序列化漏洞也叫PHP对象注入,形成的原因是程序未对用户输入的序列化字符串进行检测,导致攻击者可以控制反

    2024年02月04日
    浏览(59)
  • PHP反序列化漏洞之魔术方法

    PHP魔术方法 (Magic Methods) 是一组特殊的方法,它们在特定的情况下会被自动调用,用于实现对象的特殊行为或提供额外功能。这些方法的名称都以双下划线开头和结尾,例如: __construct() 、 __toString() 等。 魔术方法可以帮助我们实现一些特殊的行为,例如对象的初始化、属性

    2024年02月16日
    浏览(49)
  • PHP反序列化漏洞-字符串逃逸

    字符串逃逸(闭合) 字符串逃逸(闭合)是一种在反序列化函数可控的情况下,通过修改序列化字符串中的敏感字符来达到字符串逃逸的方法。 具体而言,可以通过修改变量名等个数,使得序列化字符串中的字符个数与实际变量值个数不一致 。由于反序列化机制要求字符串

    2024年01月20日
    浏览(57)
  • php魔术方法和反序列化漏洞

    漏洞形成的根本原因就是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、GetShell 等一系列不可控的后果。反序列化漏洞并不是PHP 特有的,也存在于Java、Python 语言中,其原理基本相同。 反序列化是字节流转对象的过程

    2024年02月09日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包