柬埔寨头条APP
漏洞报告:ThinkPHP配置不当可导致远程代码执行
游戏王 发表于:2017-8-17 10:32:04 复制链接 看图 发表新帖
阅读数:3536

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册

x
本帖最后由 Taingvengly 于 2017-8-17 10:33 编辑

ThinkPHP配置不当可导致远程代码执行漏洞分析报告
杭州安恒信息技术有限公司
2017年8月11日

1. 漏洞描述
ThinkPHP是一款国内流行的开源PHP框架,近日被爆出存在可能的远程代码执行漏洞,攻击者可向缓存文件内写入PHP代码,导致远程代码执行。虽然该漏洞利用需要有几个前提条件,但鉴于国内使用ThinkPHP框架的站点数量之多,该漏洞还是存在一定的影响范围。
2. 漏洞危害
攻击者可通过该漏洞获取网站的控制权限,可修改页面,导致数据泄漏等问题。
3. 影响版本
ThinkPHP 3、ThinkPHP 5
4. 漏洞利用前置条件
缓存名已知(使用了开源程序/源码泄漏等情况),或者缓存名可猜测(使用了常见的名词,如user, news, goods等)。
/runtime/目录下的文件可通过Web访问。
缓存内容可控或部分可控,可带入PHP代码。
5. 风险等级
高危
6. 漏洞分析
以ThinkPHP 3.2.3为例:
1.jpg
这是一个简单的新闻管理页面,首页调用index方法,列出系统内已有的新闻标题。addnews方法用于插入一条新的新闻数据。detail方法通过获取新闻的tid号查询出新闻的详细内容。
由于新闻的内容较多,查询较慢,通常采用缓存的方式提高访问速度。在这时,如果采用数据缓存的方式,就会产生安全隐患。
1.jpg
这里的逻辑是如果能查到缓存,则直接读取缓存数据,否则从数据库里查出数据,并调用S函数进行缓存。S函数的实现:
1.jpg
首先实例化一个Think\Cache类,然后调用该类的set方法。首先看一下实例化操作:
1.jpg
实例化了Cache类,并调用Connect方法:
1.jpg
可以在ThinkPHP/Conf/convention.php中找到DATA_CACHE_TYPE的默认值为File:
1.jpg
$class=’Think\\Cache\\Driver\\File’,所以S函数的操作为实例化File类并调用其set方法:
1.jpg
在这里可以看到$value的值只是被序列化之后就传入//注释后,而//注释符只是一个单行注释,只需传入换行符就能绕过防御。在137行,$data数据被写入文件,文件名在125行被赋值,跟进一下filename这个函数:
1.jpg
$name = md5(C(‘DATA_CACHE_KEY’).$name) 而DATA_CACHE_KEY在配置文件中默认为空:
1.jpg
于是当访问http://127.0.0.1/thinkphp323/home/news/detail?tid=1时管理页面会去寻找缓存目录下md5(new_1)= b00e5c9873c2a37766a94d11c19131e8.php 这个文件。
下图是访问http://127.0.0.1/thinkphp323/home/news/detail?tid=1的结果:
1.jpg
缓存文件的内容:
1.png
按照上面的分析,通过addnews方法插入一段恶意的代码:
1.jpg
然后用detail方法查看tid为2的记录触发数据缓存:
1.jpg
利用上述计算方法,此时产生的缓存文件名为md5(new_2)= 04f886bf57f9070935c4a0f972032380.php。内容如下:
1.png
直接在浏览器访问:
1.jpg
可以发现输入的恶意代码已经被执行了。
修复建议
在查阅相关资料过程中,发现有文章指出用如下代码进行防御:$data=str_replace(PHP_EOL, '', $data); 经过分析和测试,该防御方式存在绕过方式,而且会影响程序的缓存功能。
新版的ThinkPHP中已经有对缓存的内容进行一定的防护,但是依然可以绕过防护,写入PHP代码。因此主要还是要依靠用户进行安全的配置,为了避免该漏洞产生,安恒应急响应中心建议:
1. 用户在部署程序时勿将ThinkPHP中/public/目录之外的其它目录(尤其是/runtime/)放置到Web目录下。
2. 开发者在程序安装完成后使程序随机生成DATA_CACHE_KEY(在convention.php文件中),以免缓存文件名被猜测出来。
对于已经在使用ThinkPHP框架的用户,可以按下面方法加固站点:
* 进行修改之前请提前备份好数据!
1. 检查Web目录下是否存在/runtime/(/Runtime/)目录,或/application/(/Application/)目录,如果存在这两个目录,则极有可能未正确部署程序。
修改HTTP服务配置,将Wen路径修改到ThinkPHP的./public目录。
2. 添加缓存文件名前缀
在ThinkPHP3中:将convention.php文件中的DATA_CACHE_KEY设置为随机字符串。
参考:https://www.kancloud.cn/manual/thinkphp/1835
在ThinkPHP5中:在缓存初始化操作之前,设置文件前缀
```
$options = [
    // 缓存类型为File
    'type'  =>  'File',
    // 缓存有效期为永久有效
    'expire'=>  0,
    //缓存前缀
    'prefix'=>  'think',
     // 指定缓存目录
    'path'  =>  APP_PATH.'runtime/cache/',
];
Cache::connect($options);
```
- END -   


转至:E安全
条评论
您需要登录后才可以回帖 登录 | 注册
高级
相关推荐