Web安全深度剖析读书笔记
0x01 包含漏洞原理
- 编程语言中设计了可以在某个代码中包含其他已经写好或者可以供其他代码调用的文件,如调用一些定义好的类或者函数。而正是因为可以包含其他文件从而有可能会产生文件包含漏洞。
- 大多数Web语言都可以使用文件包含操作,由于PHP语言的文件包含功能强大因此也容易出现文件包含漏洞。况且目前大部分网站由PHP开发,所以着重先研究PHP文件包含漏洞。
0x02 PHP 包含
PHP 中的包含函数:
- include():如果包含文件未找到会显示警告,脚本继续执行;
- include_once():包含过的文件不再包含,包含文件未找到会显示警告,脚本继续执行;
- require():包含文件未找到会产生致命错误,脚本终止;
- require_once():包含过的文件不再包含,包含文件未找到会产生致命错误,脚本终止。
分类
1. LFI
- 本地文件包含故名包含的文件在本地服务器;
- 当网站存在文件包含漏洞时,包含的文件只要符合php语法规范,PHP解析器就会对其解析,文件如果不符合PHP语法规范则会暴露出源代码。若包含一个根本不存在的文件则会爆出网站的绝对路径。
2. RFI
- 远程文件包含故名包含的文件不在本地服务器,而需要远程访问其他服务器
- 前提:PHP开启了远程包含功能(php.ini中allow_url_include=on)
利用
<?php
if(isset($_GET['page'])){
include $_GET['page'];
}else{
include 'home.php';
}
?>
// 前台代码
<a href="Index.php?page=main.php">主页</a>
<a href="Index.php?page=news.php">新闻</a>
-
读取敏感文件
-
远程包含SHELL
-
本地包含配合文件上传
上传后门,使用文件包含构造可以利用的URL
-
PHP 伪协议
-
Apache 日志文件包含: access.log
文件内容每一行记录一次网站访问记录。当访问一个不存在的资源时,Apache日志同样会记录,这就意味着如果网站存在本地包含漏洞,却没有可以包含的文件时,就可以去访问:
http://www.xxx.com/<?php phpinfo();?>
。Apache 会记录请求,并写到 access.log 中,这时再去包含 Apache 的日志文件,就可以利用包含漏洞。 -
截断包含
很多程序员认为PHP中的包含漏洞比较好修复,固定扩展名即可,
<?php if(isset($_GET['page'])){ include $_GET['page']. ".php"; }else{ include 'home.php'; } ?>
当你上传图片木马,访问
jpg
后缀的文件时,它会为其加上php
后缀解析。而该PHP文件是不存在的,从而使包含漏洞无法正常利用。可以在URL的最后加上
%00
进行截断。此方法只适用于magic_quotes_gpc = Off
时。
0x02 JSP 包含
JSP 包含分为两种方式,静态包含和动态包含。
<%-- 静态包含 --%>
<%@ include file="..." %>
<%-- 动态包含 --%>
<jsp:include page="...">
静态包含
静态包含语句先进行包含再做处理操作。JSP语法规定,include指令为静态包含,只允许包含一个已经存在于服务器中的文件,而不能使用变量来控制包含某个文件。
动态包含
动态包含与静态包含恰恰相反,在运行时首先会处理被包含页面,然后再包含,而且可以包含一个动态页面。
0x03 安全包含
- 严格判断包含中的参数是否外部可控;代码层面
- 限制被包含文件所在路径,并限制目录跳转字符
../
; - 为被包含文件设置白名单;
- 尽量不使用动态包含;