欢迎来到 无奈人生 安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

对文件上传的一些思考和总结

来源:未知 作者:wnhack 时间:2019-01-08 14:16 点击: 我要投稿
广告位API接口通信错误,查看德得广告获取帮助
前言
最近在 ctf 比赛中考察到了很多关于文件上传的知识点,然而文件上传这块知识掌握的不是很好。所以这里总结一下近期 ctf 比赛中遇到的文件上传题目的知识考点和常见思路,并且给出相应的例题。
简单的总结一下常见的思路,再根据自己的经验简单列出近些比赛中的一些上传题的套路。
 
文件上传的本质
文件上传还是归根结底是客户端的 POST 请求,消息主体就是一些上传信息。前端上传页面需要指定 enctype 为 multipart/form-data 或者 Multipart/form-data 才能正常上传文件。
multipart 格式的数据会将一个表单拆分为多个部分(part),每个部分对应一个输入域。在一般的表单输入域中,它所对应的部分中会放置文本型数据,但是如果上传文件的话,它所对应的部分可以是二进制,下面展现了 multipart 的请求体:
filename 字段是必要的,指定了上传时的那个文件的文件名。其他的可有可无
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
这里在每个字段之间使用 ———WebKitFormBoundaryxxx 隔开,boundary是一个字符串,用来切分数据。
这里就和 post 请求一样,可以自己增加参数,就形如下面这样,将参数名放到 name 里,参数值放到下面:
------WebKitFormBoundary1PkqXeou9aUAIMHr
Content-Disposition: form-data; name="filename"
1.php
那么这里就增加了一个参数 filename = ‘1.php’
 
基本上传思路的回顾
在渗透测试或者 ctf 过程中,遇到文件上传常见的思路无非是尝试绕过一些限制直接上传 shell (脚本文件),最基本的绕过方法有以下几种:
前端绕过
这里很基础了,直接绕过前端的 js 判断就行了。
这里举个例子,某某门户系统:
在后台页面定制处,可以插入背景图片,如果直接插入 shell 就会提示不允许上传。那么这里可以先上传一个 gif 文件,抓包,改后缀名再发包就可以绕过。


这只是最简单的前端验证绕过,当然这里还可以在 f12 里直接去掉前端 js 验证。
MIME
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型。
即在传输过程中标记文件类型的一种方法,也就是 HTTP 文件请求头中的 Content-Type 。
简单的上传情况一般是单独验证这个字段值或者有时配合文件后缀名进行验证的。
这里再举一个 SUCTF 招新赛的一个例子。题目只有一个上传页面,解决这种题目最简单粗暴的方法就是直接将 Content-Type 和后缀名进行组合来爆破。

选择两个变量,选择 Cluster bomb 模式,跑一下就出结果了


这题的 “” 被过滤了,可以使用下面的 payload 进行简单的绕过
@system($_GET['c']);
大写 Multipart
即将请求头中的 Content-Type 的 multipart/form-data 第一个字符 m 改成 M,即 Multipart/form-data(不影响传输)
这里的例子是 bugku 的”求getshell”,同样只有一个上传界面:

burp 抓包,使用上面爆破的方法无效,最后发现是将 multipart 改成 Multipart…这样就成功绕过了

其实这题有点脑洞了。。不过没关系,这里的重点不是这个。
 
后缀名构造
构造数组绕过
最近碰到的两道题,一道是网鼎杯第二场的 wafUpload,一道是上海网安赛的 web3。这两道考点都很类似。但是还是有一些小的差异,我们一道一道来看。
先看一下 wafUpload 这道题:
    
    Upload Your Shell
    Filename:
    
    
    
审计源码可以知道,代码中用 end 函数取到上传文件的后缀并判断,用 reset 函数返回的值作为文件名
根据题目,需要绕过两层判断。
1.第一层,直接抓包修改 MIME 为 image/png 就行了。
2.第二层,构造 filename 字段为数组
仔细看 html 代码中提供了一个 filename 字段,在下面这句代码的判断中,会先查看是否有直接 post 提交的 filename 字段,如果有的话就使用这个字段的值(这个就有点类似提示的作用) 前言
最近在 ctf 比赛中考察到了很多关于文件上传的知识点,然而文件上传这块知识掌握的不是很好。所以这里总结一下近期 ctf 比赛中遇到的文件上传题目的知识考点和常见思路,并且给出相应的例题。
简单的总结一下常见的思路,再根据自己的经验简单列出近些比赛中的一些上传题的套路。
 
