一般情况下,数组元素的索引是从 0 开始的。因此,数组中的第一个元素的索引是 0,第二个元素的索引是 1,依此类推。
举个例子,如果有一个包含三个元素的数组,它们的索引分别是 0、1 和 2,而不是 1、2 和 3。
f
i
l
e
[
c
o
u
n
t
(
file[count(
file[count(file) - 1] 表示使用最后一个元素的索引来获取数组 $file 中的最后一个元素的值。
‘.’ 是一个字符串,代表一个点号,用于连接文件名和文件扩展名。
将上面两步中得到的值拼接在一起,形成完整的文件名。
最终将完整的文件名赋值给变量 $filename。
例如,假设
f
i
l
e
是一个包含
[
′
f
i
l
e
′
,
′
t
x
t
′
]
的数组,那么该行代码的执行过程如下:
r
e
s
e
t
(
file 是一个包含 ['file', 'txt'] 的数组,那么该行代码的执行过程如下: reset(
file是一个包含[′file′,′txt′]的数组,那么该行代码的执行过程如下:reset(file) 返回 ‘file’。
count($file) - 1 返回 1。
f
i
l
e
[
c
o
u
n
t
(
file[count(
file[count(file) - 1] 返回 ‘txt’。
‘.’ 表示点号。
将 ‘file’、. 和 ‘txt’ 拼接在一起,得到最终的文件名 ‘file.txt’。
将文件名赋值给变量 $filename,即 $filename = ‘file.txt’。
因此,最终 $filename 的值将是 ‘file.txt’。
*/
/*
最后,如果通过了上述检查,就将上传的文件移动到之前创建的目录
s
a
n
d
b
o
x
中,并输出成功或失败的信息。
∗
/
i
f
(
m
o
v
e
u
p
l
o
a
d
e
d
f
i
l
e
(
sandbox 中,并输出成功或失败的信息。 */ if (move_uploaded_file(
sandbox中,并输出成功或失败的信息。∗/if(moveuploadedfile(_FILES[‘file’][‘tmp_name’], $sandbox . ‘/’ . $filename)) {
echo ‘Success!’;
echo ‘filepath:’ .
s
a
n
d
b
o
x
.
′
/
′
.
sandbox . '/' .
sandbox.′/′.filename;
} else {
echo ‘Failed!’;
}
/*
move_uploaded_file() 函数是 PHP 中用于将上传的文件移动到新位置的函数。
格式:
move_uploaded_file(string $filename, string $destination): bool
参数:
$filename:表示上传文件的临时路径,通常可以通过 $_FILES[‘file’][‘tmp_name’] 来获取。
$destination:表示文件移动后的目标路径,包括目录和文件名。
返回值:
如果文件成功移动到指定位置,则返回 true。
如果移动失败,则返回 false。
整个代码块的作用是:尝试将用户上传的文件移动到指定目录,并根据移动操作的结果输出相应的提示信息,告知用户文件上传是否成功。
*/
}
–>
以上的代码存在不一致可绕过的问题。
当文件上传功能依赖于文件名的后缀来判断文件类型时,攻击者可以利用控制 $file
数组中参数的顺序来绕过文件类型验证,打开代理,上传正确的文件格式,例如:shell.jpg。
这种情况通常与程序对文件名和后缀的处理方式有关,具体原因如下:
- 文件名和后缀的处理方式不一致:在某些情况下,程序可能会将文件名和后缀分开处理,而不是整体进行验证。如果攻击者能够控制文件名和后缀的顺序,就有可能绕过这种验证机制。
- 文件类型验证依赖于错误的信息:有些程序可能会错误地依赖文件名中的后缀来判断文件类型,而忽略了其他更可靠的验证方式,比如文件内容或者 MIME 类型。攻击者可以利用这一点来伪装文件类型,绕过验证。
举例来说,假设程序接受文件上传,并且使用文件名的后缀来判断文件类型,以下是一个攻击场景:
- 攻击者构造一个文件名为
shell.jpg.php
的文件,并上传到服务器。 - 由于程序只检查文件名的后缀,认为这是一个
.jpg
格式的图片文件,就会通过验证。 - 程序将该文件保存在服务器上,并且允许用户访问,从而导致攻击者成功上传了一个恶意的 PHP 脚本文件。
在这个例子中,攻击者成功地通过控制文件名中的后缀顺序,绕过了文件类型验证,并成功上传了恶意文件,实现了攻击目的。
上传文件,抓请求包
这是一个HTTP协议的POST请求
POST /HTTP/1.1
Host:192.168.3.186:10093
User-Agent:Mozilla/5.0(Windows NT 10.0;Win64;x64;rv:80.0)Gecko/20100101
Firefox/80.04
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: zh-CN,zh;g=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=-----------15871529313486380551969503112
Content-Length:449R
0rigin:http://192.168.3.186:100930
DNT:1
Connection:close
Referer:http://192.168.3.186:10093/
Upgrade-lInsecure-Requests:1
-----------15871529313486380551969503112
Content-Disposition:formdata;name=“filename”
-----------15871529313486380551969503112
Content-Disposition: form-data; name=“file”; filename=“shell.jpg”
Content-Type:image/jpeg
-----------15871529313486380551969503112
Content-Disposition:form-data:name=“submit”
Submit
-----------15871529313486380551969503112–
请求包的解析:
请求头部分包括以下内容:
POST /HTTP/1.1
- 请求方法:POST
- 请求目标:/
- 协议版本:HTTP/1.1
Host:192.168.3.186:10093
HTTP请求头中的一个字段,表示请求目标的主机地址和端口。
在这个例子中,请求目标的主机地址是 192.168.3.186
,端口号是 10093
。
在HTTP协议中,任何请求都需要指定目标主机的地址和端口号,这是因为同一台服务器可能会提供多个服务(例如Web服务、FTP服务等),而端口号可以用来区分不同的服务。
如果没有指定端口号,则默认使用该服务的标准端口号。在Web服务中,标准端口号是80
User-Agent:Mozilla/5.0(Windows NT 10.0;Win64;x64;rv:80.0)Gecko/20100101 Firefox/80.0
是HTTP请求头中的一个字段,表示发起请求的用户代理(User-Agent)信息。User-Agent字段:指定客户端使用的浏览器类型和版本信息
具体来说,该字段中包含了浏览器或其他客户端程序的相关信息,例如所使用的操作系统、浏览器名称和版本号等。
Mozilla/5.0
:这部分通常称为产品标记(Product Token),它指示了用户代理是基于Mozilla浏览器引擎构建的。在过去,存在一些历史原因,使得大多数浏览器都使用了"Mozilla"作为他们的产品标记。(Windows NT 10.0; Win64; x64)
:这部分描述了操作系统的信息。在这个例子中,表示用户代理运行在 Windows NT 10.0 操作系统上,并且该操作系统是64位的。
在"Windows NT 10.0"中,“NT"代表"New Technology”,表示这是Windows操作系统的一种变体,基于"New Technology"内核。"10.0"指示了Windows 10的版本号。
3. rv:80.0
:这部分表示浏览器的版本号。在这个例子中,表示浏览器的版本是80.0。
4. Gecko/20100101
:这部分表示浏览器引擎的相关信息。表示使用了 Gecko 渲染引擎,它是 Firefox 浏览器的核心组成部分。,并且版本号是20100101。
5. User-Agent: Firefox/80.0
:这个字段标识了发起请求的客户端应用程序或浏览器的名称和版本号。在这个例子中,用户代理表示请求是由Firefox浏览器的80.0版本发起的。
综上所述,整个User-Agent
字段表示该请求是由一个基于Mozilla浏览器引擎(Gecko)构建的、运行在 Windows NT 10.0 操作系统上的64位浏览器(版本号80.0)发起的。
服务端通常会根据User-Agent
字段来判断请求来源的客户端类型和版本,从而做出相应的响应。例如,服务端可能会根据客户端浏览器的类型和版本来优化网页显示、选择合适的文件格式、提供符合客户端能力的功能等等。
需要注意的是,User-Agent
字段并不是强制要求的,有些客户端程序可能并不会发送该字段,或者发送的内容并不准确。此外,有些恶意程序也可能伪造User-Agent
字段,因此服务端不能完全信任该字段的内容。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: zh-CN,zh;g=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
Accept字段:指定客户端能够接收的内容类型及优先级
Accept-Language字段:指定客户端能够接收的自然语言
Accept-Encoding字段:指定客户端能够接收的编码格式
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
:这个字段指示了客户端可以接受的响应内容类型(MIME类型)。它是一个逗号分隔的列表,每个元素都有一个权重值(q值)来表示其优先级。在这个例子中,客户端能够接受的请求头中的内容类型首选是"text/html",然后是"application/xhtml+xml"、“application/xml”,最后是"image/webp",如果服务器没有提供以上类型,则可以接受任意类型"/"。权重值越高,表示优先级越高。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
:这个字段指示了客户端偏好的语言。它也是一个逗号分隔的列表,每个元素都有一个权重值来表示其优先级。在这个例子中,客户端首选的语言是"zh-CN"(简体中文),然后是"zh"(中文),接下来是"zh-TW"(繁体中文),“zh-HK”(香港中文),最后是"en-US"(美式英语)和"en"(英语)。权重值越高,表示优先级越高。Accept-Encoding: gzip, deflate
:这个字段指示了客户端能够解码的响应内容编码方式。在这个例子中,客户端可以接受使用gzip或deflate算法进行压缩的响应内容。
Content-Type:multipart/form-data;
Content-Type字段:指定请求体中的媒体类型和字符集
Content-Type
是HTTP请求头中的一个字段,用于指定请求体(Request Body)的媒体类型。媒体类型描述了请求体中数据的格式和结构。
Content-Type
的值是multipart/form-data
。这个值表示请求体中包含了多个部分(multipart),每个部分都有自己的数据类型和格式。multipart/form-data
通常用于向服务器提交包含文件上传或表单数据的请求。
当使用multipart/form-data
时,请求体会被划分为多个部分,每个部分都有自己的头部信息和数据内容。这些部分之间通过边界(boundary)进行分隔,边界是一个唯一的字符串,用于用于分隔不同的数据字段、标识不同的部分。服务器端可以通过解析请求体的边界来获取每个部分的数据。
Content-Type
字段还可以指定其他类型的媒体,例如application/json
表示请求体是JSON格式的数据,application/x-www-form-urlencoded
表示请求体是经过URL编码的表单数据等。
综上所述,Content-Type: multipart/form-data
表示请求体中包含多个部分(multipart),用于上传文件或提交表单数据。
boundary=-----------15871529313486380551969503112
boundary分割线:用于分隔不同的数据块,这里使用"—15871529313486380551969503112"作为boundary。
Content-Length:449R
Content-Length字段:指定请求体的长度,449字节
0rigin:http://192.168.3.186:100930
Origin字段:指定请求来源
DNT:1
DNT字段:表示是否启用“不跟踪”功能,本例中为1,表示启用了该功能。
Connection:close
Connection字段:指定连接类型,本例中为close,表示在完成请求后关闭连接。
Referer:http://192.168.3.186:10093/
Referer字段:指定当前页面的来源地址,http://192.168.3.186:10093/
Upgrade-lInsecure-Requests:1
Upgrade-Insecure-Requests字段:表示客户端是否愿意升级到安全连接(https),本例中为1,表示愿意。
请求体部分包括以下内容:
-----------15871529313486380551969503112
Content-Disposition:formdata;name=“filename”
第一个消息部分表示一个表单字段,它的 Content-Disposition
值为 "form-data"
,name
属性值为 "filename"
。这个字段的值为空。
Content-Disposition字段:指定数据块的类型和名称,本例中指定了一个文件类型的数据块,名为"file",文件名为"shell.jpg"。
-----------15871529313486380551969503112
Content-Disposition: form-data; name=“file”; filename=“shell.jpg”
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注网络安全获取)
给大家的福利
零基础入门
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
同时每个成长路线对应的板块都有配套的视频提供:
因篇幅有限,仅展示部分资料
网络安全面试题
绿盟护网行动
还有大家最喜欢的黑客技术
网络安全源码合集+工具包
所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
c9543810.png)
所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算