【代码审计】PHP SECURITY CALENDAR 2017 Snow Flake
个人博客地址
http://www.darkerbox.com
欢迎大家学习交流
环境:
https://www.ripstech.com/php-security-calendar-2017/
参考
https://xz.aliyun.com/t/2459
分析
<?php
function __autoload($className) {
include $className;
}
$controllerName = $_GET['c'];
$data = $_GET['d'];
if (class_exists($controllerName)) {
$controller = new $controllerName($data['t'], $data['v']);
$controller->render();
} else {
echo 'There is no page with this name';
}
class HomeController {
private $template;
private $variables;
public function __construct($template, $variables) {
$this->template = $template;
$this->variables = $variables;
}
public function render() {
if ($this->variables['new']) {
echo 'controller rendering new response';
} else {
echo 'controller rendering old response';
}
}
}
这里存在两个漏洞。
- 文件包含漏洞
- 实例化任意对象漏洞
文件包含漏洞
我们看见autoload函数。当实例化一个无法找到的类时,调用autoload函数,将类名传过去。然后包含指定的文件。
我们可以看到这里的autoload没有进行任何过滤,直接使用include包含。而参数是由用户传的。
class_exists($controllerName)
调用了class_exists函数。默认情况下,如果autoload函数存在。class_exists会自动的调用autoload函数。那么就构成了文件包含漏洞。
我现在使用的php版本是5.4.45
。
我包含我本地的xor.html文件。发现页面直接回显了There is no page with this name。if判断是false。
我修改了一下函数,输出一下类名称
然后再次访问。得到了相同的结果。
你会发现,我已经使用print想输出类名,但是并没有成功输出,说明这个autoload
函数并没有调用。。
然而,当我把xor.html
中的.html
去掉。页面报错,并且输出了要实例的类名称。说明autoload被调用了。
从这里可以看出class_exists
函数遇到.
会直接返回false。
注意:使用路径穿越符号的前提是 PHP5~5.3(包含5.3版本)版本 之间才可以
我切换到了5.2.17
再次访问,成功包含了文件。也可以使用../../../
访问其他文件
http://127.0.0.1/3.php?c=xor.html&d=1
任意对象实例化漏洞
漏洞出现在红框中,你会发现。$controllerName
和$data
是用户可控的。我们可以直接实例化任意一个已经存在的类。
例如SimpleXMLElement
类。这是php中的内置类。SimpleXMLElement的构造方法。支持两个参数
那就可以xxe攻击了。先构造一个xxe
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///g:/2.txt">
]>
<x>&xxe;</x>
创建好2.txt文件
d[v]我写为1。才不会报错,。具体啥意思没有深究。
http://127.0.0.1/3.php?c=SimpleXMLElement&d[t]=<?xml version="1.0" encoding="utf-8" ?><!DOCTYPE ANY [<!ENTITY xxe SYSTEM "file:///g:/2.txt">]><x>&xxe;</x>&d[v]=1
然后访问。因为有特殊字符,需要url编码。
可以看见报错,没有render方法。SimpleXMLElement没有render方法所以报错。我们这里修改一下
再次访问
欢迎大家一起学习交流,共同进步,欢迎加入信息安全小白群