冬令营模块二
1、请大家写一个文件上传的表单,用于向服务端上传文件,并用php作为后端,抓包分析这个请求体的结构是什么样的呢?
文件上传表单
1 |
|
后端 PHP 文件处理
1 |
|
运行和测试
把index.html和upload.php挪到C:\Users\Administrator里
在本地 PHP 服务器运行(我什么时候在本地配置了php环境?👀🤔)
在终端运行:
1 | sh |
然后访问 http://localhost:8080/index.html
,选择文件并上传。
抓包
1 | POST /upload.php HTTP/1.1 |
Content-Type: multipart/form-data; boundary=—-WebKitFormBoundary8tQQDPkwKM6Th9n4
说明请求是
multipart/form-data
,用于传输文件。boundary
标识不同部分的分隔符。
WebKitFormBoundary8tQQDPkwKM6Th9n4 Content-Disposition: form-data; name="file"; filename="鏂板缓鏂囨湰鏂囨。.txt" Content-Type: text/plain
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- **boundary**:每个部分用 `----WebKitFormBoundary8tQQDPkwKM6Th9n4` 分隔,这个分隔符用于区分不同部分的数据。
- **Content-Disposition**:指示文件数据的位置和属性。这里,`name="file"` 表示上传文件的表单字段名,`filename="鏂板缓鏂囨湰鏂囨。.txt"` 表示上传的文件名。(原本写的新建文本文档的,但是编码好像有问题🤔🤔)
- **Content-Type**:上传的文件类型(`text/plain`,表示文本文件)。
- 文件内容:`iRkN31+X_<Me`,这是上传的文件内容。
## 2、怎样去指定上传目录(如/tmp),在这种情况下你有什么招能让木马文件落地在web目录(假设为/var/www/html)呢?
### 指定上传目录
可以通过 **`move_uploaded_file()`** 来指定文件的上传路径
例如,上传文件到 `/tmp/` 目录:
```php
$uploadDir = "/tmp/"; // 指定上传目录
$uploadFile = $uploadDir . basename($_FILES["file"]["name"]);
move_uploaded_file($_FILES["file"]["tmp_name"], $uploadFile);
让木马文件落地在web目录
- 指定上传到 Web 根目录
你可以通过 PHP 代码直接指定 Web 目录(例如 /var/www/html
)为上传目标:
1 | $uploadDir = "/var/www/html/"; // Web 根目录 |
这会把上传的文件直接存储在 Web 根目录下。
- 上传可执行文件
在没有文件类型检查的情况下,恶意用户可以上传 PHP 木马文件,比如 **evil.php
**。这个文件可能包含可执行代码,并且会被 Web 服务器执行:
1 |
|
- 修改文件名
如果 Web 服务器允许上传的文件名,攻击者可以将木马文件命名为 .php
文件,或者上传一个带有 PHP 代码的文件,并通过浏览器访问该文件来执行木马:
1 | <form action="/upload.php" method="post" enctype="multipart/form-data"> |
- 文件执行
如果木马文件上传到了 /var/www/html/
目录,攻击者可以通过访问该文件来执行它,比如 http://localhost/evil.php
,该 PHP 文件就会被执行。
3、学一下php的eval()函数的用法,并写点什么好玩的~,如何在php中执行系统命令呢?比如ls
eval()
函数的基本用法
1 |
|
输出:
1 | Hello, world! |
解释:
eval()
函数将字符串$code
当作 PHP 代码执行,结果就是输出"Hello, world!"
。
eval()
函数执行动态代码
你可以根据条件动态生成代码并执行
在PHP中执行系统命令
PHP 中执行系统命令一般使用以下函数:
shell_exec()
exec()
system()
passthru()
在 PHP 中执行系统命令(例如 ls
),可以使用 shell_exec()
函数。例如,在 Linux 系统上运行 ls
命令来列出目录内容:
1 |
|
4、在上传文件又要传递一个POST参数,此时请求包的参数是什么样的?
Content-Type:请求的 Content-Type
会是 multipart/form-data
,并且会包含一个 boundary
字段,用来分隔请求的不同部分(即文件和普通字段)。
文件字段:文件的内容会通过该字段传输,通常包含文件的二进制数据。
普通字段:除文件外的其他字段数据以普通的表单字段形式传输。
以上面的请求包为例
1 | POST /upload.php HTTP/1.1 |
5、你能在js的层面限制只能上传图片吗?
可以在 JavaScript 层面通过文件输入(<input type="file">
)来限制用户只能上传图片。通过设置 accept
属性,可以指定允许上传的文件类型。对于图片文件,可以设置 accept
为 image/*
,这会限制用户只能选择图片文件。
示例:
1 | <form> |
6、请你利用请求包中Content-Type头检测文件的是否是图片
可以通过读取文件的 Content-Type
(即 MIME 类型)来检测文件是否为图片。通过 file.type
属性可以获取文件的 MIME 类型。
示例
1 | <form> |
使用
file.type
获取文件的 MIME 类型。如果用户选择的是图片,MIME 类型会以image/
开头(例如:image/jpeg
,image/png
等)。startsWith('image/')
用来检查文件的 MIME 类型是否属于图片类型。如果文件不是图片,阻止表单提交并显示一个警告信息。
7、常见的图片类型(jpg,png,gif)的文件头有什么特征?试着在你的防护中加入对应的检测
常见图片类型的文件头特征:
- JPG(JPEG):
- 文件头:
FF D8 FF
(16进制表示) - 文件尾:
FF D9
- 文件头:
- PNG:
- 文件头:
89 50 4E 47 0D 0A 1A 0A
(16进制表示)
- 文件头:
- GIF:
- 文件头:
47 49 46 38
(16进制表示) - 文件尾:
00 3B
(终止符)
- 文件头:
在 JavaScript 中检测文件类型
可以通过 FileReader
API 读取文件的二进制内容,并检查文件头是否符合图片的文件格式特征。
完整示例
1 | <form> |
**
FileReader.readAsArrayBuffer()
**:读取文件的前几个字节,并将其转为ArrayBuffer
,然后我们可以检查这些字节是否符合图片文件的特征。**
isValidImage()
**:此函数检查文件的前几个字节,判断其是否符合 JPG、PNG 或 GIF 的文件头。如果文件头符合其中一个类型,则返回true
,表示文件是有效的图片。**
file.slice(0, 8)
**:我们只读取文件的前 8 个字节,因为 JPG、PNG、GIF 的文件头通常位于文件的开头。
8、请你写一个能够过滤.php后缀的waf
在 HTML 表单提交前检查文件名
1 | <form id="uploadForm"> |
9、请你使用file_put_content()来实现一次文件上传到指定目录
file_put_contents()
是一个 PHP 函数,用于将数据写入文件。
使用 file_put_contents()
实现文件上传到指定目录
1 |
|
10、文件上传除了导致php代码执行,还可能导致什么漏洞?
文件覆盖漏洞
- 描述:攻击者可以上传一个与服务器上已有文件同名的文件,进而覆盖原有的文件内容。这可能导致应用程序出错、敏感数据丢失或其他恶意操作。
恶意文件注入漏洞
- 描述:攻击者可能上传包含恶意脚本的文件(如
.jpg
文件中的嵌入式恶意脚本),这些文件可能在用户访问时被触发。即使文件扩展名为图片,也可以通过隐藏的内容执行恶意代码。
路径遍历漏洞
- 描述:攻击者可以利用路径遍历技术上传恶意文件到不应该存储的位置,可能会覆盖关键文件或者泄露敏感信息。例如,上传文件时,恶意文件名可能包含如
../../../../../etc/passwd
的路径,从而覆盖敏感的系统文件。
文件大小漏洞
- 描述:没有对文件大小进行严格限制,攻击者可能上传非常大的文件,导致 拒绝服务攻击(DoS),占用大量存储空间或内存。
跨站脚本(XSS)漏洞
- 描述:攻击者上传含有恶意 JavaScript 脚本的文件(如
.html
、.svg
或.js
文件),并通过特定的路径直接访问这些文件。恶意脚本可能会在用户浏览时被执行,导致 XSS 攻击。
11、为后续做个铺垫,请你想办法捕捉到文件上传瞬间临时目录(Linux下是/tmp)下的文件变化(动作要快,姿势要帅,临时文件消失快)
使用 inotify
(Linux)进行文件监控
inotify
是 Linux 系统中的一种强大的文件系统事件监控工具,可以用来监控文件或目录的变化。你可以通过 Python 或 Bash 脚本来实现文件监控,在文件被创建或修改时立即捕获事件。
使用 inotifywait
(命令行工具)
inotifywait
是 inotify-tools
包中的命令行工具,用于监听目录中的文件创建、修改、删除等事件。
首先,你需要安装 inotify-tools
:
1 | sudo apt-get install inotify-tools |
然后,可以使用 inotifywait
来监听 /tmp
目录中的文件变化:
1 | inotifywait -m /tmp -e create -e modify -e delete |
-m
表示持续监控(不退出)。-e
用来指定监听的事件类型,这里我们监听create
(文件创建)、modify
(文件修改)、delete
(文件删除)事件。
- 本文作者: 林姜
- 本文链接: http://example.com/2025/02/15/冬令营模块二/