文件上传漏洞总结
前端验证绕过
条件:网站或CMS仅在前端使用JavaScript来校验。
流程:
上传js.png抓包修改为js.php,通过Burp Suite抓包,修改内容后放行。
通过Chrome禁止/删除js代码。
.htaccess绕过
什么是.htaccess?
.htaccess文件(分布式配置文件)提供了一种方式,使得配置文件可以随文件夹不同而不同,其所放置的文件夹及所有子文件夹都会受此影响,其语法同apache主配置文件。
它提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。
管理员可以通过Apache的AllowOverride指令来设置。
.htaccess文件是用于apache服务器下的控制文件访问的配置文件,因此Nginx下是不会生效的
利用.htaccess?
场景:启用了.htaccess文件的网站,使用此文件类型来绕过限制较为全面的黑名单过滤。
利用:
先上传一个.htaccess文件,内容如下:
SetHandler application/x-httpd-php
把文件都会当成php来解析
接下来直接上传文件内容为一句话木马的正确类型文件,比如222.png
大小写绕过
这是一种比较简单的绕过方式,针对黑名单策略。
上传php的一句话木马,上传一个pHp即可。
截断绕过
%00截断是和php版本有关联型的,是5.2.x版本的一个漏洞,php5.3.24代码中已经修复,修复的代码位于ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER
函数的开始处
%00和0x00:
0x00是十六进制的0
%00是url加密,是url的终止符
当程序在输出含有chr(0)变量时,chr(0)后面的数据会被停止,换句话说,就是误把它当成结束符,后面的数据直接忽略,这就导致漏洞产生的原因。
截断条件:php版本小于5.3.4,php的magic_quotes_gpc为OFF状态
利用:(post,get)
get:上传php文件get文件后缀名加入%00
post:上传php文件需要在二进制中进行修改。
MIME验证绕过(Content-Type)#
原理:Content-Type(MediaType),即是Internet Media Type,互联网媒体类型,也叫做MIME类型。在互联网中有成百上千中不同的数据类型,HTTP在传输数据对象时会为他们打上称为MIME的数据格式标签,用于区分数据类型。最初MIME是用于电子邮件系统的,后来HTTP也采用了这一方案。在HTTP协议消息头中,使用Content-Type来表示请求和响应中的媒体类型信息。它用来告诉服务端如何处理请求的数据,以及告诉客户端(一般是浏览器)如何解析响应的数据,比如显示图片,解析并展示html等等。
使用burpsuite拦截分别为jpg和php类型观察Content-Type发现Content-Type不同.
空格绕过
代码对后缀进行了大小写处理
文件名最后增加空格,写成666.phpx(x表示空格),上传后保存在系统上的文件名最后的一个空格会被去掉,实际上保存的文件名就是666.php
上传666.php抓包修改后缀为666.phpx(x表示空格),
点绕过
代码没有对后缀名末尾的点进行处理,自此会自动去掉后缀名中最后的”.”,可在后缀名中加”.”绕过:
上传222.png抓包修改为222.php.
::$DATA绕过
没有对后缀名中的’:: D A T A ’ 进 行 过 滤 。 在 p h p + w i n d o w s 的 情 况 下 : 如 果 文 件 名 + " : : DATA’进行过滤。在php+windows的情况下:如果文件名+":: DATA’进行过滤。在php+windows的情况下:如果文件名+"::DATA“会把:: D A T A 之 后 的 数 据 当 成 文 件 流 处 理 , 不 会 检 测 后 缀 名 . 且 保 持 ” : : DATA之后的数据当成文件流处理,不会检测后缀名.且保持”:: DATA之后的数据当成文件流处理,不会检测后缀名.且保持”::DATA"之前的文件名。利用windows特性,可在后缀名中加” :: D A T A ” 绕 过 , 文 件 名 改 成 222. p h p : : DATA”绕过,文件名改成222.php:: DATA”绕过,文件名改成222.php::DATA,上传成功后保存的文件名其实是222.php:
双写文件名绕过
黑名单过滤,将黑名单里的后缀名替换为空且只替换一次,
绕过原理:
上传文件的后缀名凡是符合黑名单中任意一个后缀都会被替换为空,那么我们可以利用双写后缀的方式进行绕过。所以pphpph中间的php就被抹去了,剩下php达到木马文件后缀的要求。
图片马绕过
通过读文件的前2个字节判断文件类型,也就是绕过文件头检查,添加GIF图片的文件头GIF89a,绕过GIF图片检查。也可制作图片马:
copy 212.jpg /b + 222.php /a 444.jpg
一般通过文件包含漏洞包含图片🐎
getimagesize()图像信息判断
如果上传的不是图片文件,那么getimagesize()就获取不到信息,则不允许上传。
通过Linux合成图片马,此时使用getimagesize()既可以获取图片信息,文件后缀php也能被解析为脚本文件,从而绕过getimagesize()的限制。
cat image.jpg webshell.php > image.php
竞争条件攻击
一些网站上传文件的逻辑是先允许上传任意文件,然后检查上传的文件是否包含Webshell脚本,如果包含则删除文件。这里存在一个问题是文件上传成功后和删除文件之间存在一个短的时间差(因为要执行文件上传和删除文件的操作),攻击者就可以利用这个时间差完成竞争条件的上传漏洞攻击。
利用:
可以先上传一个webshell脚本10.php,10.php的内容是生成一个新的webshell脚本shell.php。10.php的代码如下
?>
当10.php上传成功后,客户端检查脚本文件后会自动生成shell.php。
user.ini
进行文件上传绕过。
user.ini官方文档
自 PHP 5.3.0 起,PHP 支持基于每个目录的 INI 文件配置。此类文件 仅被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果你的 PHP 以模块化运行在 Apache 里,则用 .htaccess 文件有同样效果。
除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER[‘DOCUMENT_ROOT’] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。
在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI 设置可被识别。
思路:
上传一个.user.ini 文件设置一个文件333.png然后访问index.php就相当于包含了333.png
先写好一个.user.ini内容如下:
GIF89a
auto_prepend_file=333.png
在写一个shell
意思为PHP有一个可以重写的配置文件,类似于apache的.htaccess绕过,但是PHP这个比较苛刻,需要开启一定功能才能使用,
先上传.user.ini.png文件(之后抓包之后再修改文件名为.user.ini.)
然后再上传shell文件333.png,访问index.php自动包含
用POST:xiaoyu=system();查找flag
文件日志包含漏洞
日志包含漏洞原因:
某php文件存在本地文件包含漏洞,但无法上传文件,利用包含漏洞包含Apache(看服务器是Apache还是nginx)日志文件也可以获取WebShell
注意:需要开启服务器记录日志功能
访问日志的位置和文件名在不同的系统上会有所差异
apache一般是/var/log/apache/access.log。:
nginx的log在/var/log/nginx/access.log和/var/log/nginx/error.log
Apache运行后一般默认会生成两个日志文件,这两个文件是access.log(访问日志)和error.log(错误日志),Apache的访问日志文件记录了客户端的每次请求及服务器响应的相关信息。
127.0.0.1 - - [02/Dec/2019:22:18:28 +0800] "GET / HTTP/1.1" 200 5615
127.0.0.1 - - [02/Dec/2019:22:18:28 +0800] "GET /wampthemes/classic/style.css HTTP/1.1" 200 2415
127.0.0.1 - - [02/Dec/2019:22:18:29 +0800] "GET /wampthemes/classic/img/gifLogo.gif HTTP/1.1" 200 3525
当访问一个不存在的资源时,Apache日志同样会记录 例如访问http://127.0.0.1/<?php phpinfo();?>。Apache会记录请求“<?php phpinfo();?>”,并写到access.log文件中,这时候去包含access.log就可以利用包含漏洞
但并不能直接利用,原因是直接访问URL后,一句话木马在日志文件中被编码了 需要通过burpsuite拦截直接访问http://127.0.0.1/<?php phpinfo();?> 就能生成包含一句话木马的access.log文件
图片马 exif_imagetype()
exif_imagetype()函数:用于判断一个图像的类型,正常则返回签名对应常量,否则返回false
绕过方法:上传图片木马即可
超短shell
在某些时候,服务器对上传文件的大小限制很大,这时候我们就需要把shell代码缩短至极限。
<?=`$_GET[x]`?>这里利用的是PHP命令执行的特性。`号内会被当做命令执行。