填坑嘛,想起来好久以前立的flag,要写写PHP反序列化相关
这里就再补充一下上一篇没有涉及到的PHP反序列化常见姿势
PHP反序列化相关函数
- nstruct(), destruct()
构造函数与析构函数
- call(), callStatic()
方法重载的两个函数
__call()是在对象上下文中调用不可访问的方法时触发
__callStatic()是在静态上下文中调用不可访问的方法时触发。
get(), set()
__get()用于从不可访问的属性读取数据。
__set()用于将数据写入不可访问的属性。
- isset(), unset()
__isset()在不可访问的属性上调用isset()或empty()触发。
__unset()在不可访问的属性上使用unset()时触发。
- sleep(), wakeup()
serialize()检查您的类是否具有魔术名sleep()的函数。如果是这样,该函数在任何序列化之前执行。它可以清理对象,并且应该返回一个数组,其中应该被序列化的对象的所有变量的名称。如果该方法不返回任何内容,则将NULL序列化并发出E_NOTICE。sleep()的预期用途是提交挂起的数据或执行类似的清理任务。此外,如果您有非常大的对象,不需要完全保存,该功能将非常有用。
unserialize()使用魔术名wakeup()检查函数的存在。如果存在,该功能可以重构对象可能具有的任何资源。wakeup()的预期用途是重新建立在序列化期间可能已丢失的任何数据库连接,并执行其他重新初始化任务。
- __toString()
__toString()方法允许一个类决定如何处理像一个字符串时它将如何反应。
- __invoke()
当脚本尝试将对象调用为函数时,调用__invoke()方法。
__set_state()
__clone()
__debugInfo()
PHP反序列化与POP链
常用的POP链方法
命令执行:
- exec()
- passthru()
- popen()
- system()
文件操作:
- file_put_contents()
- file_get_contents()
- unlink()
反序列化漏洞挖掘的思路
除开比赛中直观的可利用的类
大致还有一下思路
- 依赖库(原生类)
- 框架
- PHP本身的CVE
CVE-2016-7124
来分析一下CVE-2016-7124这个著名的漏洞
它可以绕过魔法函数
利用环境为PHP5 < 5.6.25
PHP7 < 7.0.10
漏洞危害在于序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
这个demo明天上来补
CTF中的反序列化
还是上一个例题吧
jarvisoj的一道题目
http://web.jarvisoj.com:32784/index.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = 'phpinfo();';
}
function __destruct()
{
eval($this->mdzz);
}
}
if(isset($_GET['phpinfo']))
{
$m = new OowoO();
}
else
{
highlight_string(file_get_contents('index.php'));
}
从上篇文章猜想这里可以通过session的机制触发反序列化
但是没有通过php_serialize添加session的方法
我们先看看phpinfo页面
session.upload_progress.enabled为On
session.upload_progress.enabled本身作用不大,是用来检测一个文件上传的进度。但当一个文件上传时,同时POST一个与php.ini中session.upload_progress.name同名的变量时(session.upload_progress.name的变量值默认为PHP_SESSION_UPLOAD_PROGRESS),PHP检测到这种同名请求会在$_SESSION中添加一条数据。我们由此来设置session。
(别看了,这是别人的wp
然后直接读文件就行了