【原创】MySQL Proxy - read_query_result()

15.7.4.8. Manipulating Results with read_query_result()


       read_query_result() 函数仅在你之前手动向 query 队列中添加了 query 的情况下,有结果集从服务器端返回的时候被调用。如果你没有对 query 队列进行过操作,该函数不会被调用。该函数仅具有一个入参,即结果包(在 Lua 脚本中可以认为该包对应的是 Injection 结构),其中包含了一系列属性:

  • id: 结果集 ID ,其对应于 当 query 包被客户端向服务器提交时使用 append(id) 函数对 query 队列操作时设置的 ID 值。你必须设置 resultset_is_needed 标志,以便当拦截到来自于服务器的返回结果集时,进行相应处理,之后再返回给客户端。参阅 proxy.queries 。
  • query: 原始 query 的文本内容。
  • query_time: 从 query 被发送到服务器,到接收到结果集的第一行时,所需要的微秒数。
  • response_time: 从 query 被发送到服务器,到接收到结果集的最后一行时,所需要的微秒数。
  • resultset: 结果集数据的内容。

       通过对来自 MySQL 服务器的返回结果信息的分析处理,可以提取出与你之前注入的 query 语句匹配的结果,并返回修改后的结果集(例如返回一个经过修改的 query 产生的结果),甚至创建属于你自己的结果集。


       下面的 Lua 脚本,将输出每一个发送到服务器的 query 对应的文本内容,以及 query 时间和 response 时间(即开始执行 query 的时刻和返回该 query 结果的时刻):


function read_query( packet )
        if packet:byte() == proxy.COM_QUERY then
                print("we got a normal query: " .. packet:sub(2))


                proxy.queries:append(1, packet )


                return proxy.PROXY_SEND_QUERY
        end
end


function read_query_result(inj)
        print("query-time: " .. (inj.query_time / 1000) .. "ms")
        print("response-time: " .. (inj.response_time / 1000) .. "ms")
end


       你可以通过 read_query_result() 函数获得返回结果中的 resultset 属性的 row 属性。例如,你可以使用下面的 Lua 代码段来递归显示返回结果中所有行的第一列内容:


for row in inj.resultset.rows do
        print("injected query returned: " .. row[1])
end


       正如 read_query() 函数一样,read_query_result() 函数能够根据返回结果的内容,按需返回结果的不同值。例如,如果你之前注入了额外的 query 到 query 队列中,然后在获取返回的结果集后,移除与额外 query 对应的结果,仅返回与客户端发送的原始 query 对应的结果。


       下面的例子注入额外的 SELECT NOW() 语句到 query 队列中,并设置了一个与原始 query 不同的 ID 值。在 read_query_result() 函数中,如果发现了与我们自己注入的 query 的 ID 相匹配的结果,我们将显示结果的行内容,然后通过 return proxy.PROXY_IGNORE_RESULT 语句使该结果不会被返回给客户端。如果结果是由任何其他 query 产生,则打印出 query 相应的时间信息,并返回默认值,即返回不做任何修改的结果集给客户端。我们同样可以显式地使用 return proxy.PROXY_IGNORE_RESULT 来将结果返回给 MySQL 客户端。


function read_query( packet )
        if packet:byte() == proxy.COM_QUERY then
                proxy.queries:append(2, string.char(proxy.COM_QUERY) .. "SELECT NOW()", {resultset_is_needed = true} )
                proxy.queries:append(1, packet, {resultset_is_needed = true})
                proxy.queries:append(2, string.char(proxy.COM_QUERY) .. "SELECT NOW()", {resultset_is_needed = true} )


                return proxy.PROXY_SEND_QUERY
        end
end




function read_query_result(inj)
        if inj.id == 2 then
                for row in inj.resultset.rows do
                        print("injected query returned: " .. row[1])
                end
                return proxy.PROXY_IGNORE_RESULT
        else
                print("query-time: " .. (inj.query_time / 1000) .. "ms")
                print("response-time: " .. (inj.response_time / 1000) .. "ms")
        end
end



转载于:https://my.oschina.net/moooofly/blog/111773

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值