27
重燃PHP安全之火 作者:王文群 联系方式:[email protected]

Phpsecurity.ppt

Embed Size (px)

Citation preview

Page 1: Phpsecurity.ppt

重燃PHP安全之火

作者:王文群

联系方式:[email protected]

Page 2: Phpsecurity.ppt

目录

一.前言

二.php.ini的配置

三.magic_quotes_gpc的隐患

四.解码函数造成的防注入失效

五.变量覆盖

六.变量本身的key 七.一些危险的函数

八.不可忽略的细节

Page 3: Phpsecurity.ppt

一.前言

在许多人看来搞脚本的只是用啊D扫个点传个shell而已,但这种情况已经很少见了,随着国内web代码审计水平的提高,站长们开始放心的使用各种整站系统,一时感觉web从此远离危险,许多脚本爱好者也愈发感到这门技术的枯燥,今天的这篇文章源自于很久以前看的幻影旅团写的php高级代码审计技巧,加上自己的一些感悟,总结了大牛们探索出来的挖掘php漏洞的一些新视角,一些细节。本文将从php.ini的配置,魔术引号带来的安全隐患,解码函数造成的防注入失效,变量覆盖,变量本身的key等几个方面提供一些挖掘php代码漏洞的思路,希望能给大家带来些灵感。

Page 4: Phpsecurity.ppt

二.php.ini的配置

1.1 背景知识:

php.ini是php的配置文件,包涵了许多php的运行设置,在脚本中我们可用ini_set,ini_get,,ini_get_all,int_restore等函数对php.ini进行读取和设定.下面将介绍一些可能导致安全问题的参数:

Page 5: Phpsecurity.ppt

1.2 short_open_tag 1)该选项用来设定php是否支持<? ?>这样的缩写形式:

Page 6: Phpsecurity.ppt

2)首先介绍一下apache日志包涵漏洞,该漏洞由include函数参数未过滤所引起的本地包含漏洞和short_open_tag=on导致,在apache的日志中记录了服务器所接受的url请求,这样我们就可以构造一个恶意的url请求再配合include本地包含漏洞写入我们的一句话.(所谓的一句话就是这样一段php代码:<?php eval($_POST[cmd])?>),但问题出现了,语句中的空格经过url编码后变为%20,这样服务器就不能解析我们的一句话了,但若是short_open_tag开启的话,我们可以这样构造一句话:<?/**/eval($_POST[cmd])?>,如果像这样构造一句话会报错: <?php/**/eval($_POST[cmd])?>,下面请看测试过程:

Page 7: Phpsecurity.ppt

第一步提交包涵一句话的url:

第二步构造一个包涵漏洞的php文件:

第三布利用这个存在包涵漏洞的php文件写入shell:

Page 8: Phpsecurity.ppt

1.3 register_globals 1)该选项用来设定是否开启自动注册全局变量

Page 9: Phpsecurity.ppt

2)该选项的开启会带来许多隐患,这些隐患主要是由于为初始化变量的值所引发的,下面通过一个测试代码来看看:

Page 10: Phpsecurity.ppt

1.4 display_error和error_reporting 这两个选项用来设置错误提示是否开启和错误提示的等级,通常在开发的过程中可以将error_reporting设置为e_all,这样方便调试。但在站点配置时,最好将错误信息屏蔽,可以这样设置display_error=Off,error_reporting(0),这样攻击者便无法从错误信息中获取有用的信息。

Page 11: Phpsecurity.ppt

设置是否允许远程包含文件 allow_url_fopen

设置是否显示php版本信息 expose_php

设置禁止执行的函数 disable_functions

指定php脚本所能访问的目录,限制shell

open_basedir

安全模式,对命令执行,文件操作函数等有影响

Safe_mode

以下是其它一些配置选项:

Page 12: Phpsecurity.ppt

三.magic_quotes_gpc的隐患

2.1 双字节编码漏洞

在GBK编码中,汉字是用两个字节来表示的。

例如“中”字编码后为%D6%D0,在开启GPC后’被转义为\’,\的URL编码为%5C,这样我们只需要在参数前随便加上一个%??,那服务器便认为这是一个中文,这样\就被成功的编码入中文了。我们的’,也就逃脱了被转义的命运。

Page 13: Phpsecurity.ppt

2.2 引入‘\’后所带来的问题

1)可造成对mysql数据库的二次攻击。

在gpc开启后,*’变成*\’,但\是mysql的转义字符,存入数据库时又变为*’,这样便将’带入了数据库,若是程序员过分信任数据库中的数据,对于从数据库中取出的数据并未做任何过滤,那么这个单引号便可以为我们做很多事:像闭合前一个单引号进行注入,在写文件函数中写入一句话等

