thinkphp3.2.3经典漏洞:缓存函数不当使用导致临时文件变木马
发布于 作者:苏南大叔 来源:程序如此灵动~本文中的经典漏洞,来自于thinkphp@3.2.3
的S()
函数。在这个漏洞中,由于编程人员的疏忽,可能会把一些客户可控的参数,写入到缓存中。而对于thinkphp@3.2.3
来说,默认的缓存处理机制中,这又是一个可访问的.php
文件。那么,漏洞就这么产生了。
本文测试环境:mac
、thinkphp@3.2.3
、php72
。苏南大叔在本文中,要描述的就是这样一个漏洞,框架默认+运维配置不当+程序猿没注意。就可能导致本文中的漏洞发生。这个S()
函数会把值缓存成某个特殊的可执行的临时.php
文件保存起来。
发生漏洞的可能场景
程序员获得了一个用户提交的变量,然后使用S()
函数把它保存了下来。例如:
//S("bug",$_GET["poc"]);
S("bug",I("get.poc"));
漏洞背后的默认值情况
注意缓存变量的名字是bug
,用户传递的变量名是poc
。其中的缓存名字,这个是本文漏洞的关键线索。thinkphp@3
默认是使用File
做缓存的,而且缓存文件的名字是可以依法换算的.php
文件。
缓存文件的名字命名规则是这样的:md5(name)
。比如,在上面的例子中,缓存的名字是bug
,那么文件名就是ae0e4bdad7b5f67141743366026d2ea5.php
。
而这个临时文件的默认存储路径是:
<domain>/Application/Runtime/Temp/<md5>.php
漏洞的利用
因为这个漏洞是的本质,就是把用户传递的参数保存到一个.php
缓存中了。那么,根据缓存文件的代码情况,可以构造一个特殊的参数,形成一个事实上的一句话木马。下面以phpinfo()
函数的执行为例:
下图中的参数,可以构造一个phpinfo()
的可执行缓存文件。
http://tp3/?poc=%0aphpinfo();//
- 关键突破口是
%0a
,它产生了一个换行符 - 而
//
曾注释掉了后续的代码。
下面的截图是,缓存文件的真实代码结果(注意看换行符的产生):
根据文件的默认路径,大家可以访问到下面的网址,进而执行相关的php
代码。注意替换文件名的md5
值:
http://tp3/Application/Runtime/Temp/ae0e4bdad7b5f67141743366026d2ea5.php
漏洞的防范
防范的办法,还是从根源上入手。优先推荐升级到最新版的thinkphp
,当然这个工作量可能比较大。如果抗拒的话,那么可以使用现有的thinkphp@3
代码,做一些必要的防范措施。
框架移出根目录
这个比较好理解,把thinkphp
及Application
目录上移动一层。然后修改原有的index.php
的框架位置定义即可。
index.php
:
define('APP_PATH','./../Application/');
require './../ThinkPHP/ThinkPHP.php';
修改默认应用名称
治标不治本的方案,但是也可以值得试试。修改index.php
即可:
define('APP_PATH','./ApplicationRename/');
设置nginx
规则
Application
下的所有文件,是不是都不应该允许用户直接访问到呢?
location ~ ^/Application/ {
deny all;
}
相关链接
总结
这个漏洞的产生,还是需要有点前提条件的。所以,也并不能说是必现的漏洞。而且,破局的关键点:缓存的名字,这个也是需要您来猜测得到的。所以说,这个经典漏洞客观是存在的,但是能不能找到,那就可能取决于机缘巧合了。
更多thinkphp
的相关文字,请点击苏南大叔的博客:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
这种漏洞错误应该不多吧