文件上传的本质 copyright 无奈人生
文件上传还是归根结底是客户端的 POST 请求,消息主体就是一些上传信息。前端上传页面需要指定 enctype 为 multipart/form-data 或者 Multipart/form-data 才能正常上传文件。
multipart 格式的数据会将一个表单拆分为多个部分(part),每个部分对应一个输入域。在一般的表单输入域中,它所对应的部分中会放置文本型数据,但是如果上传文件的话,它所对应的部分可以是二进制,下面展现了 multipart 的请求体:
filename 字段是必要的,指定了上传时的那个文件的文件名。其他的可有可无 无奈人生安全网
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA copyright 无奈人生
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
这里在每个字段之间使用 ———WebKitFormBoundaryxxx 隔开,boundary是一个字符串,用来切分数据。

copyright 无奈人生


这里就和 post 请求一样,可以自己增加参数,就形如下面这样,将参数名放到 name 里,参数值放到下面:
------WebKitFormBoundary1PkqXeou9aUAIMHr
Content-Disposition: form-data; name="filename"
1.php
那么这里就增加了一个参数 filename = ‘1.php’ www.wnhack.com
 
基本上传思路的回顾
在渗透测试或者 ctf 过程中,遇到文件上传常见的思路无非是尝试绕过一些限制直接上传 shell (脚本文件),最基本的绕过方法有以下几种:
前端绕过
这里很基础了,直接绕过前端的 js 判断就行了。 copyright 无奈人生
这里举个例子,某某门户系统:
在后台页面定制处,可以插入背景图片,如果直接插入 shell 就会提示不允许上传。那么这里可以先上传一个 gif 文件,抓包,改后缀名再发包就可以绕过。

copyright 无奈人生

这只是最简单的前端验证绕过,当然这里还可以在 f12 里直接去掉前端 js 验证。
MIME
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型。
即在传输过程中标记文件类型的一种方法,也就是 HTTP 文件请求头中的 Content-Type 。 www.wnhack.com
简单的上传情况一般是单独验证这个字段值或者有时配合文件后缀名进行验证的。
这里再举一个 SUCTF 招新赛的一个例子。题目只有一个上传页面,解决这种题目最简单粗暴的方法就是直接将 Content-Type 和后缀名进行组合来爆破。

选择两个变量,选择 Cluster bomb 模式,跑一下就出结果了 无奈人生安全网


这题的 “” 被过滤了,可以使用下面的 payload 进行简单的绕过
@system($_GET['c']); 本文来自无奈人生安全网
大写 Multipart
即将请求头中的 Content-Type 的 multipart/form-data 第一个字符 m 改成 M,即 Multipart/form-data(不影响传输)
这里的例子是 bugku 的”求getshell”,同样只有一个上传界面:
无奈人生安全网
burp 抓包,使用上面爆破的方法无效,最后发现是将 multipart 改成 Multipart…这样就成功绕过了

其实这题有点脑洞了。。不过没关系,这里的重点不是这个。
 

copyright 无奈人生


后缀名构造
构造数组绕过
最近碰到的两道题,一道是网鼎杯第二场的 wafUpload,一道是上海网安赛的 web3。这两道考点都很类似。但是还是有一些小的差异,我们一道一道来看。
先看一下 wafUpload 这道题:
    

www.wnhack.com


    Upload Your Shell
    Filename:
    
    
    

本文来自无奈人生安全网


审计源码可以知道,代码中用 end 函数取到上传文件的后缀并判断,用 reset 函数返回的值作为文件名
根据题目,需要绕过两层判断。
1.第一层,直接抓包修改 MIME 为 image/png 就行了。
2.第二层,构造 filename 字段为数组
仔细看 html 代码中提供了一个 filename 字段,在下面这句代码的判断中,会先查看是否有直接 post 提交的 filename 字段,如果有的话就使用这个字段的值(这个就有点类似提示的作用)。 (责任编辑:wnhack)
【声明】:无奈人生安全网(http://www.wnhack.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱472701013@qq.com,我们会在最短的时间内进行处理。