PHP代码审计03之实例化任意对象漏洞
前言
根据红日安全写的文章,学习PHP代码审计的第三节内容,题目均来自PHP SECURITY CALENDAR 2017,讲完相关知识点,会用一道CTF题目来加深巩固。之前分别学习讲解了in_array函数缺陷和filter_var函数缺陷,有兴趣的可以去看看:
PHP代码审计01之in_array()函数缺陷
PHP代码审计02之filter_var()函数缺陷
漏洞分析
下面我们看第一题,代码如下:
<?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';
}
}
}
?>
这段代码有两处漏洞,第一处是文件包含漏洞,现在看代码第八行,这里用到了class_exists()函数来判断用户传过来的控制器是否存在。现在看一下PHP手册对这个函数的解释。

通过看上面的解释,我们知道,如果不指定第二个参数,默认情况下,如果本程序存在__autoload()函数,如果检查的类不存在,那么class_exists()函数就会去调用它。这道题的文件包含漏洞,就出现在这里。如果PHP版本在5~5.3之间,就可以使用路径穿越来包含任意文件,比如类名为../../../../../etc/passwd的查找,那么将查看passwd的内容。
第二处漏洞是在上面代码的第10行,我们发现实例化的类名和传入的参数都是我们可以控制的,所以我们可以通过这个漏洞调用PHP代码库的任意构造构造函数。比如可以使用PHP内置类SimpleXMLElement来进行XXE攻击,看一下PHP手册对这个函数的解释:

功能就是用来表示XML文档中的元素。详细的请看下面,重点是第六条,下面要用到它。
SimpleXMLElement::addAttribute-向SimpleXML元素添加属性
SimpleXMLElement::addChild-向XML节点添加子元素
SimpleXMLElement::asXML-基于SimpleXML元素返回格式良好的XML字符串
SimpleXMLElement::attributes-标识元素的属性
SimpleXMLElement::children-查找给定节点的子节点
SimpleXMLElement::__construct-创建新的SimpleXMLElement对象
SimpleXMLElement::count-计算元素的子级
ExtSimpleNamespaces::GetDocElement-在文档命名空间中声明
SimpleXMLElement::getName-获取XML元素的名称
SimpleXMLElement::getNamespaces-返回文档中使用的命名空间
SimpleXMLElement::registerXPathNamespace-为下一个XPath查询创建前缀/ns上下文
SimpleXMLElement::saveXML-别名SimpleXMLElement::asXML
SimpleXMLElement::__toString -返回字符串内容
SimpleXMLElement::xpath-对XML数据运行XPath查询
为了便于理解,用一小段代码来说明:
<?php
$xml = <<<EOF
<?xml version = "1.0" encoding="utf-8"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///C:Windows/win.ini">
]>
<x>&xxe;</x>
EOF;
$xml_class= new SimpleXMLElement($xml,LIBXML_NOENT);
var_dump($xml_class);
?>
查看系统win.ini文件,效果如下图:

CTF练习
通过上面的学习分析,是不是对实例化漏洞和XXE漏洞有了一点点的理解呢?下面我们来做一道CTF题目来练习一下吧,这道题考察的就是实例化漏洞和XXE漏洞。现在我们看具体代码:
<?php
class NotFound{
function __construct()
{
die('404');
}
}
spl_autoload_register(
function ($class){
new NotFound();
}
);
$classname = isset($_GET['name']) ? $_GET['name']:null;
$param = isset($_GET['param']) ? $_GET['param'] : null;
$param2 = isset($_GET['param2']) ? $_GET['param2'] : null;
if (class_exists($classname)){
$newclass = new $classname($param,$param2);
var_dump($newclass);
foreach ($newclass as $key=>$value)
echo $key.'$value'.'<br>';
}
?>
我们把注意力放在class_exists()函数这里,上面我们说过了,这个函数它会去检查类是否定义,如果不存在的话,就会调用程序中的 __autoload 函数。我们发现上面没有__autoload 函数,是用spl_autoload_register注册了和__autoload()差不多的,这里输出404信息。
我们仔细看上面的代码第12~16行,我们发现这里的类和类里面的参数都是我们可以控制的,满足了上面咱们提到的实例化漏洞。也就是说,我们可以调用PHP的内置类来完成我们的攻击。
先用GlobIterator类来寻找flag文件的名字,PHP手册对这个类的构造函数定义如下:

通过上图,我们知道,第一个参数是必须的的,也就是搜索的文件名,第二个参数为选择文件的哪个信息作为键名。咱们先搜一下.txt文件。我们构造payload如下:
http://localhost/DMSJ/day3/index.php?name=GlobIterator¶m=*.txt
效果如下图,我们发现了flag.txt的文件。

下一步,就是查看这个文件,获取flag。用到的内置类为SimpleXMLElement,上面简单的提到了一下,现在就来使用它来进行XXE攻击来查看flag.txt文件的内容。这里需要注意一点:要结合PHP流的使用,因为当文件中存在: < > & ' " 等符号时会导致XML解析错误。我们用PHP流进行base_64编码输出就可以了。
什么是PHP流呢?这里简单说一下,PHP提供了php://的协议允许访问PHP的输入输出流,标准输入输出和错误描述符,内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器,主要提供如下访问方式来使用这些封装器:
php://stdin
php://stdout
php://stderr
php://input
php://output
php://fd
php://memory
php://temp
php://filter
咱们用的最多的是php://input、php://output、php://filter。这里咱们就用php://filter,它是一个文件操作的协议,可以对文件进行读写操作,具体看下表:

