看代码学安全(9 )str_replace函数过滤不当

本文转载自 先知社区:https://xz.aliyun.com/t/2541

经红日安全审计小组授权。

-----------------------------------------------------------------------------------

本文由红日安全成员: 七月火 编写,如有不当,还望斧正。

前言

大家好,我们是红日安全-代码审计小组。最近我们小组正在做一个PHP代码审计的项目,供大家学习交流,我们给这个项目起了一个名字叫 PHP-Audit-Labs 。现在大家所看到的系列文章,属于项目 第一阶段 的内容,本阶段的内容题目均来自 PHP SECURITY CALENDAR 2017 。对于每一道题目,我们均给出对应的分析,并结合实际CMS进行解说。在文章的最后,我们还会留一道CTF题目,供大家练习,希望大家喜欢。下面是 第9篇 代码审计文章:

Day 9 - Rabbit

题目叫做兔子,代码如下:

漏洞解析 :

这一题考察的是一个 str_replace 函数过滤不当造成的任意文件包含漏洞。在上图代码 第18行 处,程序仅仅只是将 ../ 字符替换成空,这并不能阻止攻击者进行攻击。例如攻击者使用payload:....// 或者 ..././ ,在经过程序的 str_replace 函数处理后,都会变成 ../ ,所以上图程序中的 str_replace 函数过滤是有问题的。我们来看一下PHP手册对 str_replace 函数的具体定义:

str_replace :(PHP 4, PHP 5, PHP 7) 功能 :子字符串替换 定义 : mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] ) 该函数返回一个字符串或者数组。如下: str_replace(字符串1,字符串2,字符串3):将字符串3中出现的所有字符串1换成字符串2。 str_replace(数组1,字符串1,字符串2):将字符串2中出现的所有数组1中的值,换成字符串1。 str_replace(数组1,数组2,字符串1):将字符串1中出现的所有数组1一一对应,替换成数组2的值,多余的替换成空字符串。

实例分析

本次实例分析,我们选取的是 Metinfo 6.0.0 版本。漏洞文件在 app/system/include/module/old_thumb.class.php 中,我们发现程序将变量 $dir 中出现的 ../ 和 ./ 字符替换成空字符串(下图第6行处),猜想开发者应该是有考虑到路径穿越问题,所以做了此限制。具体代码如下:

接着在第8行处,用 strstr 函数判断 $dir** 变量中是否含有 **http** 字符串,如果有,则读取加载 **$dir 变量,并以图片方式显示出来。这里猜测开发者的意图是,加载远程图片。关于 strstr 函数,定义如下:

strstr :(PHP 4, PHP 5, PHP 7)

功能 :查找字符串的首次出现

定义 : string strstr ( string $haystack , mixed $needle [, bool $before_needle = FALSE ] )

返回 haystack 字符串从 needle 第一次出现的位置开始到 haystack 结尾的字符串。

domain = strstr('hongrisec@gmail.com', '@');// 上面输出:@gmail.comuser = strstr('hongrisec@gmail.com, '@', true); // 从 PHP 5.3.0 起
// 上面输出:hongrisec

然而这段代码是可以绕过的,例如我们使用 payload:.....///http/.....///.....///.....///.....///etc/passwd,过滤后实际就变成: ../http/../../../../etc/passwd ,效果如下:

接下来,我们要做的就是搜索程序在哪里调用了这个文件。用 phpstorm 加载整个项目文件,按住 Ctrl+Shift+F 键,搜索关键词 old_thumb ,发现在 include/thumb.php 文件中调用 old_thumb 类,搜索结果如下图:

我们在 include/thumb.php 文件中,可以看到 M_CLASS 定义为 old_thumb ,而 M_ACTION 定义为 doshow 。我们接着跟进到 app/system/entrance.php 文件中,在该文件的末尾可以看包含了 app/system/include/class/load.class.php 文件,引入了 load 类,然后调用了 load 类的 module方法。

