Fastbin attack
“Fastbin attack” 是一种针对**堆(heap)的攻击技术,利用了快速分配(fastbin)**内存管理机制中的漏洞。在C/C++程序中,快速分配是一种常见的内存分配机制,它通过维护多个不同大小的链表来管理已释放但尚未被重用的内存块。
Fastbin attack 的基本原理是通过伪造合适大小的堆块并构造堆溢出漏洞,使得程序将伪造的堆块链接到 fastbin 链表中。接着,攻击者可以通过多次分配和释放操作,绕过堆的内存分配检查,从而控制并修改返回的指针,实现任意内存写入或执行恶意代码的目的。
文件上传处理代码
总代码:
代码解析:
"凑成一对。/*
在PHP中,
是HTML注释的语法,而不是PHP代码的一部分。在PHP文件中,
将被视为普通文本而不会被解析为PHP代码。注释的内容不会在浏览器中显示
*/
$sandbox = ‘/var/www/html/upload/’ . md5(“phpIsBest” . $_SERVER[‘REMOTE_ADDR’]);
/*
这部分首先构建了一个名为 $sandbox 的目录路径,目录路径由固定的前缀 ‘/var/www/html/upload/’ 和用户 IP 地址经过 md5 哈希处理后的结果拼接而成。
*/
/*
在 PHP 中,$ 符号是一个变量标识符,用于声明或引用变量。
在 PHP 中,变量名可以以 $ 符号开头,后面跟着一个标识符(由字母、数字和下划线组成),以表示一个变量。
*/
@mkdir($sandbox);//然后尝试创建这个目录
@chdir($sandbox);//将当前工作目录切换到该目录
/*
在 PHP 中,@ 符号是一个错误控制运算符(Error Control Operator)。
它用于抑制代码中的错误或警告信息,使其不会被显示出来。当在一个表达式之前使用 @ 符号时,如果该表达式发生错误,PHP 将忽略该错误并继续执行后面的代码,而不会中断程序执行。
举例说明:
在
s
a
n
d
b
o
x
目录创建的代码中,
@
m
k
d
i
r
(
sandbox 目录创建的代码中,@mkdir(
sandbox目录创建的代码中,@mkdir(sandbox); 使用了 @ 符号。这意味着如果 mkdir() 函数调用中出现错误,例如:由于权限问题无法创建目录,PHP 将不会显示错误消息,并且代码将继续执行下去。
*/
/*
接下来是文件上传的处理部分。首先检查是否有文件被上传,然后进行了两方面的检查:
MIME 类型检查 & 文件名检查。
*/
if(!empty( F I L E S [ ′ f i l e ′ ] ) ) / ∗ 名为“ f i l e ”的文件 ! e m p t y ( _FILES['file'])) /* 名为“file”的文件 !empty( FILES[′file′]))/∗名为“file”的文件!empty(_FILES[‘file’]) 是一个条件表达式,用于检查是否上传了名为 ‘file’ 的文件。具体来说,它使用了 PHP 中的两个函数:empty() 和 $_FILES。
empty() 函数用于检查一个变量是否为空。如果变量为空,则返回 true,否则返回 false。在这里,empty($_FILES[‘file’]) 检查名为 ‘file’ 的文件是否被上传到服务器。
F I L E S 是一个超级全局数组,用于在 P H P 中处理 H T T P 文件上传。该数组包含了上传文件的相关信息,如文件名、文件类型、文件大小等。在这里, _FILES 是一个超级全局数组,用于在 PHP 中处理 HTTP 文件上传。该数组包含了上传文件的相关信息,如文件名、文件类型、文件大小等。在这里, FILES是一个超级全局数组,用于在PHP中处理HTTP文件上传。该数组包含了上传文件的相关信息,如文件名、文件类型、文件大小等。在这里,_FILES[‘file’] 表示上传到服务器的名为 ‘file’ 的文件的相关信息。
理解1:
(!,否定) + (empty,空的) = 不是空的 -> 有东西,有名为’file’的文件被上传到服务器
->
if(!empty($_FILES[‘file’])) :如果名为 ‘file’ 的文件成功上传到服务器,则执行 if 语句内的代码块,返回 true,否则返回 false。
理解2:
如果名为 ‘file’ 的文件被成功上传到服务器,!empty($_FILES[‘file’]) 将返回 true。这是因为 empty() 函数在检查一个变量是否为空时,如果变量不为空,即非空,则返回 false,然后 ! 取反运算符将 false 转换为 true。
*/
{
#mime check,MIME 类型检查:
if (!in_array($_FILES[‘file’][‘type’], [‘image/jpeg’,‘image/png’,‘image/gif’])) {
die(‘This type is not allowed!’);
}
/*
MIME 类型检查:
F
I
L
E
S
是一个特殊的超全局变量,用于处理上传的文件。
_FILES 是一个特殊的超全局变量,用于处理上传的文件。
FILES是一个特殊的超全局变量,用于处理上传的文件。_FILES[‘file’] 表示上传的名为 ‘file’ 的文件的相关信息,其中 ‘type’ 属性表示上传文件的 MIME 类型。因此,$_FILES[‘file’][‘type’] 表示上传文件的 MIME 类型。
检查上传文件的 MIME 类型是否为 ‘image/jpeg(JPEG 图片)’、‘image/png( PNG 图片)’ 或 ‘image/gif( GIF 图片)’,如果不是,则输出错误信息并终止程序。
in_array() 函数用于检查一个值是否存在于数组中。在这里,它的作用是检查 $_FILES[‘file’][‘type’] 是否在给定的类型数组 [‘image/jpeg’, ‘image/png’, ‘image/gif’] 中。
in_array() 函数 它的使用格式如下:
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
参数 $needle 是要查找的值,可以是任何数据类型。参数 $haystack 是待搜索的数组,是一个包含多个元素的数组。可选参数 $strict 是一个布尔值,表示是否进行严格比较,默认为 false。
函数返回值是一个布尔值,如果 $needle 存在于 $haystack 数组中,则返回 true,否则返回 false。
*/
/*
MIME 是一种标准,用于在互联网上对多媒体和其他类型的数据进行标识和描述。MIME(Multipurpose Internet Mail Extensions)中文名称为“多用途互联网邮件扩展”。
MIME 类型检查是指通过检查文件的扩展名或内容来确定文件的 MIME 类型。每个文件都有一个关联的 MIME 类型,它指示了文件的内容类型。
MIME 类型将帮助浏览器和其他应用程序正确解释和处理文件。通过检查文件的扩展名或内容,可以确定文件的 MIME 类型,并相应地处理它。这在上传文件、下载文件或处理文件时非常有用。
例如,常见的 MIME 类型包括:
text/plain:普通文本文件
text/html:HTML 文件
application/pdf:PDF 文件
image/jpeg:JPEG 图像文件
audio/mp3:MP3 音频文件
video/mp4:MP4 视频文件
*/
#check filename文件名检查
f
i
l
e
(
!
i
s
a
r
r
a
y
(
file (!is_array(
file(!isarray(file)) {
f
i
l
e
=
e
x
p
l
o
d
e
(
′
.
′
,
s
t
r
t
o
l
o
w
e
r
(
file = explode('.', strtolower(
file=explode(′.′,strtolower(file));
}
/*
这段代码的作用是将 $file 变量转换为数组,如果 $file 本身就是一个数组,则不做处理。
该代码使用了 PHP 中的逻辑非运算符 ! 和类型判断函数 is_array(),以及字符串函数 explode() 和转换函数 strtolower()。
首先,is_array() 函数用于检查变量是否为数组。如果
f
i
l
e
不是数组,即
!
i
s
a
r
r
a
y
(
file 不是数组,即 !is_array(
file不是数组,即!isarray(file) 为 true,则执行括号内的代码。否则,跳过括号内的代码不执行。
注意区分函数 is_array()和 in_array()
在括号内的代码中,strtolower() 函数用于将 $file 变量中的所有字母转换为小写。
explode() 函数将 $file 变量按照点号 ‘.’ 进行拆分,并返回拆分后的数组。例如,如果 f i l e 为 ′ e x a m p l e . j p g ′ ,则 e x p l o d e ( ′ . ′ , s t r t o l o w e r ( file 为 'example.jpg',则 explode('.', strtolower( file为′example.jpg′,则explode(′.′,strtolower(file)) 返回一个包含两个元素的数组 [‘example’, ‘jpg’]。
最后,将拆分后的数组赋值给 $file 变量,从而将 $file 转换为数组。如果
f
i
l
e
本身就是一个数组,则该代码不会执行任何操作,因为已经满足条件
!
i
s
a
r
r
a
y
(
file 本身就是一个数组,则该代码不会执行任何操作,因为已经满足条件 !is_array(
file本身就是一个数组,则该代码不会执行任何操作,因为已经满足条件!isarray(file) 为 false。
/
e
x
t
=
e
n
d
(
ext = end(
ext=end(file);
if(!in_array($ext,[‘jpg’,‘png’,‘gif’])) {
die(‘This file is not allowed!’);
}
/
文件名检查:对文件名进行检查,确保文件名中只包含 ‘jpg’、‘png’ 或 ‘gif’ 这三种类型的图片文件扩展名,如果不是,则输出“提示错误的信息”并终止程序。
*/
f
i
l
e
n
a
m
e
=
r
e
s
e
t
(
filename = reset(
filename=reset(file).‘.’.
f
i
l
e
[
c
o
u
n
t
(
file[count(
file[count(file) - 1];
/*
这行代码的作用是根据数组 $file 中的元素来构建一个文件名。
reset($file) 函数返回数组 $file 的第一个元素的值。
count($file) - 1 返回数组 $file 中元素的数量减去 1,即最后一个元素的索引。
一般情况下,数组元素的索引是从 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
自我介绍一下,小编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、安卓逆向、云计算