PHP+MySQL多语句履行[MySQL防范]
本文“PHP+MySQL多语句履行[MySQL防范]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
发动这个帖子,预计就很多人看到标题就表示不屑了.一向以来PHP+MySQL环境下,无论是写程序大概是注入攻击,是无法多语句履行的,这么广为人知的常识,没来由会有人不知道.
可声望就是用来被挑衅的,常识也就是为了被冲破的.假如没有一点创新性,追根到底的求知欲,一向在条条框框里挣扎,那还有什么争取安闲、解析世界的Hacker,Geek精神?
近来看到一个很简单的sql注入案例,固然漏洞很简单,但是此中包含的内容可大大差别.
亮点在于:作者竟然在注射操纵历程中利用了mysql的多语句履行.
感激作者@紫梦芊 ,让我们一向以来奉为金科玉律的信条被完好推翻.
本着Know it then hack it的设法,我细心研究了一下这一条“常识”是若何形成,又若何被作者冲破的.
从最早国内angel介绍的《SQL Injection with MySQL》&《Advanced SQL Injection with MySQL》这两篇文章开始,PHP+MySQL注入就一向逗留在UNION Select的基石上成立起来的.可Union select作为SQL Inj的办法,一向都有很多限制,比方需求猜字段数、猜表名,非select语句就无法利用union,注入点在order by大概group by语句后就很难举行操作,盲注对比复杂等等问题.
可为什么非要利用union select?除了昔时MySQL 3.x不支持子查询查询数据之外,主要缘由,在实践中发现注射中一样不能像mssql一样用分号来分割履行多个sql语句.为什么?因为PHP的 MySQL,MySQLi扩大,都因为安全缘由,在connect的时刻,都不答应设置CLIENT_MULTI_STATEMENTS,哪怕你手工在connect的时刻设置了这个flag,php在源代码级别,仍旧会帮你去撤除:
php-5.3.8/ext/mysqli/mysqli_nonapi.c
/* set some required options */
flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
/* remove some insecure options */
flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */
而没有这个特别的设置,MySQL是不答应在一个mysql_query中利用分号履行多语句的.于是,这也就是长期以来,大家都认为mysql是不允很多语句履行的根本缘由.实际上这恰好是个错误的熟习,实际上mysql早在4.1版本就允很多语句履行.只是PHP自身限制了这种用法.
而是不是PHP就完好无法利用多语句履行呢?答案能否,操纵mysqli_multi_query便可以履行多语句,但是实际利用中基本没有人会用这个语句.而另一个常被程序员所利用的PDO方法操作数据库,情形又若何?
create table `car`(`name` varchar(32), `type` varchar(32));
$db = new PDO("mysql:host=localhost:3306;dbname=test", 'root', '');
// works regardless of statements emulation
// $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
//
$sql = "DELETE FROM car; INSERT INTO car(name, type) VALUES ('car13', 'coupe'); INSERT INTO car(name, type) VALUES ('car2', 'coupe');";
//
try {
//$db->exec($sql);
$db->query($sql);
//$stmt = $db->prepare($sql);
//$stmt->execute();
}
catch(PDOException $e){
echo $e->getMessage();
die();
}
测试了一下,公然,以上这些多语句,在PDO的情形下,安然履行了.果断查找PHP源代码:
php-5.3.8/ext/mysqlnd/mysqlnd_enum_n_def.h
#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
php-5.3.8/ext/pdo_mysql/mysql_driver.c
#ifdef CLIENT_MULTI_STATEMENTS
|CLIENT_MULTI_STATEMENTS
公然,PHP源代码默许支持了多语句履行特点,已经在mysqlnd这个driver中定义了多语句履行的参数.
要知道,目前大都PHP的编程框架为了支持大都据库范例,基本城市利用PDO作为底层数据库衔接方法.这意味着什么?意味着在PDO的环境中,注入点是什么范例(insert,update,delete,select)已经不重要了,注入点在语句的什么位置也不重要了(table,where,orderby),一切大概性都重现了,mysql功效忽然全开放在我们眼前,都可以操纵多语句的方法,重新构造我们所需求的sql语句.
那能否操纵PDO利用这个就完好没有限制了呢?当然也不是.首先,普通框架利用PDO作为数据库衔接,常用的数据库操作,都是利用参数绑定大概 prepare的方法,举行参数绑定的.而在默许情形下,这种参数绑定是在php客户端举行的,在这种情形下,是不允很多语句的.只有以下办法:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
才可以操纵prepare履行多语句(因为参数绑定是在server端履行),而这种情况非常少见.
所以,真正可以操纵的多语句注射,只能是存在于操纵PDO衔接数据库,并直接利用exec大概query函数举行履行sql语句的地方.是不是太尖刻?其实这种例子并不少见,各位只要用心找,老是能找到的.
文末再次感激指导我探求缘由的漏洞作者@紫梦芊 ,以及@Laruence ,给我看PHP代码供应了不少帮忙
作者 GARY
以上是“PHP+MySQL多语句履行[MySQL防范]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |