通行证│用户名: 密码: 验证码: 验证码,看不清楚?请点击刷新验证码 爱心红客 电信网通铁通移动 在线
文章搜索:
热门搜索:红客 黑鹰 红客技术 安全动画 红客培训
首页 文章 软件 动画 资源 励志 论坛 邮箱 会员 军事 科技 博客 爱心红客 最近更新 800g资源
 业内新闻 漏洞公告 病毒公告 电脑知识 网络知识 菜鸟入门 攻防教程 黑客攻防 安全编程 工具使用 综合安全 个人安全 安全相关 Q Q安全 原创精华 红客人物 站内事件
您现在的位置: 爱国者安全网 >> 文章类 >> 安全防御 >> 安全相关 >> 文章正文
脚本安全的本质 PHP+MYSQL
责任编辑:酷酷の鱼   更新日期:2008-5-4
 

来源:网络

一  前言    问题的存在

    从代码级别上,也就是应用层次上考虑代码安全的话(也就是不考虑底层的语言本身等问题的漏洞),脚本安全问题就是函数和变量的问题。变量直接或者间接的接收用户不安全的的输入,由于php本身的特性,在php中更容易发现这种变量的混乱(很多php程序都用来定义以及初始化以及接收变量,可以直接在程序中使用$id这样的变量,初始化完全由php的设置来完成,如果稍不注意,就可能导致变量的混乱从而导致攻击)。
    变量接收不安全的输入之后,没有做恰当的过滤又用在不同的地方,就可能造成不同的危害。如果直接进入数据库然后显示给用户就会导致跨站脚本攻击,如果用在sql语句中就可能导致Sql注射攻击,这几种攻击都是是与具体的脚本语言无关的,在各种脚本语言里都可能存在。由于php的变量很灵活,这些有害的变量如果用在一些逻辑语句中,就会导致关键代码的跳过如身份验证失败和跳过一些变量的初始化从而导致程序逻辑混乱而产生其他漏洞。如果这个变量用在了危险的函数如include等等当中,当然就会出现文件包含漏洞,出现在fopen函数里就会可能产生写文件的漏洞,出现在mysql_query函数中就是Sql注射漏洞,eval以及preg_replace中可能导致代码的执行,出现在htmlspecia函数中可能导致出错而绝对路径泄露......变量出现的环境决定了它可能的危害。
    思考了问题的存在,那么如何从代码级别上检查这种漏洞呢?当然熟悉熟悉php语言是最基本的,也应该是抓住函数和变量,危险的函数里如果有变量那么请确定这个变量的来源,是否正确的初始化,初始化之后是否能被用户注入敏感字符,在进入函数前这些敏感的字符是否得到了彻底的清除。对于代码审核工作的难点可能就在于对变量来源的确定,这需要对php特性以及你所审核的代码的熟悉,但也并不是所有的变量的来源都清晰可见,可能一些初始化的代码并没有像想象中运行,一些变量里的东西可能也来自于你并不想他来的地方,还有一些变量可能来自于数据库或者系统的配置文件,但是很可能数据库和配置文件在之前就已经被修改,或者在后面不安全的操作了这些变量,这些变量也是不可相信的。下面我们就按照变量与函数的思路来思考脚本代码的安全。

二  变量来自哪里?

1   显示的输入

    叫变量来自哪里其实也就是说威胁来自哪里,只是从web上考虑的话,什么样的网站最安全?很明显,那些只提供静态Html页面的网站是最安全的,因为这样的网站不与浏览者进行任何交互,就好比打劫一个密不透风的银行,很难实现,但是对于一个大的论坛或者脚本程序就不一样了,你登陆的时候需要传递用户名和密码这些变量给服务器,甚至包括你登陆的Ip与浏览器等等都是程序抓取的对象,抓取一次与服务器交互的过程如发表帖子等等你就发现浏览器与服务器之间进行的数据传输,你可能看得见的包括提交的表单,地址栏参数等等,你看不见的包括Cookie,Http头都是提交数据也就是变量的地方。这些地方也是服务器处理数据最原始的入口。那么php程序是如何接受变量的呢?所有提交的变量都被php保存在了一些数组里,包括

$_GET
$_POST
$_COOKIE
$_FILES
$_SERVER

为了最初的方便与灵活,在php的设置里有这么个选项

register_globals

当这个选项为on的时候,上面出现的那些变量都会成为$GLOBALS中的一员,在脚本中都不需要再取得就可以直接使用,并且以

variables_order

的顺序覆盖。很多程序考虑到了register_globals为off的情况,于是在程序初始化的时候使用如下的代码:

@extract(daddslashes($_POST));
@extract(daddslashes($_GET));

这些代码起到了register_globals的作用,作用也是将POST和GET的内容释放出去做为全局变量,但是危险可能更大,后面会提到。

2    隐式的输入

    上面这些是最原始的,没有经过程序转换的数据,程序很多地方用到的变量都来自这里,但也不表示其他的地方没有变量传递过来,下面有一个数据传递的模式:


                                用户传递的数据===========>数据库===========>程序代码处理=======>程序代码


    这个模式的意思是用户的输入可能先进入了数据库,然后程序从数据库再取得这个输入送入某些危险的函数执行,一般的程序员都会有一个意识认为从数据库中取得的变量是安全的,但是事实并不如此,只要某些敏感字符最终送入到程序代码中,不管他中间停留在什么地方,都是危险的。与存储在数据库中类似的情况是,一些程序把用户的输入放到文件中,如缓存文件,然后在必要的时候从里面取得,如果太过相信这些地方来的变量,这样还是会导致问题的。