Page 14: Phpsecurity.ppt

2)\,这个符号本身也是个极具作用的符号,像windows中目录的跳转,倘若在\”

这样的情况前再加上一个\,便得到了以前的符号,这又会引发一些列其他的安全问题

Page 15: Phpsecurity.ppt

2.3 被魔术引号所遗忘的地方

1) $_SERVER变量

2) getenv()得到的变量(使用类似$_SERVER变量)

3) $HTTP_RAW_POST_DATA与PHP输入、输出流

4) 数据库操作容易忘记'的地方如:in()/limit/order by/group by

Page 16: Phpsecurity.ppt

四.解码函数造成的防注入失效

防注入程序的出现一定程度上缓解了无站不可注的尴尬情景,但随着变量在程序中层层传递,部分变量被“忽略”了,请看测试代码:

Page 17: Phpsecurity.ppt

类似的编码函数还有:

编码 URL 字符串 urlencode

解码已编码的 URL 字符串

urldecode

按照 RFC 1738 对 URL 进行编码

rawurlencode

对已编码的 URL 字符串进行解码

rawurldecode

使用 MIME base64 对数据进行编码

base64_encode

对使用 MIME base64 编码的数据进行解码

base64_decode

Page 18: Phpsecurity.ppt

五.变量覆盖

这个问题与php.ini中register_globals=off所带来问题类似,变量覆盖问题可能有以下两种情况造成:

4.1代码的逻辑问题 <?php //var.php?a=fuck $a='hi'; foreach($_GET as $key => $value) { $$key = $value; } print $a; ?> 这样a的值便成了fuck

Page 19: Phpsecurity.ppt

4.2 函数所带来的变量覆盖问题

下面实例是由estract函数所引发的变量覆盖问题:

Page 20: Phpsecurity.ppt

类似存在覆盖变量隐患的函数还有:

parse_str(),mb_parse_str(),import_request_variables()等

Page 21: Phpsecurity.ppt

六.变量本身的key

在web安全人员千方百计的封堵来自于value的危险时,却忽略了变量本身的key也同样极其危险。请看如下代码:

Page 22: Phpsecurity.ppt

倘若我们这样提交URL:

这样变引发了一个xss,倘若在include或是其他执行代码的函数中还有更大的发挥余地

Page 23: Phpsecurity.ppt

七.一些危险的函数

1.文件操作类函数:

fopen(),file(),readfile(),openfile()等对于这些函数所引用的参数一定要严加过滤,稍有不慎便可能造成源码泄露甚至直接写入shell.

2.执行命令类函数:

exec(),system()shell_exec()passthru()等函数能直接执行系统命令,这个杀伤力是毋庸置疑的

3.执行代码类函数:

eval(),preg_replace() 等函数能执行php代码

Page 24: Phpsecurity.ppt

在php中容易导致安全问题的函数还有一下这些:array_map()usort(), uasort(), uksort()array_filter()array_reduce()array_diff_uassoc(), array_diff_ukey()array_udiff(), array_udiff_assoc(), array_udiff_uassoc()array_intersect_assoc(), array_intersect_uassoc()array_uintersect(), array_uintersect_assoc(), array_uintersect_uassoc()array_walk(), array_walk_recursive()xml_set_character_data_handler()xml_set_default_handler()xml_set_element_handler()xml_set_end_namespace_decl_handler()xml_set_external_entity_ref_handler()xml_set_notation_decl_handler()xml_set_processing_instruction_handler()xml_set_start_namespace_decl_handler()xml_set_unparsed_entity_decl_handler()stream_filter_register()set_error_handler()register_shutdown_function()register_tick_function()

Page 25: Phpsecurity.ppt

八.不可忽略的细节

1. apache服务器的解析漏洞:1.php.rar被当成1.php解析,前提rar并未包括在mime types中

2. 反引号也能执行命令:“`” 3. 分号作为php语句的分隔符,改变程序执行流程

4. globals[]与global的区别

Page 26: Phpsecurity.ppt

总结

看了这些代码审计的新思路,我们是否应该思考如何扩充 属于自己的审计字典呢,我想大概从一下几方面努力吧:1.多阅读他人发掘的漏洞和EXP 2.多阅读php手册,扎实的基础才是根本 3.逆向php的实现代码 4.和开发者多交流。我想这样或许才能真正做好know it then hack it.

Page 27: Phpsecurity.ppt