// app/system/include/class/load.class.phprequire_once PATH_SYS_CLASS.'load.class.php';
load::module();

我们跟进 module 方法,并查看各个变量的赋值情况( app/system/include/class/load.class.php 文件):

上图程序最后调用了 load 类的 _load_class 方法,我们跟进该方法,详细代码如下:

可以看到上图代码第16行处实例化了一个 old_thumb 类对象,然后在第25行处调用了 old_thumb 类的 doshow 方法, doshow 方法中的 $dir 变量就是用户可以控制的。以上便是完整的攻击过程分析,下面我们看看具体如何进行攻击。

漏洞利用

实际上攻击的话就很简单了,因为 $dir 变量是直接通过 GET请求 获取的,然后用 str_replace 方法处理,而 str_replace 方法处理又有问题,所以我们构造 payload 如下:

http://localhost/metInfo/include/thumb.php?dir=.....///http/.....///最终用户授权许可协议.txt

成功读取 最终用户授权许可协议.txt 文件。

修复建议

关于修复建议,这里先抛出个问题给大家,针对这个案例,下面的修复代码是否可行?

$dir = str_replace(array('..','//'), '', $_GET['dir']);

咋一看,这个代码好像完美地修复了路径穿越问题,但是,我们在修复代码的时候一定要结合实际情况。比如在metinfo中,程序这里原来的功能是加载远程图片,使用上面的修复代码,会导致正常的图片链接无法加载,这种修复肯定是无效的。这里给出我的修复代码,如下图:

本文分享自微信公众号 - 玄魂工作室(xuanhun521)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-11-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏同步博客

制作类似ThinkPHP框架中的PATHINFO模式功能

  搞PHP的都知道ThinkPHP是一个免费开源的轻量级PHP框架,虽说轻量但它的功能却很强大。

23530
来自专栏程序员互动联盟

【编程基础】C语言内存使用的常见问题

所讨论的“内存”主要指(静态)数据区、堆区和栈区空间。数据区内存在程序编译时分配,该内存的生存期为程序的整个运行期间,如全局变量和static关键字所声明的静态...

59360
来自专栏Jimoer

JVM学习记录-Java内存模型(二)

在处理多线程数据竞争问题时,不仅仅是可以使用synchronized关键字来实现,使用volatile也可以实现。

9730
来自专栏coder修行路

《深入理解计算机系统》阅读笔记--程序的机器级表示(上)

编译器基于编程语言的规则,目标机器的指令集和操作系统遵循的惯例,经过一系列的阶段生成机器代码。GCC c语言编译器以汇编代码的形式产生输出,汇编代码是机器代码的...

14200
来自专栏coding for love

JS入门难点解析4-执行上下文栈

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

12440
来自专栏陈满iOS

类方法调用实例方法的后果:Instance method 'fetchXXX:data:success:failure:' is being used on 'Class' which is n...

12110
来自专栏Janti

Java多线程高并发学习笔记(二)——深入理解ReentrantLock与Condition

锁的概念 从jdk发行1.5版本之后,在原来synchronize的基础上,增加了重入锁ReentrantLock。 本文就不介绍synchronize了,有兴...

45260
来自专栏大数据架构

Java进阶(二)当我们说线程安全时,到底在说什么

这一点,跟数据库事务的原子性概念差不多,即一个操作(有可能包含有多个子操作)要么全部执行(生效),要么全部都不执行(都不生效)。

472130
来自专栏无题

Java并发编程:volatile关键字解析

我将一些最关键的要点和结论先做一下总结。如果要做细致的理解,通读全文还是很有必要的。 1.并发编程中三个原则: 原子性,可见性,有序性 2.先行发生原则: ...

44960
来自专栏开源优测

BeautifulSoup的使用

参考资料地址:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/#id28

13910

扫码关注云+社区

领取腾讯云代金券