Upload
fantasy-zheng
View
302
Download
8
Embed Size (px)
Citation preview
目录
一.前言
二.php.ini的配置
三.magic_quotes_gpc的隐患
四.解码函数造成的防注入失效
五.变量覆盖
六.变量本身的key 七.一些危险的函数
八.不可忽略的细节
一.前言
在许多人看来搞脚本的只是用啊D扫个点传个shell而已,但这种情况已经很少见了,随着国内web代码审计水平的提高,站长们开始放心的使用各种整站系统,一时感觉web从此远离危险,许多脚本爱好者也愈发感到这门技术的枯燥,今天的这篇文章源自于很久以前看的幻影旅团写的php高级代码审计技巧,加上自己的一些感悟,总结了大牛们探索出来的挖掘php漏洞的一些新视角,一些细节。本文将从php.ini的配置,魔术引号带来的安全隐患,解码函数造成的防注入失效,变量覆盖,变量本身的key等几个方面提供一些挖掘php代码漏洞的思路,希望能给大家带来些灵感。
二.php.ini的配置
1.1 背景知识:
php.ini是php的配置文件,包涵了许多php的运行设置,在脚本中我们可用ini_set,ini_get,,ini_get_all,int_restore等函数对php.ini进行读取和设定.下面将介绍一些可能导致安全问题的参数:
1.2 short_open_tag 1)该选项用来设定php是否支持<? ?>这样的缩写形式:
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])?>,下面请看测试过程:
第一步提交包涵一句话的url:
第二步构造一个包涵漏洞的php文件:
第三布利用这个存在包涵漏洞的php文件写入shell:
1.3 register_globals 1)该选项用来设定是否开启自动注册全局变量
2)该选项的开启会带来许多隐患,这些隐患主要是由于为初始化变量的值所引发的,下面通过一个测试代码来看看:
1.4 display_error和error_reporting 这两个选项用来设置错误提示是否开启和错误提示的等级,通常在开发的过程中可以将error_reporting设置为e_all,这样方便调试。但在站点配置时,最好将错误信息屏蔽,可以这样设置display_error=Off,error_reporting(0),这样攻击者便无法从错误信息中获取有用的信息。
设置是否允许远程包含文件 allow_url_fopen
设置是否显示php版本信息 expose_php
设置禁止执行的函数 disable_functions
指定php脚本所能访问的目录,限制shell
open_basedir
安全模式,对命令执行,文件操作函数等有影响
Safe_mode
以下是其它一些配置选项:
三.magic_quotes_gpc的隐患
2.1 双字节编码漏洞
在GBK编码中,汉字是用两个字节来表示的。
例如“中”字编码后为%D6%D0,在开启GPC后’被转义为\’,\的URL编码为%5C,这样我们只需要在参数前随便加上一个%??,那服务器便认为这是一个中文,这样\就被成功的编码入中文了。我们的’,也就逃脱了被转义的命运。
2.2 引入‘\’后所带来的问题
1)可造成对mysql数据库的二次攻击。
在gpc开启后,*’变成*\’,但\是mysql的转义字符,存入数据库时又变为*’,这样便将’带入了数据库,若是程序员过分信任数据库中的数据,对于从数据库中取出的数据并未做任何过滤,那么这个单引号便可以为我们做很多事:像闭合前一个单引号进行注入,在写文件函数中写入一句话等
2)\,这个符号本身也是个极具作用的符号,像windows中目录的跳转,倘若在\”
这样的情况前再加上一个\,便得到了以前的符号,这又会引发一些列其他的安全问题
2.3 被魔术引号所遗忘的地方
1) $_SERVER变量
2) getenv()得到的变量(使用类似$_SERVER变量)
3) $HTTP_RAW_POST_DATA与PHP输入、输出流
4) 数据库操作容易忘记'的地方如:in()/limit/order by/group by
四.解码函数造成的防注入失效
防注入程序的出现一定程度上缓解了无站不可注的尴尬情景,但随着变量在程序中层层传递,部分变量被“忽略”了,请看测试代码:
类似的编码函数还有:
编码 URL 字符串 urlencode
解码已编码的 URL 字符串
urldecode
按照 RFC 1738 对 URL 进行编码
rawurlencode
对已编码的 URL 字符串进行解码
rawurldecode
使用 MIME base64 对数据进行编码
base64_encode
对使用 MIME base64 编码的数据进行解码
base64_decode
五.变量覆盖
这个问题与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
4.2 函数所带来的变量覆盖问题
下面实例是由estract函数所引发的变量覆盖问题:
类似存在覆盖变量隐患的函数还有:
parse_str(),mb_parse_str(),import_request_variables()等
六.变量本身的key
在web安全人员千方百计的封堵来自于value的危险时,却忽略了变量本身的key也同样极其危险。请看如下代码:
倘若我们这样提交URL:
这样变引发了一个xss,倘若在include或是其他执行代码的函数中还有更大的发挥余地
七.一些危险的函数
1.文件操作类函数:
fopen(),file(),readfile(),openfile()等对于这些函数所引用的参数一定要严加过滤,稍有不慎便可能造成源码泄露甚至直接写入shell.
2.执行命令类函数:
exec(),system()shell_exec()passthru()等函数能直接执行系统命令,这个杀伤力是毋庸置疑的
3.执行代码类函数:
eval(),preg_replace() 等函数能执行php代码
在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()
八.不可忽略的细节
1. apache服务器的解析漏洞:1.php.rar被当成1.php解析,前提rar并未包括在mime types中
2. 反引号也能执行命令:“`” 3. 分号作为php语句的分隔符,改变程序执行流程
4. globals[]与global的区别
总结
看了这些代码审计的新思路,我们是否应该思考如何扩充 属于自己的审计字典呢,我想大概从一下几方面努力吧:1.多阅读他人发掘的漏洞和EXP 2.多阅读php手册,扎实的基础才是根本 3.逆向php的实现代码 4.和开发者多交流。我想这样或许才能真正做好know it then hack it.