前言
今天,我们将深入探讨上传文件漏洞攻击,这部分内容是EdgeOne专项实践篇的一部分。在本章中,我们不会涉及文件漏洞的含义、原理或站点配置等基础教程,如果你对这些内容感兴趣,可以参考这篇文章:探索网络安全:浅析文件上传漏洞 - 掘金 (juejin.cn)
在本段之后将不再详述如何购买套餐或配置站点等基础应用。而当我们讲解完攻击之后,我还会分享一些防范措施,以保护您的服务器免受攻击。因此,本文的焦点依然集中在腾讯云的EdgeOne上。
靶场搭建
当我们考虑到攻击他人服务器属于违法行为时,我们需要思考如何更好地保护我们自己的服务器。为了测试和学习,我们可以搭建一个专门的靶场来模拟文件上传漏洞攻击。以下是我搭建靶场的环境和一些参考资料,供大家学习和参考,也可以自行探索相关内容。
使用腾讯云轻量应用服务器的Linux版本时,考虑到环境要求较为严格,自行搭建可能存在诸多错误。可以简单地通过拉取他人封装好的docker镜像来快速部署。
docker pull c0ny1/upload-labs
docker run -d -p 8289:80 c0ny1/upload-labs
在启动之后,请务必前往腾讯云控制台进行防火墙规则的配置,否则可能无法正常访问。你可以使用自己配置的IP地址和端口号替换访问地址:http://ip:8289。
系统可以正常启动。然而,当尝试上传文件时,系统会提示找不到所需的upload目录。为了解决这个问题,需要通过docker容器控制台手动新增一个upload目录。
进去之后执行下命令:
mkdir upload
chmod 777 upload
当下一切运行正常,靶场已成功搭建!请牢记,在学习完成后,请勿攻击他人的服务器。这一点至关重要,切记、切记、切记。
文件上传漏洞
靶场共设有20个关卡,每一个关卡都代表一个不同的漏洞案例。在这里,我将选择几个典型的案例与大家分享和学习。那么,我们现在就开始吧!
upload-labs靶场攻略
为了避免长篇文本对大家造成干扰,我已经准备了一张简明的流程图,帮助大家快速理解。请大家先看一下这张图,相信你们会觉得一切都变得非常简单。现在我们准备出发了,请系好安全带。
接下来,我们的所有任务都依赖于上传一个或多个文件来访问服务器配置信息。攻击脚本的设计也极其简单,其目标同样明确:只需通过其他途径访问我们的攻击脚本并成功执行即可。
php
<?php
phpinfo();
?>
当我们谈论获取信息的用处时,是否可以用于攻击?实际上,我们的主要目的是执行脚本。对于脚本的内容并不重要,关键是能够顺利执行。你可以随意替换脚本的语句,例如像蚁剑的一句话脚本来获取shell。这里只是为了演示攻击的目的而已。
下面我们开始讲解一下如何使用靶场,请注意每个页面都配备了查看源码和查看提示的功能。如果查看源码后仍不清楚如何进行攻击,可以根据提示逐步闯关。那么,让我们开始吧。
前端页面校验漏洞
我们先看下源码:
当我们审视这段代码时,可以注意到,这里仅仅是在前端进行了一个基本的后缀校验。
那么,我们可以选择在不依赖于工具的情况下,通过修改前端代码以移除这一验证步骤来实现上传,或者手动修改请求以将文件后缀改为.php的方式来进行。我们可以先从简单的方法开始。
接下来,进行删除操作并保存文件,随后再次上传我们的脚本文件。
请保存更改后,确保刷新页面,以便接口能够识别我们上传的以.php结尾的文件。
由于这并非一张图片,因此它无法显示。因此,请右键复制图片路径以查看。操作已成功执行。
后端校验文件类型漏洞
当然,即使是最差劲的公司也不能仅仅依赖前端进行校验,因此第二个阶段就开始涉及后端操作。现在我们继续查看源代码;
后端的主要功能是获取上传文件的类型。要修改文件类型,我们需要使用Burp Suite工具进行拦截。仅仅改变文件后缀是不够的,因为这里传输的文件类型是通过Content-Type标头传递的,具体来说是application/octet-stream
。
当系统后台基于文件类型进行判断时,我们只需调整文件类型以符合后台校验的要求,具体如下所示:
不出所料,我们依然会发现上传成功的情况。
剩下的步骤是右键点击打开图像文件的地址。在接下来的关卡中,我们不再需要演示查看PHP信息,只需通过验证即可确保我们的代码成功运行。
老版本文件后缀
这一关,如果发现无论如何都无法有效进行校验,那么最好的做法是直接限制可上传文件的后缀名。然而,单纯依赖文件后缀名来进行限制也存在潜在的安全隐患。让我们深入分析一下这个问题。
在早期的Web开发阶段,PHP文件常以.php3结尾。这是因为旧版PHP仅支持.php3后缀,而不直接支持.php。尽管现代PHP版本不再强制要求特定的文件后缀,仍有一些网站因为历史或兼容性原因仍在使用.php3后缀。为了支持这些老版本网站,Apache默认配置支持解析.php3后缀的PHP文件。
现在问题就变得非常简单了,我们只需上传那些不在后缀限制数组中的文件,然后一切搞定。
利用Apache配置文件
当谈到上述情况时,一些人可能已经认识到,不再可以随意使用简单的文件后缀名。我需要全面审查并加强这方面的限制,这样我们就进入了第四阶段。现在让我们来仔细查看源代码。
当然,我们不必局限于上传 PHP 文件。这次,我们可以利用另一个配置文件的漏洞进行攻击。
.htaccess
是一个用于配置 Apache Web 服务器的配置文件,其名称是 "hypertext access" 的缩写。它允许网站管理员在没有修改主配置文件(如 httpd.conf
)的情况下,通过在网站根目录或特定目录下创建 .htaccess
文件来进行配置和控制网站的行为。
.htaccess
文件可以包含各种指令和规则,用于控制网站的访问权限、重定向 URL、设置自定义错误页面、启用压缩、禁止目录列表、限制访问速率等等。通过 .htaccess
文件,网站管理员可以在不需要服务器级别访问的情况下,实现对网站的灵活配置和管理。
需要注意的是,.htaccess
文件只对 Apache Web 服务器有效,而且其配置可能会影响网站的性能,特别是如果包含复杂的规则或需要频繁读取文件时。
那我们先写脚本后传文件。
php
<FilesMatch "loudong.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
这句话的意思就是当访问到名为 loudong.jpg 的文件时,Apache Web 服务器会将其当作 PHP 脚本来处理,而不是简单地作为静态文件直接返回给用户。
继续上传jpg图片,尽管这个文件实际上是一个伪装成图片的攻击脚本。
大小写漏洞
当人员发现漏洞后,简单地添加一个限制即可解决问题。因此,第五关的解决方案是直接禁止上传.htaccess文件。
当然,他未能察觉到另一个问题。再次查看源代码。
文件名都是小写的,但是我们需要确认一下,PHP是否支持大写文件名。我们可以试一试直接拦截请求并修改文件名来测试。
空格漏洞
在检测大小写后,经过详细查阅源代码后发现,没有对空格进行限制。如果确实没有空格限制,那么文件后缀的限制也将失效。
我们使用Burp Suite拦截请求进行发送。我在文件名后面自行添加了一个空格,因为默认情况下并没有文件名。
最终成功上传文件。关于绕过文件后缀检查的方法还有很多,我们不打算逐一列举。问题主要在于解析代码时的不严谨,通过利用其中的某个漏洞直接上传我们的脚本文件即可。
文件包含漏洞
当这张图片不再只是简单的视觉元素时,它前面看起来可能十分寻常,然而实际上它的后半部分包含了一段代码。
这一关的源码看下
当我们只读取前两个字节时,通常是为了获取图片文件的文件头信息,这些信息包含了关于文件类型和格式的重要数据。接下来,我们可以打开这三个图片文件,使用记事本编辑,来探索它们是否有共同的特征或属性。
这一部分还有另一个需要注意的地方,那就是文件包含漏洞。你知道文件包含漏洞指的是什么吗?
php
<?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
include $file;
}else{
show_source(__file__);
}
?>
由于直接使用 include 函数并且未对 $file 参数进行充分的过滤或验证,攻击者可以构造恶意请求,包含任意文件,甚至是远程的恶意文件。那么我们上传文件后,将文件地址拿到,然后通过这个文件包含漏洞试一下,结果显示确实存在此风险。
二次渲染绕过
这一关源代码很多,因此我决定仅复制并分享关键代码,供大家参考。
php
//使用上传的图片生成新的图片
$im = imagecreatefromjpeg($target_path);
//使用上传的图片生成新的图片
$im = imagecreatefrompng($target_path);
//使用上传的图片生成新的图片
$im = imagecreatefromgif($target_path);
这一步骤的主要目的是确定用户上传的图片格式,并重新生成新的图片。在这个过程中需要特别关注 GIF 图片的处理。GIF 图片在重新渲染后改动很小,主要原因是其压缩算法的优化和格式的固定限制,使得大部分修改只影响到少量的数据部分,而不会对整个图像文件造成大幅度的变化。
我们需要对流程进行改进:首先,请确保不随意修改图片文件,而是先上传并下载图片,再与本地图片进行对比。识别未变化的部分,然后逐一复制粘贴代码,如有错误则调整位置。
最后我们在这里改下:
上传后继续使用文件包含漏洞:
条件并发竞争
在这个阶段,仅仅是将上传的文件保存下来,然后进行校验、重命名并移动文件。如果校验失败,则会将文件删除。表面看起来似乎没有问题,但实际上存在许多潜在的漏洞。
首先,未进行文件类型验证便进行了保存操作,随后才进行验证并删除。这个漏洞为我们提供了攻击服务器的入口。我们可以利用Burp Suite拦截请求并发起集中攻击。只要在删除操作执行之前,我就能够访问到我上传的文件,便能执行脚本。现在开始行动。
当我们成功拦截了请求后,接下来的步骤是配置并发请求的开发工作。我们计划从默认的10个并发开始进行攻击。
观察这里的攻击效果,尽管它们通常会被及时清除,但只要我们成功访问其中一个,攻击就可以算是成功的。让我们开始吧。
讲解完了如何利用文件上传攻击服务器后,接下来的重点在于理解如何有效防御这些攻击。在服务器端实施良好的防护措施至关重要,因为防守胜过进攻。接下来,我们将根据上述经典案例来探讨如何加强服务器的安全防护。
EdgeOne防护措施
假设我们无法对程序员编写的代码进行检查,或者我们本身没有进行代码审计的能力,那么我们只能依赖外部保护措施。在这种情况下,今天仍然建议采用EdgeOne来解决这些问题。为了让大家更清楚地理解,我也简单绘制了一张图作为参考,看完图后问题就变得非常简单了,就像在架构中使用一个可插拔的中间件一样轻松应用即可。
文件漏洞防护手段
在前面我们详细讨论了多种攻击方法,现在让我们综述一下应该从哪些方面进行防护:
- 未限制文件类型:允许上传任何类型的文件,包括可执行文件。
- 未进行文件内容检查:未检查文件内容是否包含恶意代码。
- 未限制文件上传频率:刚才我们演示的时候,可以看到通过频繁上传文件达到条件竞争的状态。
除了前面提到的措施外,还有一个需要注意的地方,即文件大小的限制。考虑到我们拥有的是自己的服务器资源,我们可以避免不必要的流量消耗。因此,我们也需要在这方面进行适当的控制。
接下来,我们将逐一实施这些防护措施,你将会看到,通过最小的调整,我们能够达到最佳的安全效果。
文件敏感后缀检查
如果你打算上传Webshell,文件内容必定包含脚本内容。因此,我们需要确认EdgeOne是否提供相关的检查和校验功能。一旦你购买了EdgeOne的标准版,无需进行任何修改,即可立即上传文件并检查其是否能够有效拦截。
在一般情况下,EdgeOne应该会拦截这类请求,但我们需要再次查看样本日志,确认是否确实有请求未被拦截。
当我们注意到这一点时,我们发现请求不仅被捕获,还被识别为防护规则,但实际上处于观察状态而非直接拦截状态。这一点很重要,因为默认情况下,EdgeOne仅观察并不会直接拦截请求。我们需要进一步查看这个规则的ID,了解其具体功能。
首先进到自己配置的站点后,找到安全防护->web防护->托管规则->筛选规则id
这个问题相当繁琐,因为在样本日志中,当前规则id的具体限制并不直接显示出来,需要我们自己去查找。不过,最终我们确实可以找到这些信息。通过这种方式,我们可以识别文件后缀,这样一来,前端和后端在处理文件后缀时就无需编写大量的限制代码了。
事实上,前几个案例中的文件上传漏洞主要都是由于文件后缀问题导致的。EdgeOne技术能够通过一种简单的方法解决程序员代码不严谨的问题。
当涉及到相关的防护请求时,请记住关闭全局观察模式,这样可以让您单独配置每个规则的拦截方式。因此,现在我们将全局观察模式关闭。
那么让我们再次发起请求,以确认是否能够有效拦截这些请求。
难道我们表演翻车了吗?怎么还是观察模式,我本以为我们应该处于拦截请求的状态,而不是仅仅处于观察模式。这涉及到一个防护等级的问题,我们需要检视一下,默认设置可能偏向宽松了一些。
那么我们需要调整防护等级,以确保它能够拦截那些不应该直接访问后台的请求。然而,请注意,我们不能单独设置一个规则,如果需要进行设置,也必须按照父类规则的方式进行设置。让我们仔细查看一下:
当然!那么我们现在可以尝试上传一个文件,以便查看结果如何。
在实际应用中效果非常显著。不再演示剩余的各种奇葩敏感后缀,因为最终的拦截结果都是一致的。对于企业或个人而言,只需简单操作两次按钮开关,使用体验也非常出色。
伪文件代码注入检查
当我们试图规避后缀检查时,我们制作了一个文件,其后缀名为.jpg,但实际上是一个伪装的图片文件。让我们首先验证一下这个简单的伪装文件是否有效。
当文件内容实际上是PHP脚本时,尽管我们的文件后缀被设置为.jpg并不属于敏感后缀文件,因此可能可以规避EdgeOne的后缀规则检查。因此,我们可以尝试上传并查看是否能够成功执行。
尝试并未取得成功。那么我们来看看他被那个安全防护规则拦截住了。
当我们成功绕过了敏感后缀的防护检查,那么现在需要进一步分析的是,这是哪一个具体的规则被规避了。
这防护措施真的蛮不错,php脚本已经被拦截了。
那么,当我们测试更高级的伪装文件时,比如在一个看似正常的图片文件中嵌入代码脚本,防护规则是否能够检测到它们呢?在我们探讨绕过图片二次渲染的方法时,我们进行了实验,测试了在 GIF 文件中注入 PHP 代码的情况,具体如下图所示:
当然,我们可以看看是否有办法绕过这个防护措施呢?不过看来防护措施还是能够有效阻止的。
看看这些样本日志,因为它们都属于同一个防护规则ID,我们就不再重复查看了,而是继续探索其他测试手段。
除了上述代码注入来防止图片渲染外,如果没有进行二次渲染,另一种方法是直接在图片末尾添加内容。这种操作简单,接下来我们看看它是否能提供额外的防护效果。
演示虽然出了点问题,但没关系。如果防护不住,也不要紧,我们还可以联系腾讯客服,赶紧反馈情况。我会把所有的测试文件和网站链接都交给他们,让他们测试一下,找出问题所在。
经过长时间的深入沟通和分析,我们最终成功帮助他们发现了一个问题,剩下的就交给他们自行解决了。
这里为什么没有演示条件竞争防护呢?难道不应该增加一个上传频率规则吗?我不确定大家是否还记得,条件竞争攻击是通过上传一个PHP脚本,然后在检验通过的短暂时间窗口内发动攻击的。首先,PHP脚本必须成功上传,但EdgeOne已经拦截了这种脚本,这样怎么能有效地实施后续的上传速率限制呢?
文件上传速率限制
之前我们讨论过避免演示条件竞争攻击,但现在为什么又有上传速率限制呢?这个限制是为了防止频繁的文件上传导致服务器网络IO异常拥堵。这其实涉及到两个问题:一方面,我们不是在谈论通过脚本攻击服务器,而是用户可能通过频繁上传文件来占用服务器资源。只要上传足够频繁,就有可能使服务器无法响应其他用户的访问,进而导致网站宕机的情况发生。这种情况非常严重,影响可能相当恶劣。
话不多说,让我们来进行演示并设置一些限制。由于上传脚本文件会被拦截,因此我们将上传一个正常的图片来进行演示。同时,我们将使用Burp Suite来频繁测试文件上传攻击服务器,具体如图所示:
然后,我们直接发起并发请求。我们计划按照以下几个测试并发规则进行测试:每秒5、10、15、30和100次。首先,我们会使用10次每秒的并发量进行测试,然后再尝试100次每秒的并发量。
我们多次发送请求后,请查看一下服务器资源的情况。
这里服务器的流量封装上涨,尽管网站仍可正常访问,但我们的目的已经实现,大量消耗了网站的流量。
可以查看EdgeOne的统计分析,这次不仅限于Web安全分析,而是重点在指标分析上。我们可以观察到异常流量大量请求服务器,面对这种情况,我们应该采取哪些措施?
可以再看下面的请求分析。如图:
首先,通过分析该图,我们可以确定请求的IP地址及其对哪些URL进行了频繁请求,这些信息将为我们制定有效策略提供基础。
尽管这种方法并不是最优选择,但我们可以将客户的IP地址加入黑名单,以限制其访问我们的网站。这种方法虽然笨拙,因为客户IP可能会变动,导致我们需要不断更新配置,但至少是一种可行的措施。
然后,我们接下来要做的是将IP地址添加到黑名单中,这样可以简单地增加安全防护措施。当然,你可以根据个人需求添加IP地址段。在这个示例中,我仅添加了一个IP地址作为演示。
好的,保存完毕。接下来,我们试试发送请求,看看是否已经被成功拦截。
当所有请求都被成功拦截后,我们可以再次查看一下样本日志。
没错,这个规则ID就是刚刚由我们生成的唯一标识符。
当考虑到这一情况时,第二种方法即为限制请求的频率。
这里的限制过于宽松,我们需要收紧一些。一个人不可能请求得这么快。
当我们继续发送并发请求进行测试时,可以观察到EdgeOne已经能够识别到后续请求,并且使用了JavaScript挑战脚本,而非直接由服务器响应。
当我们检视样本日志时,同样可以观察到这一情况。
这是一个简单的全局限制。当然,某些企业用户的网站可能要求允许客户进行大量点击,这就需要考虑了。但不用着急,我们可以精确控制这个过程。接下来我们来讨论如何设置针对特定URL的请求限制。我们根据指标分析异常请求的地方,来设定相应的控制策略。你可以根据个人需求自行设置限制。
我在这里设置了所有涉及文件上传路径的限制。我们需要再确认一下是否已经完全拦截了所有这些路径。例如,/Pass-10/index.php
。
看起来确实成功阻止了潜在的攻击。至于上传速率的问题,我们就到这里讨论吧。
文件大小限制
速度有限制,不能让客户上传过大的文件。我们只需上传图片,并非视频,所以设定个上限是合理的,比如不超过2M,这个范围应该适应大多数需求。现在我们来具体操作一下。需要注意的是,这个操作不是在Web防护层进行,而是在站点加速层进行的设置。
为了更好地进行演示,我不会使用全局配置,而是采用差异化配置的方式。这意味着我们会根据业务需求单独配置特定路径下的文件上传,具体如图所示。
当我们试着上传一个非常大的文件,以便测试上传过程。
结果是网站被拦截了,这让我感觉好像我的网站无法访问一样。看起来我需要设置一下自定义响应页面,以免让访问者误以为网站不稳定。
我们需要在这里进行响应页面的设置,内容十分简洁明了,完全遵循官方网站提供的示例进行展示。
上述页面已创建,但尚未与413状态码绑定。接下来,我们将进一步完善刚才提到的规则。请参考下图:
当我们再次审视其效果时,可以使其看起来更加稳定,这里可以稍微美化一些,确保在满足自己需求的同时,外观也可以更为优美,具体如下图所示。
截至目前,针对文件上传的所有潜在漏洞攻击已经得到有效防范,但是道路漫漫,修行需持之以恒,少年仍需不懈努力。
总结
通过本文,我们深入探讨了文件上传漏洞攻击的多种案例和防范措施,以及在搭建攻击靶场时的实际操作。从前端和后端的校验漏洞,到利用Apache配置文件和文件包含漏洞的攻击方式,每一步都展示了安全防护的重要性。
在学习和实践过程中,我们不仅仅关注如何进行攻击,更着重于如何保护自己的服务器免受此类攻击。我们使用了EdgeOne作为一个解决方案的示例,展示了如何利用其提供的防护规则来有效防御文件上传漏洞。
无论是在靶场搭建过程中的细节操作,还是在攻击案例的分析过程中,安全意识和防护措施的实施都显得至关重要。通过本文,希望读者能够更深入地理解和应用这些安全原则,以保护自己的网络和服务器免受攻击的威胁。
在网络安全的道路上,学习永无止境。让我们共同努力,不断提升技能,保障网络环境的安全与稳定。
我是努力的小雨,一名 Java 服务端码农,潜心研究着 AI 技术的奥秘。我热爱技术交流与分享,对开源社区充满热情。身兼掘金优秀作者、腾讯云内容共创官、阿里云专家博主、华为云云享专家等多重身份。
💡 我将不吝分享我在技术道路上的个人探索与经验,希望能为你的学习与成长带来一些启发与帮助。
🌟 欢迎关注努力的小雨!🌟