1、研究缓冲区溢出的原理,至少针对两种数据库进行差别化研究php
1.1 原理mysql
在计算机内部,输入数据一般被存放在一个临时空间内,这个临时存放的空间就被称为缓冲区,缓冲区的长度事先已经被程序或者操做系统定义好了。向缓冲区内填充数据,若是数据的长度很长,超过了缓冲区自己的容量,那么数据就会溢出存储空间,而这些溢出的数据还会覆盖在合法的数据上,这就是缓冲区和缓冲区溢出的道理。linux
1.2 对抗缓冲区溢出攻击程序员
为了在系统中插入攻击代码,攻击者不但要插入代码,还要插入指向这段代码的指针,这个指针也是攻击字符串的一部分。产生这个指针须要知道这个字符串放置的栈地址。在过去,程序的栈地址很是容易预测,在不一样的机器之间,栈的位置是至关固定的。
栈随机化的思想使得栈的位置在程序每次运行时都有变化。所以,即便许多机器都运行相同的代码。它们的栈地址都是不一样的。
实现的方式是:程序开始时,在栈上分配一段0--n字节之间的随机大小空间。程序不使用这段空间,可是它会致使程序每次执行时后续的栈位置发生了变化。web
在Linux系统中,栈随机化已经变成了标准行为。(在linux上每次运行相同的程序,其同一局部变量的地址都不相同)sql
在C语言中,没有可靠的方法来防止对数组的越界写,可是,咱们可以在发生了越界写的时候,在没有形成任何有害结果以前,尝试检测到它。
最近的GCC版本在产生的代码中加入了一种栈保护者机制,用来检测缓冲区越界,其思想是在栈中任何局部缓冲区与栈状态之间存储一个特殊的金丝雀值。这个金丝雀值是在程序每次运行时随机产生的,所以,攻击者没有简单的办法知道它是什么。
在恢复寄存器状态和从函数返回以前,程序检查这个金丝雀值是否被该函数的某个操做或者函数调用的某个操做改变了。若是是,那么程序异常终止。数据库
限制那些可以存放可执行代码的存储器区域。在典型的程序中,只有保存编译器产生的代码的那部分存储器才须要是可执行的,其余部分能够被限制为只容许读和写。
如今的64位处理器的内存保护引入了”NX”(不执行)位。有了这个特性,栈能够被标记为可读和可写,可是不可执行,检查页是否可执行由硬件来完成,效率上没有损失。编程
1.3 数据库后端
MySQL是一款开放源代码关系型数据库系统。数组
MySQL包含的mysql_real_connect()函数不充分检查用户提供的参数值,本地或远程攻击者能够利用这个漏洞进行缓冲区溢出攻击,可能用来破坏数据库或执行任意指令。
攻击者能够利用SQL注入攻击,或者可上传恶意脚本到服务器上,经过传递超长的字符串做为mysql_real_connect()函数参数,可触发溢出,精心构建提交数据可能以数据库进程权限在系统上执行任意指令。
2、针对不一样数据类型,研究SQL注入点的发现与注入技术
2.1 sql注入
SQL注入攻击经过构建特殊的输入做为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,经过执行SQL语句进而执行攻击者所要的操做。
SQL注入便是指web应用程序对用户输入数据的合法性没有判断,攻击者能够在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,以此来实现欺骗数据库服务器执行非受权的任意查询,从而进一步获得相应的数据信息。
● SQL注入威胁表现形式能够体现为如下几点:
绕过认证,得到非法权限 猜解后台数据库所有的信息 注入能够借助数据库的存储过程进行提权等操做
● SQL注入攻击的典型手段:
判断应用程序是否存在注入漏洞 收集信息、并判断数据库类型 根据注入参数类型,重构SQL语句的原貌 猜解表名、字段名 获取帐户信息、攻击web或为下一步攻击作准备
● 注入方法
当输入的参 x 为整型时,一般 abc.php 中 Sql 语句类型大体以下:
select * from <表名> where id = x
这种类型可使用经典的 and 1=1 和 and 1=2 来判断:
Url 地址中输入 http://xxx/abc.php?id= x and 1=1页面依旧运行正常,继续进行下一步。
Url 地址中继续输入http://xxx/abc.php?id= x and 1=2 页面运行错误,则说明此 Sql 注入为数字型注入。
当输入的参 x 为字符型时,一般 abc.php 中 SQL 语句类型大体以下:
select * from <表名> where id = 'x'
这种类型咱们一样可使用and '1'='1 和 and '1'='2 来判断:
Url 地址中输入http://xxx/abc.php?id= x' and '1'='1 页面运行正常,继续进行下一步。
Url 地址中继续输入http://xxx/abc.php?id= x' and '1'='2页面运行错误,则说明此 Sql 注入为字符型注入。
这是一种特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,通常在连接地址中有“keyword=关键字”,有的不显示的连接地址,而是直接经过搜索框表单提交。
此类注入点提交的 SQL 语句,其原形大体为:
select * from 表名 where 字段 like '%关键字%'
当咱们提交注入参数为“keyword='and[查询条件] and '%'=',则向数据库提交的完事SQL语句为:
select * from 表名 where 字段 like '%' and [查询条件] and '%'='%'
2.2 经过 LAMP 搭建 Sql 注入环境
2.2.1 Sql 注入示例一.猜解数据库
(1)以下图所示,先下载文件并解压运行:
(2)进入 Firefox 浏览器,输入网址 : localhost/dvwasql , 点击create/Reset Database建立数据库:
(3)进入登陆界面,默认用户名为:admin 密码为:password
(4)将 Security 级别调整为 low
(5)进入 SQL injection页面开始注入:
(6)先输入 1 ,查看回显 (URL中ID=1,说明php页面经过get方法传递参数):
(7)那实际上后台执行了什么样的Sql语句呢?点击 view source查看源代码 :
能够看到,实际执行的Sql语句是:
SELECT first_name, last_name FROM users WHERE user_id = '1';
咱们是经过控制参数Id的值来返回咱们须要的信息。若是咱们不按常理出牌,好比在输入框中输入 1' order by 1#,实际执行的Sql语句就会变成:
SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#`;(按照Mysql语法,#后面会被注释掉,使用这种方法屏蔽掉后面的单引号,避免语法错误)
这条语句的意思是查询users表中user_id为1的数据并按第一字段排行。
(8)输入 1' order by 1#和 1' order by 2#时都返回正常,当输入 1' order by 3#时,返回错误:
由此可知,users表中只有两个字段,数据为两列。
接下来咱们使用 union select联合查询继续获取信息。union 运算符能够将两个或两个以上 select 语句的查询结果集合合并成一个结果集合显示,即执行联合查询。须要注意在使用 union 查询的时候须要和主查询的列数相同,而咱们以前已经知道了主查询列数为 2,接下来就好办了。输入1' union select database(),user()#进行查询 :
实际执行的Sql语句是 :
SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),user()#`;
经过上图返回信息,咱们成功获取到:
同理咱们再输入 1' union select version(),@@version_compile_os#进行查询:
实际执行的Sql语句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select version(),@@version_compile_os#`;
(9)接下来咱们尝试获取 dvwa 数据库中的表名。
由经验咱们能够大胆猜想users表的字段为 user 和 password ,因此输入:1' union select user,password from users#进行查询:
2.2.2 Sql 注入实例二.验证绕过
(1)以下图所示,先下载文件并解压运行:
(2)进入 Firefox 浏览器,输入网址 : localhost/sql2 , 按照顺序,初始化数据:
(3)准备工做完成以后,咱们进入首页发现这是一个普通的登陆页面,只要输入正确的用户名和密码就能登陆成功。咱们先尝试随意输入用户名 123 和密码 123 登陆,发现提示错误。
(4)按照第一个实验的思路,咱们尝试在用户名中输入 123' or 1=1 #, 密码一样输入 123' or 1=1 # :
为何可以成功登录呢?由于实际执行的语句是:
select * from users where username='123' or 1=1 #' and password='123' or 1=1 #'
按照 Mysql 语法,# 后面的内容会被忽略,因此以上语句等同于(实际上密码框里不输入任何东西也同样):
select * from users where username='123' or 1=1
因为判断语句 or 1=1 恒成立,因此结果固然返回真,成功登陆。
(5)再尝试不使用 # 屏蔽单引号,采用手动闭合的方式:咱们尝试在用户名中输入 123' or '1'='1, 密码一样输入 123' or '1'='1 (不能少了单引号,不然会有语法错误):
实际执行的 Sql 语句是:
select * from users where username='123' or '1'='1' and password='123' or '1'='1`
两个 or 语句使 and 先后两个判断永远恒等于真,因此可以成功登陆。
3、研究缓冲区溢出的防范方法,至少针对两种编程语言进行差别化研究
根据缓冲区溢出攻击的步骤,可将经常使用的缓冲区溢出攻击检测技术分为如下3种类型:
3.1 基于输入字符串的检测方法
对输入的字符串进行检测,肯定其为溢出攻击字符串时采起阻拦措施,使攻击者没法注入攻击代码。通常有如下3 种方法构建溢出攻击字符串
3.2 基于保护堆栈中返回地址的检测方法
缓冲区溢出攻击最关键的步骤是要经过修改函数返回地址来改变程序的流程,所以,在函数调用返回前,经过检查返回地址是否被修改能够判断是否有缓冲区溢出攻击发生。
缓冲区溢出攻击占了远程网络攻击的绝大多数,这种攻击可使得一个匿名的Internet用户有机会得到一台主机的部分或所有的控制权。若是能有效地消除缓冲区溢出的漏洞,则很大一部分的安全威胁能够获得缓解。 目前有三种基本的方法保护缓冲区免受缓冲区溢出的攻击和影响:
(1)经过操做系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码
(2)强制写正确的代码的方法
(3)利用编译器的边界检查来实现缓冲区的保护,使得缓冲区溢出不可能出现,从而彻底消除了缓冲区溢出的威胁
4、至少使用两种数据库注入攻击工具
4.1 Sqlmap
Sqlmap是一个自动SQL 注入工具。其可胜任执行一个普遍的数据库管理系统后端指纹,检索DBMS数据库、usernames、表格、列、并列举整个DBMS信息。
Sqlmap提供转储数据库表以及MySQL、PostgreSQL、SQL Server服务器下载或上传任何文件并执行任意代码的能力。
4.2 tnscmd10g
容许咱们向Oracle数据库中注入命令
通常来讲,SQL注入通常存在于形如HTTP://xxx.xxx.xxx/abc.asp?id=XX等带有参数的ASP动态网页中,有时一个动态网页中可能只有一个参数,有时可能又N个参数,有时是整型参数,有时是字符串型参数,不能一律而论。总之只要是带有参数的动态网页且此网页访问了数据库,那么就有可能存在SQL注入。若是ASP程序员没有安全意识,不进行必要的字符过滤,存在SQL注入的可能性就很是大。至于如何防范SQL注入攻击:请参考
http://blog.csdn.net/testeralai/article/details/26478469