3    变量覆盖

    还有很多的时候,程序收到的变量很可能来自他不应该来的地方,譬如Dz的代码:

$magic_quotes_gpc = get_magic_quotes_gpc();
@extract(daddslashes($_POST));
@extract(daddslashes($_GET));
if(!$magic_quotes_gpc) {
        $_FILES = daddslashes($_FILES);
}

这样之后,你还觉得$_FILES是原来的$_FILES了么?如果我们建立一个_FILES的表单或者干脆在url里加上php?_FILES[]=ddddd,这样之后$_FILES已经完全被覆盖了,然后你代码里引用的$_FILES就不是原来的了,在Dz以前的版本中曾经出现过这个问题。这应该属于变量覆盖的问题,把初始化的那个文件放大来看看吧:

$magic_quotes_gpc = get_magic_quotes_gpc();
@extract(daddslashes($_POST));
@extract(daddslashes($_GET));
if(!$magic_quotes_gpc) {
        $_FILES = daddslashes($_FILES);
}

$charset = $dbcharset = '';
$plugins = $hooks = array();

require_once DISCUZ_ROOT.'./config.inc.php';
require_once DISCUZ_ROOT.'./include/db_'.$database.'.class.php';

if($attackevasive) {
        require_once DISCUZ_ROOT.'./include/security.inc.php';
}

这样貌似是没有问题的,但是满足一定的条件的话还是可能出问题,假设register_globals为on的话,我们进入全局的变量不只是$_GET和$_POST吧!包括$_COOKIE和$_FILES以及$_SERVER都是会在全局数组中产生变量的,通过上面的语句,我们提交一个php?_SERVER[PHP_SELF]就可以覆盖掉_SERVER数组,那么整个程序中的$_SERVER数组都是不可以相信的了。我也见过这样写的代码:

......
require_once ROOT_PATH.'inc/database_config.php';
require_once ROOT_PATH.'inc/dv_spacemain.php';
if(PHP_VERSION < '4.1.0') {
        $_GET = &$HTTP_GET_VARS;
        $_POST = &$HTTP_POST_VARS;
        $_COOKIE = &$HTTP_COOKIE_VARS;
        $_SERVER = &$HTTP_SERVER_VARS;
        $_ENV = &$HTTP_ENV_VARS;
        $_FILES = &$HTTP_POST_FILES;
        $_SESSION =& $HTTP_SESSION_VARS;
}

$magic_quotes_gpc = get_magic_quotes_gpc();
$register_globals = @ini_get('register_globals');
if(!$register_globals || !$magic_quotes_gpc) {
        @extract(i_addslashes($_POST));
        @extract(i_addslashes($_GET));
        @extract(i_addslashes($_COOKIE));
        if(!$magic_quotes_gpc) {
                $_FILES = i_addslashes($_FILES);
        }
}
......

同样是在系统初始化的地方,但是变量的释放是在

require_once ROOT_PATH.'inc/general_funcs.php';
require_once ROOT_PATH.'inc/dv_spacemain.php';

这些关键变量初始化之后,那么我们完全可以提交一个?$host=xxx.xxx.xxx.xxx这样的东西覆盖掉系统自己的数据库初始化文件里的数据库地址变量,然后就可以......

[1] [2] 下一页

  • 上一篇文章:
  • 下一篇文章: 没有了
  • 最近更新
    固顶文章 企业网络组建与维护班正式开课
    普通文章 瑞星公司05月04日发布 每日计算机病毒及木马播报
    普通文章 绝密!为WindowsXP系统设置一个隐形密码
    普通文章 脚本安全的本质 PHP+MYSQL
    普通文章 网络安全只需要对症下药 给自己系统设道安全防线
    推荐文章 推荐:揭开迅雷无种子也能BT下载之谜
    普通文章 对趋势科技等数万网站被攻击的分析
    普通文章 社会工程学入侵三部曲
    普通文章 用python修改注册表干掉360safe
    普通文章 Novell GroupWise客户端 HTML注入及拒绝服务漏洞
    热门文章
    普通文章黑客破解美总统参选人网站 并导向竞选对手网站
    普通文章"蠕虫"攻击韩总统府电脑 非机密资料遭泄露
    普通文章"灰鸽子"变种泛滥 给用户隐私安全带来隐患
    普通文章病毒"大胃王"可同时盗取多款网游账号
    普通文章微软承认 Windows提升权限安全漏洞 但未承诺修补
    普通文章微软Windows XP SP3向制造商发货 用户月底可下载
    普通文章Firefly媒体服务器Content-Length字段堆溢出漏洞
    普通文章MPlayer sdpplin_parse()函数 RTSP 整数溢出漏洞
    普通文章攻击木马--远程控制软件自身的漏洞你注意了吗
    普通文章用vbs写的短小精悍的字典生成器
    精彩专题