问题的发现

是在对文件上传漏洞的ctf题目中偶然发现的。

在尝试把含有一句话木马的php文件绕过过滤的时候,试了试先转成压缩包,之后,再改文件名为.txt

结果上传后,通过网址访问时,就自动下载了下来。

用记事本打开操作后的“.txt”文件,和正常的是不同了

图1

图2

访问图1

访问图2

这就不得不思考浏览器下载文件的机制了

浏览器下载文件的机制

//浏览器的构成??

  • HTML文件定义了页面的结构,CSS文件定义了页面的样式,JavaScript文件定义了页面的行为。浏览器会将这些文件解析后,渲染出用户看到的页面。

  • 静态内容:如果服务器返回的是预先写好的HTML、CSS和JavaScript文件,那么这些内容是静态的。用户每次访问时看到的内容都是相同的。

  • 动态内容:如果服务器根据用户的请求动态生成HTML、CSS和JavaScript文件,那么这些内容是动态的。

浏览器的文件

可通过<a>标签来

能解析和渲染的文件

  • HTML文件
  • CSS文件
  • JavaScript文件
  • 图片文件
  • 字体文件
  • 视频文件
  • 音频文件
  • JSON文件
  • XML文件
  • SVG文件
  • Web字体文件

不能解析和渲染的文件

自动下载:.

可执行文件:exe、.dll、.bat

压缩文件:.zip、.rar、.tar

一些文档文件:.doc、.docx、.xls、.xlsx、.ppt、.pptx

二进制文件:.bin、.dat

也有一些是“提示用户选择操作”—-(eg:一些浏览器(如Chrome)可以内置解析PDF文件)

和通过安装的插件或扩展来打开的

浏览器识别链接是下载文件还是展示的方法

浏览器主要通过 MIME 类型(即 Content-Type 响应头)来识别文件类型——最核心的依据

补充机制:若 Content-Type 缺失或错误,会进行内容嗅探

[!NOTE]

内容嗅探:会分析文件内容的魔术数字(Magic Bytes)推测类型。

安全风险

  • 跨站脚本攻击(XSS):攻击者可以通过混淆MIME嗅探算法,使浏览器错误地解析响应内容,从而执行恶意脚本。
  • 恶意文件执行:如果浏览器错误地将可执行文件识别为普通文件,可能会导致恶意代码的执行

防范措施

  • 设置X-Content-Type-Options头部:在服务器的响应中设置X-Content-Type-Options: nosniff,告诉浏览器不要对响应内容进行MIME类型嗅探,必须严格按照服务器返回的Content-Type头处理内容。
  • **正确配置Content-Type**:服务器应确保在响应中正确设置Content-Type头部,以避免浏览器进行不必要的MIME嗅探

浏览器下载行为

标签

window.open()

Javascript调用DOM对象实现文件下载

Javascript模拟<a>标签

。。。未完待续

实验网址:

文件下载 | have a good time!

[!IMPORTANT]

对于想下载的,而一般是渲染的:
1、可以通过HTML标签控制 标签的download属性

1
<a href="example.svg" download="example.svg">下载SVG</a>

但跨域文件可能无效——对于跨域的文件用fetch和Blob对象

2、服务器设置:

在服务器端设置响应头Content-Dispositionattachment,并指定文件名,可以强制浏览器下载文件。

(思考:要用iframe来加载文件吗)

1
2
Content-Disposition: attachment; 
filename="example.xml"

3、JavaScript方法:

通过JavaScript创建一个动态链接并触发点击事件来下载文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function forceDownload(url, filename) {
// 创建一个 <a> 元素
const link = document.createElement("a");

// 设置 href 属性指向文件的 URL
link.href = url;

// 设置 download 属性指定下载时的文件名
link.download = filename || "download"; // 如果没有提供文件名,默认为 "download"

// 将 <a> 元素附加到文档中
document.body.appendChild(link);

// 触发点击事件
link.click();

// 下载完成后移除临时 <a> 元素
document.body.removeChild(link);
}


setTimeout(function() {
document.body.removeChild(link);
}, 50);
}

JS

用phpstudy_pro来测试实例

内嵌JS

是指在 HTML 文件的<head><body> 标签 中 , 可以使用 <script> 标签来包含 JavaScript 代码 , 这种书写方式称为 内嵌 JavaScript ;而不是通过<script>标签的src属性引入外部的.js文件。——适合比较简单的javascript代码。

内联JS

将JavaScript代码直接写在HTML元素的属性中,而不是单独写在<script>标签中。

内联JS代码是通过HTML元素的事件属性来绑定JavaScript代码的。常见的事件属性包括onclickonmouseoveronchange等。

注意单双引号的使用:属性值 写在 双引号 中 , 如果在 双引号中 写一行 JavaScrip 脚本 , 涉及到 字符串内容时 , 使用 单引号 ;

1
2
<input type="button" value="按钮" onclick="alert('内联')">

得到:

外部JS

写在.js文件中,通过<script>标签的src属性引用(script标签要空着)

1
<script src="test.js"></script>

得到

对于script标签内是否要写内容有:

<script>标签使用了 src 属性,那么它的内部内容通常会被浏览器忽略

仍然是js文件的内容

如何通过内嵌JS来实现自动下载

(具体强制下载svg、xml等文件自动下载实际操作,未完待续。。。)