详解php反序列化之字符逃逸法
在介绍php反序列化中的字符逃逸法之前,需要先了解序列化和反序列化的基本概念。所谓序列化是将一个对象转换成一个字符串,反序列化是将一个字符串转换成一个对象。当两个系统需要交换数据时,就需要序列化和反序列化。php的序列化函数是serialize(),反序列化函数是unserialize()。
在php中,当序列化一个类时,会将对象中的所有属性和方法都序列化,并在序列字符串前加上类的名称和一些其他信息。反序列化时,会将序列化字符串转换成一个对象,并通过类的__wakeup()方法将对象属性还原为原始状态。
php反序列化漏洞的成因
php反序列化漏洞是指攻击者可以构造一些恶意的序列化字符串,将其提交到服务端,服务端在反序列化过程中执行了攻击者预设好的恶意代码。造成反序列化漏洞的成因主要有两点:
1. 反序列化时不做严格的数据检验导致漏洞;
2. 攻击者通过构造恶意的输入,使得反序列化的结果不可预期,进而实现代码执行。
接下来,我们将深入探讨如何利用php的反序列化漏洞之字符逃逸法。
php反序列化字符逃逸法的原理
php反序列化字符逃逸法本质上是通过在序列化时使用一些特殊的字符,从而欺骗反序列化函数认为反序列化过程已经结束,达到Bypass的效果。
具体来讲,就是在序列化时使用双引号包围的字符串中嵌套反斜杠,这样在反序列化时,反序列化函数会认为字符串已经结束,并将反斜杠后的内容看做代码执行。
php反序列化字符逃逸法的攻击步骤
接下来,我们将介绍php反序列化字符逃逸法的具体攻击步骤,以攻击CMS Made Simple 2.2.8版本为例:
- 根据漏洞信息,我们可以确定漏洞存在于/classes/SmartyCustom.php文件的getSmarty()函数中。在函数中,我们发现unserialize()函数被调用,容易推断出序列化字符串来自cookie中的‘__cms’参数。
private function getSmarty($template_dir, $compile_dir, $cache_dir, $config_dir)
{
if ($this->smty==null) {
$smarty = new \Smarty;
$smarty->setTemplateDir($template_dir);
$smarty->setCompileDir($compile_dir);
$smarty->setCacheDir($cache_dir);
$smarty->setConfigDir($config_dir);
if (isset($_COOKIE['__cms'])) {
$smarty->assign(unserialize($_COOKIE['__cms']));
}
$this->smty = $smarty;
}
return $this->smty;
}
- 我们在cookie中添加‘__cms’参数,并在其中写入构造好的序列化字符串。值得注意的是,在序列化中,我们添加了双引号包围的字符串,并将其中的反斜杠进行了嵌套。
O:4:"Pwn3d":1:{s:7:"message";s:55:"Hello from '\\"\}\}\]\');";}`}
- 页面重新加载时,unserialize()函数将读取cookie中的‘__cms’参数,并将其解析成对象。在解析字符串时,unserialize()函数将双引号包围的字符串视为一个完整的参数,而忽略其中的反斜杠。
"O:4:\"Pwn3d\":1:{s:7:\"message\";s:55:\"Hello from '\"}}]');\";}"
- 最终,由于字符串被视为完整字符串,而反斜杠被忽略,导致执行了恶意代码,在页面中弹出‘Hello from '"+}}]');”的弹窗。
示例1:php反序列化字符逃逸法的适用场景
攻击者之所以会利用php反序列化字符逃逸法,一方面是因为其实现简单,另一方面是其比较适用于一些开发框架或应用中自动进行序列化和反序列化的场景。下面我们来看一个具体的例子。
在php中,我们经常使用ORM(Object-Relational Mapping)框架来进行数据库操作。ORM框架会将对象转换成对应的数据库表结构,并在查询时将查询结果转换成对应的对象,这就涉及到了序列化和反序列化。
例如,我们使用了yii2框架,并且我们的模型中存在安全漏洞,攻击者可以提交特殊的数据使得框架进行反序列化,并执行恶意代码。这时,攻击者就可以利用字符逃逸法来构造序列化字符串,从而通过美妙的序列化达到攻击的目的。
示例2:php反序列化字符逃逸法的实战演练
接下来,我们将通过一个实例演练如何使用php反序列化字符逃逸法进行攻击。本次演练的目标是官方提供的PHP Object Injection漏洞演示网站。这个漏洞网站中,存在一个图书管理系统,并且用户可以通过该系统将自己的图书添加进去。
可以通过添加具有恶意的序列化数据的POST请求来进行攻击。攻击流程步骤为:
-
使用Burp Suite进行数据包拦截,并且修改管理员的cookies(PHPSESSID)。进入CMS的主界面。点击Library Manager,进入图书管理页面。
-
添加图书,利用cookie进行基于序列化的注入。
-
注入代码,我们将代码注入到图书名称中。在名称中写入如下序列化字符串:
O:8:"BookClub":1:{s:4:"name";s:54:"a";s:4:"desc";s:0:"";s:8:"position";i:0;O:8:"bookClu
»
}";}
其中,符号 » 被使用作为一个反斜杠。
- 重新加载界面时,服务器将读取cookies中的用户信息,并通过反序列化构造一个图书对象。由于字符串被视为完整字符串,而反斜杠被忽略,导致执行了恶意代码,使得攻击者可以获取到管理员的cookies,从而劫持管理员的会话。
综上所述,php反序列化字符逃逸法是一种危害巨大的攻击手段,对于那些利用反序列化实现自动化序列化和反序列化的使用场景尤为危险。因此,作为开发者应该时刻意识到php反序列化漏洞的可能性,加强对用户储存数据的严格校验及过滤,同时需要谨慎选择使用反序列化。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解php反序列化之字符逃逸法 - Python技术站