渗透测试之SQL注入(1)

前言

     不管用什么语言编写的Web应用,它们都用一个共同点,具有交互性并且多数是数据库驱动。在网络中,数据库驱动的Web应用随处可见,由此而存在的SQL注入是影响企业运营且最具破坏性的漏洞之一。

 

一、基本介绍
     结构化查询语言(StructuredQueryLanguage,缩写:SQL),是一种特殊的编程语言,用于数据库中的标准数据查询语言。1986年10月,美国国家标准学会对SQL进行规范后,以此作为关系式数据库管理系统的标准语言(ANSIX3.135-1986),1987年得到国际标准组织的支持下成为国际标准。不过各种通行的数据库系统在其实践过程中都对SQL规范作了某些编改和扩充。所以,实际上不同数据库系统之间的SQL不能完全相互通用。
SQL注入(SQLInjection)是一种常见的web安全漏洞,攻击者利用这个问题,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击。

 

二、产生原因

SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。

      根据相关技术原理,SQL注入可以分为平台层注入和代码层注入。前者由不安全的数据库配置或数据库平台的漏洞所致;后者主要是由于程序员对输入未进行细致地过滤,从而执行了非法的数据查询。基于此,SQL注入的产生原因通常表现在以下几方面:①不当的类型处理;②不安全的数据库配置;③不合理的查询集处理;④不当的错误处理;⑤转义字符处理不合适;⑥多个提交处理不当。

 

三、类型分类

SQL注入类型大致可以分为三类

1. 从注入手法分类可以分为:联合查询注入、报错型注入、布尔型注入、延时注入、堆叠注入;

2. 从数据类型上可以分为:字符型(即输入的输入使用符号进行过滤)、数值型(即输入的输入未使用符号进行过滤)

3.从注入位置可以分类为:GET数据(提交数据方式为GET,大多存在地址栏)、POST数据(提交数据方式为POST,大多存在输入框中)、HTTP头部(提交数据方式为HTTP头部)、cookie数据(提交数据方式为cookie)。

 

四、产生危害

SQL注入漏洞常见且危害性大,具体表现为:

绕过登录验证,使用万能密码登录网站后台等

获取敏感数据,获取网站管理员帐号、密码等

文件系统操作,列目录,读取、写入文件等

注册表操作,读取、写入、删除注册表等

执行系统命令,远程执行命令

 

五、举例

1.联合查询注入

其中最重要的是页面要有显示位,即爆出来的库信息能在页面上当作正常数据显示出来。然后爆出来的库信息要放在select后相应的位置。下面是操作步骤:

首先判断闭合类型

 ?id=1' and 1=1 --

     ?id=1' and 1=2 --

        如果显示不同,所以要单引号闭合,其次判断显示位数

        ?id=-1' order by 4 --

        最后进行联合查询注入,把显示位的数字替换为database()

  http://localhost/sqli-labs-master/Less-1/?id=-1' union select 1,2,database() -- 

    2.报错型注入

        使用检测闭合类型的方法发现关有报错信息,可以实现报错注入,下面是常见的注入步骤:

         测试闭合类型为单引号闭合

 

        输入报错注入的函数

http://localhost/sqli-labs-master/Less-5/?id=1' and extractvalue(1,concat(0x7e,database(),0x7e)) --

        报错函数不单单只有extractvalue,还有updatexml和floor,下面我们说明一下使用情况和方法

extractvalue函数:extractvalue(1,2)在xml文档中提取相应的值,第一个数值表示xml字符串,第二个是xml路径。注入的时候,使用的方式大概为?id=1 and extractvalue(111,'~sdfggfds'),发现第二位的属于会在报错代码中显示。使用的限制为对mysql版本有要Mysql5.0 以上才能使用函数。

UpdateXml函数:该函数共有三个参数,第一个参数是XML文档对象的名称,第二个参数是xml路径,第三个参数是String格式替换查找到的符合条件的数据。注入的时候,使用的方式大概为id=1 and updatexml(1,concat(0x7e,(查询的内容),0x7e),1),使用的限制为对mysql版本有要Mysql5.0 以上才能使用函数。

Floor函数:注入的时候,使用的方式大概为?id=1 and (select 1 from (select count(*),concat((select 查询的内容 from information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a) -- ,且适应任何mysql版本。

 

  3.延时注入

使用sleep函数进行延时查询闭合方式sleep()函数可以让页面延迟运行一段时间。输入?id=1' and sleep(10) --+发现页面会有延时,则说明闭合方式为单引号闭合,使用if函数判断数据库长度范围,数据库函数if(表达式,1,2)如果表达式成立输出1,不成立输出2,输入?id=1' and if(length(database())=8,sleep(10),0) -- 进行测试。最后使用ASCII码进行获取首字母,?id=1' and if(ascii(substr(database(),1,1))=115,sleep(5),0) -- ,执行时发现有延时则说明测试的ASCII对应刚好就是115。

     4.堆叠注入

 

 在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。

 

六、防御方法

防止注入漏洞需要将数据与命令语句、查询语句分隔开来。

• 最佳选择是使用安全的API,完全避免使用解释器,或提供参数化界面的接口,或迁移到ORM或实体框架。

注意:当参数化时,存储过程仍然可以引入SQL注入,如果PL/SQL或T-SQL将查询和数据连接在一起,或者执行带有立即执行或exec()的恶意数据。

• 使用正确的或“白名单”的具有恰当规范化的输入验证方法同样会有助于防止注入攻击,但这不是一个完整的防御,因为许多应用程序在输入中需要特殊字符,例如文本区域或移动应用程序的API。

• 对于任何剩余的动态查询,可以使用该解释器的特定转义语法转义特殊字符。

注意:SQL结构,比如:表名、列名等无法转义,因此用户提供的结构名是非常危险的。这是编写软件中的一个常见问题。

• 在查询中使用LIMIT和其他SQL控件,以防止在SQL注入时大量地泄露记录。

posted @ 2020-03-23 15:25  Underwate  阅读(485)  评论(0编辑  收藏  举报