白帽子-第十四章 PHP安全

14.1文件包含漏洞

曾经提到过“代码注入漏洞”这种攻击,其原理就是注入一段用户能控制的脚本或代码,并让服务器执行。“代码注入”的典型代表就是文件包含。

在互联网的安全历史中,PHP的文件包含漏洞已经臭名昭著。

文件包含是php常用用法,主要由4个函数完成:include、require、include_once、require_once。当使用这4个函数包含一个新的文件时,该文件将作为PHP代码执行,PHP内核并不会在意该文件是什么类型。

要想成功利用这个漏洞,需要满足以下2个条件:

  1.include等函数通过动态变量的方式引入需要包含的文件;

  2.用户能够控制该动态变量。

14.1.1 本地文件包含

<?php
$file = $_GET['file'] ; // "../../etc/password'
if(file_exists('/home/wwwrun/'.$file.'.php')){
    //file_exists will return true as the file /home/wwwrun/../../etc/password exist   
    include '/home/wwwrun/'.$file.'.php';       
    //the file /etc/password will be included
}

这段代码中,用户控制了参数file,PHP将访问/etc/password文件。(使用隔断了.php标识

在一般的web应用中,0字节用户其实是不需要的,因此完全可以禁用0字节:

if (is_string($value)) {
    $value = str_replace("",'',$value);
}

但是这样并不能解决问题,由于操作系统对目录最大长度的限制,可以不需要0字节达到隔断的目的。

目录字符串在windows下是256字节,在Linux下是4096字节。最大长度之后的字符床将被丢弃,可以通过'./'的形式构造出这么长的字符串。

除了inluce等4个函数外,fopen、fread也十分危险。

解决方法:

  1.URLEncode

  2.设置php.ini的open_basedir限制项目的访问目录。

  注意:

    open_basedir的值是目录前缀.如果要限定一个目录,需要加上‘/’

    windows下多个目录应当使用分号隔开,linux下使用冒号隔开。

14.2 变量覆盖漏洞

变量如果未被初始化,且能被用户所空至,那么很可能导致安全问题。而在PHP中,这种情况在register_globals为ON时尤为严重。

(register_globals为ON,代表参数变量可以直接注入到全局变量中)

<?php
    if($auth){
        echo "private!";
    }
?>

在register_globals=ON的情况下,如果存在auth=1类似的参数,那么if语句的语句体将被执行。

类似的,通过$GLOBALS获取的变量,也可能导致变量覆盖。

如下是一段常见的禁用register_globals的代码:

if (int_get('register_globals')) foreach($_REQUEST as $k=>$v) unset(${$k});

这样会禁止参数注入到变量中,但是尝试使用GLOBAL[a]覆盖全局变量的时候,却成功覆盖了$a.

这是因为unset默认只会销毁局部变量

产生变量覆盖的其他场景:

  extract(),从数组中导出变量。

  遍历初始化变量。

  import_request_variables ,将GET、POST、Cookie中的变量导出到全局。

  parse_str(),解析URL中的query string

14.4 定制安全的PHP环境

php.ini 安全参数配置

  1.register_globals=OFF,否则容易出现变量覆盖。

  2.open_basedir ,用于对抗文件包含、目录遍历等攻击。

  3.allow_url_include=off、allow_url_fopen=off,用于对抗远程文件包含。

  4.display_errors=off,开发模式下可为on,否则会暴露很多蜜柑信息。

  5.log_errors=on,正式环境下使用即可,把错误信息记录在日志中。

  6.magic_quotes_gpc,推荐关闭,他并不只得依赖,一直有若干中方法可以绕过他,甚至由于它的存在衍生新的安全问题。

  7.cgi.fix_pathinfo,如果php以cgi方式安装,则需要关闭,避免出现文件解析问题。

  8.session.cookie_httponly,开启HttpOnly

  9.safe_mode,PHP的安全模式是否开启的争议一直很大。一方面,他会影响很多函数;另一方面,他又不停的被黑客们绕过,因此很难去设。

    共享环境下:建议开启,可以和disable_functions配合使用

    单独应用环境下:考虑关闭它,更多的依赖于disable_functions控制环境安全。

  10.disable_functions,能够在PHP中禁用函数。这是把双刃剑,禁用函数增加开发困难,禁用的太少有可能增加开发写出不安全代码的几率。

原文地址:https://www.cnblogs.com/wangxin201492/p/4171366.html