成因

上传文件时没有对上传的文件进行严格的验证和过滤,容易造成上传任意文件的情况,从而使得攻击者绕过上传机制上传恶意代码

恶意代码文件就是php asp aspx jsp等,也被称为webshell

文件上传漏洞的类型

  1. 前端验证

  2. .htaccess利用

  3. MIME类型绕过

  4. %00截断

  5. 双写绕过

  6. 文件头检查

。。。

注:1~4的例题在周报3中

一句话木马(php)

1
<?php @eval($_POST["ctf"]);?>
  • 这是 PHP 代码的起始标记,表明从这里开始是 PHP 代码区域。

  • @:在 PHP 中,@ 是错误抑制符,不报错。

  • eval():是 PHP 的一个内置函数,它的作用是把字符串作为 PHP 代码来执行。

  • $_POST["ctf"]$_POST 是 PHP 的一个超全局变量,用于接收通过 POST 方法提交的数据。

  • 其中的ctf就是一句话的密码

也可以把$_POST换为$_GET,接收通过 GET 方法提交的数据

工具

上传一句话木马后,需要借助特定工具与木马建立连接,以执行命令、获取信息等。常用的操作一句话木马的工具:菜刀(中国菜刀)、蚁剑、冰蝎、哥斯拉

文件上传

表单简单举例:

1
2
3
4
5
<form action="" method="post" enctype="multipart/form-data" onsubmit="return checkfilesuffix()">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<input type="submit" name="submit" value="Submit" />
</form>
  • action="":表示表单数据将提交到当前页面。如果需要将数据提交到其他页面,可以在此处填写目标页面的 URL。

  • method="post":提交方式为 POST

  • enctype="multipart/form-data":这是文件上传表单必须设置的属性,用于指定表单数据的编码类型,以支持二进制文件的上传。

需要特别注意请求头中的Content-Type,它是用来告诉后端我们的数据类型和编码方式的

前端验证

原理

校验是通过前端javascript代码完成的,可以对前端javascript进行修改或者是通过抓包篡改上传的文件。

.htaccess利用

htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

——百度百科

MIME

MIME 类型是一种标准化的标识方式,用来描述数据的类型

MIME 类型通用结构:type/subtype

例如:

  • text/plain 表示文本文件的默认值。

  • application/octet-stream 表示所有其他情况的默认值。

  • 超文本标记语言文本 .html、.htmltext/html

  • 普通文本 .txttext/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 是要进行替换操作的目标字符串,即前面提取出来的文件名。

这行代码的作用是将文件名中包含的黑名单扩展名替换为空字符串

例题

题目:

解题:

先看源码

在注释中的提示中发现,后端使用了str_ireplace()函数把黑名单中的后缀名替换为空

上传一个文件名为w.pphphp的文件,内含一句话木马

后端自动将其中的php去掉了,变成了w.php

接着打开蚁剑,得到flag

文件头检查

文件头

在每一个文件(包括图片,视频或其他的非ASCII文件)的开头(十六进制 表示)实际上都有一片区域来显示这个文件的实际用法,这就是文件头标志。 在计算机中,文件头是一段用来描述文件内容和格式的数据。 不同的文件格式有不同的文件头格式。 文件头内容通常包含文件的类型、版本、编码方式、文件大小等信息,以方便计算机识别和处理文件。

例如:

jpg   文件头:FFD8FF                    

png    文件头:89504E47                   

gif  文件头:47494638

应用场景:当网站通过检查文件头的方式来判断文件类型时,可以在木马前添加合法的文件头

例题

题目:

解题

先看源码

一个普通的文件上传没啥特色,上传个文件试试

只能上传jpeg、jpg、png、gif类型

制作一个图片马

随便找一张后缀为png的图片(不要太大),用记事本打开在最后面写上一句话木马,并将后缀改为php

上传还是不行,还需要改一下包

打开burp,开启拦截

将Content-Type的内容改一下, 换为image/png

连接,获取flag