返回介绍

1.3 PHP 核心配置详解

发布于 2024-10-11 22:07:41 字数 7067 浏览 0 评论 0 收藏 0

代码在不同环境下执行的结果也会大有不同,可能就因为一个配置问题,导致一个非常高危的漏洞能够利用;也可能你已经找到的一个漏洞就因为你的配置问题,导致你鼓捣很久都无法构造成功的漏洞利用代码。然而,在不同的 PHP 版本中配置指令也有不一样的地方,新的版本可能会增加或者删除部分指令,改变指令默认设置或者固定设置指令,因此我们在代码审计之前必须要非常熟悉 PHP 各个版本中配置文件的核心指令,才能更高效地挖掘到高质量的漏洞。

我们在阅读 PHP 官方配置说明( http://www.php.net/manual/zh/ini.list.php )之前需要了解几个定义值,即 PHP_INI_*常量的定义,参见表 1-1。

表 1-1 PHP_INI_*常量的定义

PHP 配置文件指令多达数百项,为了节省篇幅,这里不一一对每个指令进行说明,只列出会影响 PHP 脚本安全的配置列表以及核心配置选项。

1.register_globals(全局变量注册开关)

该选项在设置为 on 的情况下,会直接把用户 GET、POST 等方式提交上来的参数注册成全局变量并初始化值为参数对应的值,使得提交参数可以直接在脚本中使用。register_globals 在 PHP 版本小于等于 4.2.3 时设置为 PHP_INI_ALL,从 PHP 5.3.0 起被废弃,不推荐使用,在 PHP 5.4.0 中移除了该选项。

当 register_globals 设置为 on 且 PHP 版本低于 5.4.0 时,如下代码输出结果为 true。

测试代码:

<?php

if ( $user=='admin' ) {

echo 'true' ; 

//do something

}

执行结果如图 1-6 所示。

图 1-6

2.allow_url_include(是否允许包含远程文件)

这个配置指令对 PHP 安全的影响不可小觑。在该配置为 on 的情况下,它可以直接包含远程文件,当存在 include($var)且$var 可控的情况下,可以直接控制$var 变量来执行 PHP 代码。allow_url_include 在 PHP 5.2.0 后默认设置为 off,配置范围是 PHP_INI_ALL。与之类似的配置有 allow_url_fopen,配置是否允许打开远程文件,不过该参数对安全的影响没有 allow_url_include 大,故这里不详细介绍。

配置 allow_url_include 为 on,可以直接包含远程文件。测试代码如下:

<?php

include $_GET['a'] ;

测试截图如图 1-7 所示。

3.magic_quotes_gpc(魔术引号自动过滤)

magic_quotes_gpc 在安全方面做了很大的贡献,只要它被开启,在不存在编码或者其他特殊绕过的情况下,可以使得很多漏洞无法被利用,它也是让渗透测试人员很头疼的一个东西。当该选项设置为 on 时,会自动在 GET、POST、COOKIE 变量中的单引号(')、双引号(")、反斜杠(\)及空字符(NULL)的前面加上反斜杠(\),但是在 PHP 5 中 magic_quotes_gpc 并不会过滤$_SERVER 变量,导致很多类似 client-ip、referer 一类的漏洞能够利用。在 PHP 5.3 之后的不推荐使用 magic_quotes_gpc,PHP 5.4 之后干脆被取消,所以你下载 PHP 5.4 之后的版本并打开配置文件会发现找不到这个配置选项。在 PHP 版本小于 4.2.3 时,配置范围是 PHP_INI_ALL;在 PHP 版本大于 4.2.3 时,是 PHP_INI_PERDIR。

图 1-7

测试代码如下:

<?php

echo $_GET['seay'] ;

测试结果如图 1-8 所示。

图 1-8

4.magic_quotes_runtime(魔术引号自动过滤)

magic_quotes_runtime 也是自动在单引号(')、双引号(")、反斜杠(\)及空字符(NULL)的前面加上反斜杠(\)。它跟 magic_quotes_gpc 的区别是,处理的对象不一样,magic_quotes_runtime 只对从数据库或者文件中获取的数据进行过滤,它的作用也非常大,因为很多程序员只对外部输入的数据进行过滤,却没有想过从数据库获取的数据同样也会有特殊字符存在,所以攻击者的做法是先将攻击代码写入数据库,在程序读取、使用到被污染的数据后即可触发攻击。同样,magic_quotes_runtime 在 PHP 5.4 之后也被取消,配置范围是 PHP_INI_ALL。

有一个点要记住,只有部分函数受它的影响,所以在某些情况下这个配置是可以绕过的,受影响的列表包括 get_meta_tags()、file_get_contents()、file()、fgets()、fwrite()、fread()、fputcsv()、stream_socket_recvfrom()、exec()、system()、passthru()、stream_get_contents()、bzread()、gzfile()、gzgets()、gzwrite()、gzread()、exif_read_data()、dba_insert()、dba_replace()、dba_fetch()、ibase_fetch_row()、ibase_fetch_assoc()、ibase_fetch_object()、mssql_fetch_row()、mssql_fetch_object()、mssql_fetch_array()、mssql_fetch_assoc()、mysqli_fetch_row()、mysqli_fetch_array()、mysqli_fetch_assoc()、mysqli_fetch_object()、pg_fetch_row()、pg_fetch_assoc()、pg_fetch_array()、pg_fetch_object()、pg_fetch_all()、pg_select()、sybase_fetch_object()、sybase_fetch_array()、sybase_fetch_assoc()、SplFileObject::fgets()、SplFileObject::fgetcsv()、SplFileObject::fwrite()。

测试代码如下:

# 文件 1.txt

1'2"3\4

# 文件 1.php

<?php

ini_set ( "magic_quotes_runtime" , "1" ); 

echo file_get_contents ( "1.txt" );

测试结果如图 1-9 所示。

5.magic_quotes_sybase(魔术引号自动过滤)

magic_quotes_sybase 指令用于自动过滤特殊字符,当设置为 on 时,它会覆盖掉 magic_quotes_gpc=on 的配置,也就是说,即使配置了 gpc=on 也是没有效果的。这个指令与 gpc 的共同点是处理的对象一致,即都对 GET、POST、Cookie 进行处理。而它们之前的区别在于处理方式不一样,magic_quotes_sybase 仅仅是转义了空字符和把单引号(')变成了双引号('')。与 gpc 相比,这个指令使用得更少,它的配置范围是 PHP_INI_ALL,在 PHP 5.4.0 中移除了该选项。

图 1-9

测试代码如下:

<?php

echo $_GET['a'] ;? >

执行结果如图 1-10 所示。

图 1-10

6.safe_mode(安全模式)

安全模式是 PHP 内嵌的一种安全机制,当 safe_mode=on 时,联动可以配置的指令有 safe_mode_include_dir、safe_mode_exec_dir、safe_mode_allowed_env_vars、safe_mode_protected_env_vars。safe_mode 指令的配置范围为 PHP_INI_SYSTEM,PHP 5.4 之后被取消。

这个配置会出现下面限制:

1)所有文件操作函数(例如 unlink()、file() 和 include())等都会受到限制。例如,文件 a.php 和文件 c.txt 的文件所有者是用户 a,文件 b.txt 的所有者是用户 b 并且与文件 a.php 不在属于同一个用户的文件夹中,当启用了安全模式时,使用 a 用户执行 a.php,删除文件 c.txt 可成功删除,但是删除文件 b.php 会失败。对文件操作的 include 等函数也一样,如果有一些脚本文件放在非 Web 服务启动用户所有的目录下,需要利用 include 等函数来加载一些类或函数,可以使用 safe_mode_include_dir 指令来配置可以包含的路径。

2)通过函数 popen()、system() 以及 exec() 等函数执行命令或程序会提示错误。如果我们需要使用一些外部脚本,可以把它们集中放在一个目录下,然后使用 safe_mode_exec_dir 指令指向脚本的目录。

下面是启用 safe_mode 指令时受影响的函数、变量及配置指令的完整列表:

apache_request_headers()、ackticks()、hdir()、hgrp()、chmode()、chown()、copy()、dbase_open()、dbmopen()、dl()、exec()、filepro()、filepro_retrieve()、ilepro_rowcount()、fopen()、header()、highlight_file()、ifx_*、ingres_*、link()、mail()、max_execution_time()、mkdir()、move_uploaded_file()、mysql_*、parse_ini_file()、passthru()、pg_lo_import()、popen()、posix_mkfifo()、putenv()、rename()、zmdir()、set_time_limit()、shell_exec()、show_source()、symlink()、system()、touch()。

安全模式下执行命令失败的提示,如图 1-11 所示。

图 1-11

7.open_basedir PHP 可访问目录

open_basedir 指令用来限制 PHP 只能访问哪些目录,通常我们只需要设置 Web 文件目录即可,如果需要加载外部脚本,也需要把脚本所在目录路径加入到 open_basedir 指令中,多个目录以分号(;)分割。使用 open_basedir 需要注意的一点是,指定的限制实际上是前缀,而不是目录名。例如,如果配置 open_basedir=/www/a,那么目录/www/a 和/www/ab 都是可以访问的。所以如果要将访问仅限制在指定的目录内,请用斜线结束路径名。例如设置成:open_basedir=/www/a/。

当 open_basedir 配置目录后,执行脚本访问其他文件都需要验证文件路径,因此在执行效率上面也会有一定的影响。该指令的配置范围在 PHP 版本小于 5.2.3 时是 PHP_INI_SYSTEM,在 PHP 版本大于等于 5.2.3 是 PHP_INI_ALL。

8.disable_functions(禁用函数)

在正式的生产环境中,为了更安全地运行 PHP,也可以使用 disable_functions 指令来禁止一些敏感函数的使用。当你想用本指令禁止一些危险函数时,切记要把 dl() 函数也加到禁止列表,因为攻击者可以利用 dl() 函数来加载自定义的 PHP 扩展以突破 disable_functions 指令的限制。

本指令配置范围为 php.ini only。配置禁用函数时使用逗号分割函数名,例如:disable_functions=phpinfo,eval,passthru,exec,system。

9.display_errors 和 error_reporting 错误显示

display_errors 表明是否显示 PHP 脚本内部错误的选项,在调试 PHP 的时候,通常都把 PHP 错误显示打开,但是在生产环境中,建议关闭 PHP 错误回显,即设置 display_errors=off,以避免带来一些安全隐患。在设置 display_errors=on 时,还可以配置的一个指令是 error_reporting,这个选项用来配置错误显示的级别,可使用数字也可使用内置常量配置,数字格式与常量格式的详细信息如表 1-2 所示。

表 1-2 数字格式与常量格式

这两个指令的配置范围都是 PHP_INI_ALL。

会影响到安全的指令大致就介绍到这里,表 1-3 列出一些常用指令以及对应的说明。

表 1-3 常用指令及说明

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文