read参数值可为:
- string.strip_tags: 将数据流中的所有html标签清除
- string.toupper: 将数据流中的内容转换为大写
- string.tolower: 将数据流中的内容转换为小写
- convert.base64-encode: 将数据流中的内容转换为base64编码
- convert.base64-decode:解码
这样是不是清楚许多了呢?那就构造如下payload:
http://localhost/DMSJ/day3/index.php?name=SimpleXMLElement¶m=<?xml version="1.0"?><!DOCTYPE ANY [<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/phpstudy_pro/WWW/DMSJ/day3/flag.txt">]><x>%26xxe;</x>¶m2=2
上面payload中的param2=2,实际上这里2对应的模式是 LIBXML_NOENT,具体效果如下图:

解码一下,如下:

我们拿到了flag。
小结
通过这篇文章的讲解,是不是对实例化漏洞和XXE漏洞有了更多的理解呢?下一篇文章会对strpos使用不当引发漏洞进行学习和分析,一起努力吧!
PHP代码审计03之实例化任意对象漏洞的更多相关文章
- 代码审计-phpcms9.6.2任意文件下载漏洞
漏洞文件: phpcms\modules\content\down.php 1.在download函数中对文件的校验部分 首先 if(preg_match('/(php|phtml|php3|php4 ...
- 【代码审计】XYHCMS V3.5任意文件下载漏洞分析
0x00 环境准备 XYHCMS官网:http://www.xyhcms.com/ 网站源码版本:XYHCMS V3.5(2017-12-04 更新) 程序源码下载:http://www.xyhc ...
- 【代码审计】CLTPHP_v5.5.3后台任意文件下载漏洞分析
0x00 环境准备 CLTPHP官网:http://www.cltphp.com 网站源码版本:CLTPHP内容管理系统5.5.3版本 程序源码下载:https://gitee.com/chich ...
- Java反射机制demo(二)—通过Class实例化任意类的对象
Java反射机制demo(二)—通过Class实例化任意类的对象 上一章节中,实例化了Class类对象的实例,这个部分的demo展示了如何使用Class对象的实例去获得其他类的对象的实例. 任意一个类 ...
- 【代码审计】ThinkSNS_V4 任意文件下载漏洞分析
0x00 环境准备 ThinkSNS官网:http://www.thinksns.com 网站源码版本:ThinkSNS V4 更新时间:2017-09-13 程序源码下载:http://www ...
- 【代码审计】EasySNS_V1.6 前台任意文件下载漏洞分析
0x00 环境准备 EasySNS官网:http://www.imzaker.com/ 网站源码版本:EasySNS极简社区V1.60 程序源码下载:http://es.imzaker.com/i ...
- PHP代码审计笔记--任意文件下载漏洞
在文件下载操作中,文件名及路径由客户端传入的参数控制,并且未进行有效的过滤,导致用户可恶意下载任意文件. 0x01 客户端下载 常见于系统中存在文件(附件/文档等资源)下载的地方. 漏洞示例代码: ...
- 代码审计-(Ear Music).任意文件下载漏洞
0x01 代码分析 后台地址:192.168.5.176/admin.php admin admin 安装后的界面 在后台发布了一首新歌后,前台点进去到一个“下载LRC歌词”功能点的时候发现是使用re ...
- 140、Java内部类之实例化内部类对象
01.代码如下: package TIANPAN; class Outer { // 外部类 private String msg = "Hello World !"; class ...
随机推荐
- 为什么ping不通google.com
前言 为什么在ping不通Google的时候,我们却可以web直接访问Google (已开启SSR 翻 墙) SSR访问Google 因为GFW的限制导致国内无法直接访问谷歌,那么SSR为什么能绕过限 ...
- 在express中使用ES7装饰器构建路由
在Java的Spring框架中,我们经常会看到类似于@Controller这样的注解,这类代码能够极大的提高我们代码的可读性和复用性.而在Javascript的ES7提案中,有一种新的语法叫做deco ...
- 《Offer一箩筐》一份高质量「简历」撰写指南,望打扰!!
「MoreThanJava」 宣扬的是 「学习,不止 CODE」. 如果觉得 「不错」 的朋友,欢迎 「关注 + 留言 + 分享」,文末有完整的获取链接,您的支持是我前进的最大的动力! Hi~ 这里是 ...
- Badboy脚本录制工具
Badboy 目录 Badboy 1.Badboy安装 2.脚本的录制 1.Badboy安装 下载地址: http://www.badboy.com.au/download/index 安装其实傻瓜式 ...
- ⏰ Moment.js 宣布停止开发,现在该用什么?
本文整理自 Monent.js 官方英文公告 https://momentjs.com/docs/#/-project-status/ Moment.js 宣布停止开发,进入维护状态. 这是一个大而全 ...
- Shell编程(3)
1. shell流程控制 2. for语句 3. while语句 4. break和continue语句 5. case语句 6. shell编程高级实战 shell流程控制 流程控制是改变程序运行顺 ...
- 使用Spring Boot+MyBatis框架做查询操作
一.在你建立的工程下创建 Module 选择Spring initializr创建. 二.在Type处选择: Maven Project(项目的构建工具) 三.创建依赖时勾上web,mybatis,m ...
- 一文带你熟悉JAVA IO这个看似很高冷的菇凉
Java IO 是一个庞大的知识体系,很多人学着学着就会学懵了,包括我在内也是如此,所以本文将会从 Java 的 BIO 开始,一步一步深入学习,引出 JDK1.4 之后出现的 NIO 技术,对比 N ...
- (转)Java中的值传递和引用传递
Java中的值传递和引用传递 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java 编程语言只有值 ...
- Cookies题解
来源:<算法竞赛进阶指南> Describe: 有M块饼干要分给N个孩子.当有k个孩子分到的饼干数比第i个孩子分到的多时,会产生g[i]*k的贡献.求最小的贡献及任意一种方案. Solut ...