寒假学web--day06
简介
今天的主要内容为文件上传,包括一些简单的和一些高级的绕过姿势
一些小细节
平时我们通过POST方式上传数据时,enctype是application/x-www-form-urlencode,而在文件上传时,是multipart/form-data
上传的文件会存在超全局变量$_FILES里面
上传的文件会先存放在临时目录里面,如果不进行后续的存储操作就会被清除
存放文件的函数为move_upload_file
一个文件上传的html文件
<form action="http://example.com" enctype="multipart/form-data" method="post" >
<input name="file" type="file" />
<input type="submit" value="upload" />
</form>
黑名单绕过
把后缀名中的php替换为空
可以通过双写绕过,即后缀名写为pphphp
禁止使用php后缀
可以用php3,php5,phps,phtml代替
php文件上传00截断
原理:字符串的结束标志为/00,所以我们可以使用/00来截断
比如
不允许上传后缀名为php的文件,那么我们可以写123.php%00.jpg
在检测时,是先取最后一个点后面的字符串为后缀名,这里是jpg,可以通过检测,在写到目录时,遇到%00时,就认为字符串已经结束了,最后就把123.php当作了文件名
注意:版本要求php<5.3.4 java<7u40
该漏洞已经基本不存在了
iconv字符转换异常后造成了字符截断
php文件上传场景下的文件名字符集转换时,可能出现截断问题
utf-8字符集,默认的字符编码范围时0x00-0x7f,iconv转换的字符不在上面的范围之内时,低版本的php会报错,同时不再处理后面的字符,这样就造成了截断问题
比如
123.php%df.jpg,与00截断相似,这里的%df超出了范围,导致后面的.jpg就不会再被处理,文件名就变成了123.php
利用web服务器解析漏洞绕过
apache
多后缀解析漏洞
当我们上传apache不认识的后缀名的文件时,apache就会往前找到认识的后缀再解析,比如123.txt.abc,会被当做txt文件来解析
imagemagic组件白名单绕过
条件:目标主机安装了<=3.3.0版本的imagemagic插件
再php.ini中启用了这个插件
通过php new imageick对象的方式来处理图片,且php版本> 5.4
满足以上条件时,上传特定的svg图片,来实现组件的缺陷导致任意代码执行
nginx
条件:错误的nginx配置和php-fpm(处理php文件的中间件)配置
cgi.fix_pathinfo默认开启
访问123.txt/123.php时,如果123.php不存在,就会找/前面的文件,把其当作php文件解析
例如
题目仅允许上传txt文件,那么我们就把一句话木马写在123.txt里面,然后访问123.txt/123.php(123.php不存在),就能成功解析我们的一句话木马
iis
windows自带的,iis6.0版本中(用于windowsxp),如果解析的目录名字为xxx.asp,那么该目录下所有的文件都会按照asp来解析
一些高级的绕过姿势
利用配置文件
要求:网站上必须存在php文件,因为auto_append_file是将后面跟的文件的内容复制到主文件中,而主文件必须是php文件才能执行里面的php代码
php的配置文件为php.ini,如果存在.htaccess或者nginx.htaccess文件,就会覆盖php.ini的内容
在nginx下,默认时使用.user.ini配置文件来进行php配置的
我们主要利用的是里面的auto_prepend_file和auto_append_file,前者是把文件内容包含在主文件前面,后者是包含在主文件后面
打法:上传一个名为.user.ini,内容为auto_append_file=123.txt的文件,然后上传一个名为123.txt,内容为一句话木马的文件,然后访问首页(一个php文件)来执行123.txt里面的php代码
服务端内容检测
服务端不局限与检测文件名,还会检测文件的后缀和文件的内容
我们可以先通过二分法找出过滤的关键字,然后使用替代的语法来绕过
POST可以换成GET,REQUEST,COOKIE等等
配合伪协议来绕过
如果对文件的内容检测太过于严格,实在想不替代的语法,可以考虑通过伪协议来绕过
在php的配置文件中,是支持伪协议的,不一定是文件
比如我们设置
auto_append_file=php://input
然后在访问首页(一个php文件)是时,我们直接写php代码,比如
<?php phpinfo(); ?>
就可以直接被执行
配合日志文件包含
在.user.ini配置文件里,我们也可以将日志文件包含进来
auto_append_file=/var/log/nginx/access.log
这个时候再访问首页,就可以看到我们的日志文件的内容,再配合上我们昨天学到的UA写马,就可以执行一些操作
getimagesize函数绕过
如果使用getimagesize函数来检测是不是图片,而不采取其他措施的情况下,一旦绕过了该函数,就可以实现任意文件上传
这个函数可以识别XBM格式图片,识别方法为,如果检测到#define %s %d就会认为时XBM图片的宽或高
那么如果我们在我们的代码里面写上这个特征,就可以绕过这个函数的检测
例如
我们在.user.ini里面这样写
#define width 100;
#define height 100;
auto_append_file=/var/log/nginx/access.log
就可以绕过getimagesize函数的检测,实现日志文件包含
png,jpg二次渲染绕过
二次渲染:通过imagepng方法,来动态的依据我们上传的图片,二次生成一个png图片,里面的php代码就会被清楚掉,所以我们需要使用特殊的方法来构造图片,来保证其不被清除
可以在网上找一个脚本,来生成一个图片,注意里面的一句话木马是动态调用,0表示方法名,1表示参数
可以传参?0=system
1=ls /
jpg的二次渲染与png做法相同
phar文件上传绕过
配置要求:phar.readonly=Off,改的时候去掉前面的分号,不然无法生成phar包
我们利用生成phar包的脚本,上传之后访问,就会在服务器上生成一个phar文件
<?php
class TestObject {
}
@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->addFromString("test.txt", "<?php eval($_POST[1]);?>"); //添加要压缩的文件
$phar->stopBuffering();
?>
如果我们可以控制写入文件及其内容,可以把phar文件的内容写到压缩包里面,然后利用phar协议解压出来