CLIENT_MULTI_RESULTS

来源:互联网 发布:jsp和java的关系 编辑:程序博客网 时间:2024/06/05 12:48
其中的一个参数CLIENT_MULTI_RESULTS不明白是什么意思,google之,在mysql的官方主页上关于mysql提供的c接口的文档(http://dev.mysql.com/doc/refman/5.0/en/mysql-real-connect.html)里找到了这个参数和其他一些参数,我大概翻译了一下描述,如下:
Flag NameFlagDescriptionCLIENT_COMPRESSUse compression protocol.(使用压缩协议。)CLIENT_FOUND_ROWSReturn the number of found (matched) rows, not the number ofchanged rows.(返回找到(匹配)的行数,而不是改变了的行数。)CLIENT_IGNORE_SIGPIPEPrevents the client library from installing a SIGPIPE signal handler. This can be used to avoidconflicts with a handler that the application has alreadyinstalled.(阻止客户端库安装一个SIGPIPE信号处理器。这个可以用于当应用程序已经安装该处理器的时候避免与其发生冲突。CLIENT_IGNORE_SPACEAllow spaces after function names. Makes all functions namesreserved words.(允许在函数名后使用空格。所有函数名可以预留字。)CLIENT_INTERACTIVEAllow interactive_timeout seconds(instead of wait_timeout seconds) ofinactivity before closing the connection. The client's sessionwait_timeout variable is set tothe value of the session interactive_timeoutvariable.(允许使用关闭连接之前的不活动交互超时的描述,而不是等待超时秒数。客户端的会话等待超时变量变为交互超时变量。)CLIENT_LOCAL_FILESEnable LOAD DATA LOCAL handling.CLIENT_MULTI_RESULTSTell the server that the client can handle multiple result setsfrom multiple-statement executions or stored procedures. This flagis automatically enabled ifCLIENT_MULTI_STATEMENTS is enabled. See the notefollowing this table for more information about thisflag.(通知服务器客户端可以处理由多语句或者存储过程执行生成的多结果集。当打开CLIENT_MULTI_STATEMENTS时,这个标志自动的被打开。可以在本表后查看更多关于该标志位的信息。CLIENT_MULTI_STATEMENTSTell the server that the client may send multiple statements ina single string (separated by “;”). If this flag is not set,multiple-statement execution is disabled. See the note followingthis table for more information about this flag.(通知服务器客户端可以发送多条语句(由分号分隔)。如果该标志为没有被设置,多条语句执行。)CLIENT_NO_SCHEMADon't allow the db_name.tbl_name.col_name syntax.This is for ODBC. It causes the parser to generate an error if youuse that syntax, which is useful for trapping bugs in some ODBCprograms.(不允许“数据库名.表名.列名”这样的语法。这是对于ODBC的设置。当使用这样的语法时解析器会产生一个错误,这对于一些ODBC的程序限制bug来说是有用的。CLIENT_ODBCUnused.(不使用)CLIENT_SSLUse SSL (encrypted protocol). This option should not be set byapplication programs; it is set internally in the client library.Instead, usemysql_ssl_set() before calling mysql_real_connect().(使用SSL。这个设置不应该被应用程序设置,他应该是在客户端库内部是设置的。可以在调用mysql_real_connect()之前调用mysql_ssl_set()来代替设置。CLIENT_REMEMBER_OPTIONSRemember options specified by calls to mysql_options(). Without this option, ifmysql_real_connect() fails, you must repeatthemysql_options() calls before trying to connectagain. With this option, themysql_options() calls need not berepeated.(记住通过调用mysql_options()生成的设置。如果不使用这个设置,当mysql_real_connect失败时,再重新连接之前必须反复调用mysql_options()。当然,如果使用这个设置,就不必反复调用了。
   下面有对于CLIENT_MULTI_STATEMENTS的说明:
If you enable CLIENT_MULTI_STATEMENTSor CLIENT_MULTI_RESULTS, you shouldprocess the result for every call tomysql_query() or mysql_real_query() by using a loop that callsmysql_next_result() to determine whether there are moreresults. For an example, see Section 20.9.12, “C API Support for MultipleStatement Execution”.

如果打开了 CLIENT_MULTI_STATEMENTS或CLIENT_MULTI_RESULTS,你必须对每一个mysql_query()或者mysql_real_query()的调用结果通过一个循环来处理,在这个循环中,调用mysql_next_result()来决定(发现)是否有更多的结果,如Section 20.9.12,“C API Support for Multiple Statement Execution”


 PHP+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));
    <?php
    $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

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘金币能抵钱商家拿了淘金币怎么办 真实订单被系统判定虚假交易怎么办 淘宝买家号疑似虚假交易违规怎么办 货品交易一方收了定金违约了怎么办 饿了么店铺收到差评怎么办 淘宝顾客退款没成功给差评怎么办 身份证绑定了淘宝注册支付宝怎么办 把钱转错到支付宝账号被扣了怎么办 网上买东西收到信息被删掉了怎么办 表格在手机上显示不出来怎么办? 电子表格中复制后没有虚线框怎么办 word中页眉页脚横线短了怎么办 亿图图示画的图不显示怎么办 掌柜宝用了几天无法登录了怎么办 手机千牛消息不小心删除了怎么办 淘宝账号被冻结提示无法恢复怎么办 商家未发货我误点了确认收货怎么办 淘宝买货商家不发货也不退款怎么办 商家没发货点成收货了怎么办 淘宝新店上架产品未通过审核怎么办 安卓手机电池虚电怎么办_查查吧 拼多多拼单期间商家下架商品怎么办 微信绑别人的卡需要人脸认证怎么办 支付宝把钱转到了停用的账号怎么办 我注册征信账号忘记了要怎么办 客户说考虑考虑我该怎么办招商类 浴巾用久了黑黑的洗不干净怎么办 wifi密码被别人改了怎么办啊 苹果手机更新后账号密码忘了怎么办 专项预审批额度额度时效了怎么办 id密码和id码丢了怎么办 手机卡丢了id密码忘了怎么办 不想叫爱派登录我的微信怎么办 pr中素材与新建序列不匹配怎么办 淘宝客户收到货不承认要退款怎么办 淘宝包邮店铺 新疆地区拍怎么办 唯品会换货上门但自己寄了怎么办 闲鱼实名认证拍身份证不行怎么办 支付宝绑定的身份证过期了怎么办 实名认证的淘宝店铺被骗走了怎么办 移动宽带los灯亮红灯闪烁怎么办