7 l* s/ s4 t: f0 s% G, w一.前言/思路 - r$ o$ z" p% x y, u2 N4 [! f ) T/ u% ^/ \/ ]- d6 _ 如果你看了angel的《SQL Injection with MySQL》一文,你有会发现一般的mysql+php的注射都是通过返回错误信息,和union联合查询替换原来查询语句中的字段而直接输出敏感信息,但是有的时候,主机设置为不显示错误信息:display_errors = Off 而且有的代码中sql查询后只是简单的对查询结果进行判断,而不要求输出查询结果,我们用上面的办法注射将一无所获。我们可以采用时间推延来进行判断注射了。2 E8 m; A. ?% e/ a
6 P8 N( w* `3 u$ H X p
本技术的主要思路:通过在构造的语句用加入执行时间推延的函数,如果我们提交的判断是正确的,那么mysql查询时间就出现推延,如果提交的判断是正确,将不会执行时间推延的函数,查询语句将不会出现推延。这样我们就可以进行判断注射。 5 l' v( f. s4 Q d! C% M / W8 b" P$ z# r. U0 ~二.关于BENCHMARK函数! F9 J; _8 g& W/ R2 i
5 J6 ~# F* n4 J& Z+ P
在MySQL参考手册里可以看到如下描叙: + w7 d+ c, |! V3 c- S
8 Y$ N/ K0 z/ p i* k' q: M" f" T5 M1 ~# b
-------------------------------------------------------------------------------- 8 W4 r2 p H1 l5 O% E" l& ? & e' e$ g; q& K- z/ u6 c" oBENCHMARK(count,expr) ; E$ m G" u/ {, g: K6 i# H/ a( w
BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。 & F& T9 o3 O# s6 cmysql> select BENCHMARK(1000000,encode("hello","goodbye")); " q2 w6 e8 F+ e
+----------------------------------------------+ 1 n4 P) x% t4 M: s" I" R; s7 q2 E| BENCHMARK(1000000,encode("hello","goodbye")) | 5 z; X( m/ `4 G( u) h9 l: \
+----------------------------------------------+ / ~4 \& ]% D* |4 U+ {| 0 | : {' G% w. n, t6 I/ h0 |
+----------------------------------------------+ " m% C( U2 ?; ` c. E- P
1 row in set (4.74 sec) & J( h- E1 t6 W) F' P4 |& P% E1 P! ]
2 Z) E; ]% s. V9 R l报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。 ; {( K' B" j4 c. | 5 v' K5 n! P& @$ e) D - M# E& H% Q, o--------------------------------------------------------------------------------# V% p F. z ^" G1 @
( B7 \3 g2 v- [8 ^& f9 |) h 只要我们把参数count 设置大点,那么那执行的时间就会变长。下面我们看看在mysql里执行的效果: . f. ^7 Y6 e ?6 u! C