# content-type 验证审计 + 绕过

本篇讲解对于文件上传漏洞中 ——content type 验证审计 + 绕过

# content-type 验证审计

来到 Pass-02

image-20221003135212262

我们点击上传,会提示 “文件类型不正确,请重新上传”

image-20221003135246520

不多说,直接开始抓包,看看怎么个情况。

image-20221003135340470

媒体类型(通常称为 Multipurpose Internet Mail ExtensionsMIME 类型)是一种标准,用来表示文档、文件或字节流的性质和格式。

通用结构:

type/subtype

MIME 的组成结构非常简单;由类型与子类型两个字符串中间用 '/' 分隔而组成。不允许空格存在。

  • type 表示可以被分多个子类的独立类别。
  • subtype 表示细分后的每个类型

独立类型如下

text/plain
text/html
image/jpeg
image/png
audio/mpeg
audio/ogg
audio/*
video/mp4
application/*
application/json
application/javascript
application/ecmascript
application/octet-stream

image-20221003135647652

上传文件的时候,Content-Type 有两类标识:

  • 标识文件上传的请求 multipart/form-data【可用于 HTML表单 从浏览器发送信息给服务器】
  • 标识文件类型 application/octet-stream 【这是应用程序文件的默认值。意思是 未知的应用程序文件 ,浏览器一般不会自动执行或询问执行】

了解了基本上传格式后,查看源码内容【单击 “显示源码” 按钮】

image-20221003140629128

这一段的主要逻辑:

  • 定义 $is_upload 变量,默认值为 false

  • 定义 $msg 变量,默认值为空

  • isset 函数判断 submit的POST请求 是否为空

    • 如果为空,什么都不做
    • 如果不为空,则继续往下走
  • 判断 UPLOAD_PATH 上传目录是否存在

    • 如果不存在,则返回 “文件夹不存在,请手工创建”
    • 如果存在,则继续往下走
  • 判断 upload_file 的 type 的字段的值是否为 image/jpeg 、png、gif 中的任意一个

    • 如果不是,则返回 "文件类型不正确,请重新上传"
    • 如果是,则继续往下走
  • 定义一个 $temp_file 变量,接收 upload_filetmp_name 字段的值

    • $ _FILES ['upload_file'] 表示内置名为 upload_fileFILES数组

    • PHP $_FILES 是一个预定义的数组,用来获取通过 POST 方法上传文件的相关信息。
      如果为单个文件上传,那么 $_FILES 为二维数组;
      如果为多个文件上传,那么 $_FILES 为三维数组。
      $_FILES数组内容如下: 
      $_FILES['upload_file']['name'] 客户端文件的原名称。 
      $_FILES['upload_file']['type'] 文件的 MIME 类型,需要浏览器提供该信息的支持,例如"image/gif"
      $_FILES['upload_file']['size'] 已上传文件的大小,单位为字节。 
      $_FILES['upload_file']['tmp_name'] 文件被上传后在服务端储存的临时文件名,一般是系统默认。可以在php.ini的upload_tmp_dir 指定,但用putenv() 函数设置是不起作用的。 
      $_FILES['upload_file']['error'] 和该文件上传相关的错误代码。['error'] 是在 PHP 4.2.0 版本中增加的。下面是它的说明:(它们在PHP3.0以后成了常量)
  • 定义一个 img_path 变量,接收 UPLOAD_PATH+’/’+upload_file 关联信息中 name 字段的值

    • ['name'] 是表示 文件"在上传者机器上"的文件名 ,或者叫 客户端文件的原名称
  • 判断 move_uploaded_file 的返回值,其函数原型为 move_uploaded_file( string file, string dest) ,意为 将上传的file移动到dest

    • 如果临时文件 $temp_file 成功移动到 $img_path 当中【相当于 linux 的 mv 指令】,那么就令 $is_uploadtrue ,并返回 "上传 Success!"
    • 如果没有移动成功,则返回 “上传出错!”

# content-type 绕过

抓包后将 Content-type字段的值 修改为 image/jpegimage/pngimage/gif 的任何一种即可实现绕过。

image-20221003144019576

修改如下

image-20221003144200588

点击 Forward,提示 "上传 Success!"

image-20221003144223909

至此,content-type 验证审计 + 绕过演示完毕。