在计算机内部,输入数据一般被存放在一个临时空间内,这个临时存放的空间就被称为缓冲区,缓冲区的长度事先已经被程序或者操做系统定义好了。向缓冲区内填充数据,若是数据的长度很长,超过了缓冲区自己的容量,那么数据就会溢出存储空间,而这些溢出的数据还会覆盖在合法的数据上,这就是缓冲区和缓冲区溢出的道理。
一般,在栈中分配某个字节数组来保存一个字符串,可是字符串的长度超出了为数组分配的空间。C对于数组引用不进行任何边界检查,并且局部变量和状态信息,都存在栈中。这样,对越界的数组元素的写操做会破坏存储在栈中的状态信息。当程序使用这个被破坏的状态,试图从新加载寄存器或执行ret指令时,就会出现很严重的错误。php
void echo() { char buf[8] ; gets(buf) ; puts(buf) ; }
因为栈是向地地址增加的,数组缓冲区是向高地址增加的。故,长一些的字符串会致使gets覆盖栈上存储的某些信息。
随着字符串变长,下面的信息会被破坏:
输入的字符数量 被破坏的状态
0---7 无
8---11 保存的%ebx的值
12---15 保存的%ebp的值
16---19 返回地址
20+ caller中保存的状态
若是破坏了存储%ebp的值,那么基址寄存器就不能正确地恢复,所以调用者就不能正确地引用它的局部变量或参数。
若是破坏了存储的返回地址,那么ret指令会使程序跳转到彻底意想不到的地方。linux
缓冲区溢出的一个更加致命的使用就是让程序执行它原本不肯意执行的函数。这是一种最多见的经过计算机网络攻击系统安全的方法。一般,输入给程序一个字符串,这个字符串包含一些可执行代码的字节编码,称为攻击代码,另外还有一些字节会用一个指向攻击代码的指针覆盖返回地址。那么,执行ret指令的效果就是跳转到攻击代码。程序员
一般,使用gets或其余任何能致使存储溢出的函数,都不是好的编程习惯。不幸的是,不少经常使用库函数,包括strcpy、strcat、sprintf,都有一个属性——不须要告诉它们目标缓冲区的大小,就产生一个字节序列。web
一、栈随机化
为了在系统中插入攻击代码,攻击者不但要插入代码,还要插入指向这段代码的指针,这个指针也是攻击字符串的一部分。产生这个指针须要知道这个字符串放置的栈地址。在过去,程序的栈地址很是容易预测,在不一样的机器之间,栈的位置是至关固定的。
栈随机化的思想使得栈的位置在程序每次运行时都有变化。所以,即便许多机器都运行相同的代码。它们的栈地址都是不一样的。
实现的方式是:程序开始时,在栈上分配一段0--n字节之间的随机大小空间。程序不使用这段空间,可是它会致使程序每次执行时后续的栈位置发生了变化。sql
在Linux系统中,栈随机化已经变成了标准行为。(在linux上每次运行相同的程序,其同一局部变量的地址都不相同)shell
二、栈破坏检测
在C语言中,没有可靠的方法来防止对数组的越界写,可是,咱们可以在发生了越界写的时候,在没有形成任何有害结果以前,尝试检测到它。
最近的GCC版本在产生的代码中加入了一种栈保护者机制,用来检测缓冲区越界,其思想是在栈中任何局部缓冲区与栈状态之间存储一个特殊的金丝雀值。这个金丝雀值是在程序每次运行时随机产生的,所以,攻击者没有简单的办法知道它是什么。
在恢复寄存器状态和从函数返回以前,程序检查这个金丝雀值是否被该函数的某个操做或者函数调用的某个操做改变了。若是是,那么程序异常终止。数据库
三、限制可执行代码区域
限制那些可以存放可执行代码的存储器区域。在典型的程序中,只有保存编译器产生的代码的那部分存储器才须要是可执行的,其余部分能够被限制为只容许读和写。
如今的64位处理器的内存保护引入了”NX”(不执行)位。有了这个特性,栈能够被标记为可读和可写,可是不可执行,检查页是否可执行由硬件来完成,效率上没有损失。编程
刚刚讲过当咱们访问动态网页时, Web 服务器会向数据访问层发起 Sql 查询请求,若是权限验证经过就会执行 Sql 语句。后端
这种网站内部直接发送的Sql请求通常不会有危险,但实际状况是不少时候须要结合用户的输入数据动态构造 Sql 语句,若是用户输入的数据被构形成恶意 Sql 代码,Web 应用又未对动态构造的 Sql 语句使用的参数进行审查,则会带来意想不到的危险。数组
Sql 注入带来的威胁主要有以下几点:
一般状况下,可能存在 Sql 注入漏洞的 Url 是相似这种形式 :http://xxx.xxx.xxx/abcd.php?id=XX
对 Sql 注入的判断,主要有两个方面:
可能存在 Sql 注入攻击的 ASP/PHP/JSP 动态网页中,一个动态网页中可能只有一个参数,有时可能有多个参数。有时是整型参数,有时是字符串型参数,不能一律而论。总之只要是带有参数的 动态网页且此网页访问了数据库,那么就有可能存在 Sql 注入。若是程序员没有足够的安全意识,没有进行必要的字符过滤,存在SQL注入的可能性就很是大。
最为经典的单引号判断法:
在参数后面加上单引号,好比:
http://xxx/abc.php?id=1'
若是页面返回错误,则存在 Sql 注入。
缘由是不管字符型仍是整型都会由于单引号个数不匹配而报错。
注:若是未报错,不表明不存在 Sql 注入,由于有可能页面对单引号作了过滤,这时可使用判断语句进行注入
一般 Sql 注入漏洞分为 2 种类型:
其实全部的类型都是根据数据库自己表的类型所产生的,在咱们建立表的时候会发现其后总有个数据类型的限制,而不一样的数据库又有不一样的数据类型,可是不管怎么分经常使用的查询数据类型老是以数字与字符来区分的,因此就会产生注入点为什么种类型。
当输入的参 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 注入为数字型注入。
缘由以下:
当输入 and 1=1
时,后台执行 Sql 语句:
select * from <表名> where id = x and 1=1
没有语法错误且逻辑判断为正确,因此返回正常。
当输入and 1=2
时,后台执行 Sql 语句:
select * from <表名> where id = x and 1=2
没有语法错误可是逻辑判断为假,因此返回错误。
咱们再使用假设法:若是这是字符型注入的话,咱们输入以上语句以后应该出现以下状况:
select * from <表名> where id = 'x and 1=1' select * from <表名> where id = 'x and 1=2'
查询语句将 and 语句所有转换为了字符串,并无进行 and 的逻辑判断,因此不会出现以上结果,故假设是不成立的。
当输入的参 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 注入为字符型注入。
缘由以下:
当输入 and '1'='1时,后台执行 Sql 语句:
select * from <表名> where id = 'x' and '1'='1'
语法正确,逻辑判断正确,因此返回正确。
当输入 and '1'='2时,后台执行 Sql 语句:
select * from <表名> where id = 'x' and '1'='2'
语法正确,但逻辑判断错误,因此返回正确。
emsp;这是一种特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,通常在连接地址中有“keyword=关键字”,有的不显示的连接地址,而是直接经过搜索框表单提交。
此类注入点提交的 SQL 语句,其原形大体为:
select * from 表名 where 字段 like '%关键字%'
当咱们提交注入参数为“keyword='and[查询条件] and '%'=',则向数据库提交的完事SQL语句为:
select * from 表名 where 字段 like '%' and [查询条件] and '%'='%'
经过查找资料我对SQL注入有了一个大概得了解,也清楚了SQL注入的强大。sql注入经常使用技术有段还包括:
根据缓冲区溢出攻击的步骤, 可将经常使用的缓冲区溢出攻击检测技术分为如下 3 种类型:
对输入的字符串进行检测,肯定其为溢出攻击字符串时采起阻拦措施,使攻击者没法注入攻击代码。通常有如下3种方法构建溢出攻击字符串。以下图所示:
缓冲区大于 ShellCode 长度:
缓冲区小于 ShellCode 长度:
将 ShellCode 放在环境变量里:
第 1 种溢出攻击字符串适用于缓冲区大于 ShellCode 长度的状况; 第 2 种溢出攻击字符串通常用于缓冲区小于 ShellCode 长度的状况; 第 3 种方法是将 ShellCode 放在环境变量里,是目前较为经常使用的方法。
在第 1 种和第 2 种类型的溢出攻击字符串中 ShellCode 前都加了若干的 NOP指令, 由于这 2 种状况下 ShellCode 的地址没法肯定, 但只要返回地址指向 ShellCode 前的任一条NOP 指令, ShellCode 就能够执行,大大增长了 ShellCode 执行的可能性。这些 NOP指令称为 sledge 。其余单字节指令如 AAA 等也可构成 sledge 。所以缓冲区溢出攻击检测系统能够经过检查输入的字符串中是否含有大量 NOP等可构成 sledge 的指令来判断此字符串是不是溢出攻击字符串。不过这种方法并不适用于检测第 3 种类型的攻击。但这 3 种类型的攻
击字符串中都含有 ShellCode 。所以,肯定出 ShellCode 的基本特征 , 如不含有“ 0x00”,含有某些特殊的系统调用等, 而后利用人工智能、 模式匹配、 规则匹配等方法检查输入字符串中是否包含 ShellCode 也可检测出是否有缓冲区溢出攻击发生。这些检测均可以在入侵检测等外围防护系统中实现, 优势是实现较为简单, 不会增长被保护系统的开销; 缺点是漏报率较高,没法检测出无明显特征的溢出攻击字符串。
缓冲区溢出攻击最关键的步骤是要经过修改函数返回地址来改变程序的流程, 所以, 在函数调用返回前, 经过检查返回地址是否被修改能够判断是否有缓冲区溢出攻击发生。 该检测的实现能够经过在源码中插入一些约束和判断的模块, 而后在编译后的程序运行期间对有关变量和堆栈区域进行监控,检测是否有攻击发生。 StackGuard 和StackShield 就是这一类型的工具,它们都是 gcc 编译器的扩展工具,用于监控调用的函数返回地址是否正常。StackGuard 主要是在内存中的返回地址及缓冲区之间插入一个 “Canary ” 字, 如图所示。
在函数调用返回前经过检查 “Canary” 字来判断返回地址是否已经被修改, 若是这个 Canary的值被改变了, 说明可能有人正进行缓冲区溢出攻击, 程序会马上响应, 发送一则入侵警告消息, 而后中止工做。为防止攻击者构造 Canary”字, StackGuard 选用“终止符”和 “随机数”做为“ Canary”字的值。但因为“ Canary ”字所在的位置是固定的,所以也可能被绕过StackShield 对此做了改进, 建立了一个新的堆栈用于备份被保护函数的返回地址。 它在被保护函数开始处增长一段代码, 用来将函数返回地址拷贝到一张特殊的表中; 一样在被保护函数的结尾处也增长一段代码, 用来将函数返回地址从表中拷贝回堆栈。 从而保证函数正确返回。
若是攻击者成功注入攻击代码,并改变了程序的执行流程使指令的执行指针指向了ShellCode 的入口地址。 按照一次缓冲区攻击的 3 个步骤, 还须执行 ShellCode 来完成攻击目的。所以,经过检测是否有 ShellCode 运行能够检测是否发生缓冲区溢出攻击。攻击者既但愿 ShellCode 利用得到的权限启动一个交互式的 shell 进程来完成尽可能多的事情,又但愿 ShellCode 尽可能短小从而更加隐蔽,因此绝大多数 ShellCode 都会调用系统函数。 因为监视全部系统调用会耗费大量系统资源, 所以只对 ShellCode 经常使用的系统调用进行监视, 根据某些特征判断受监视的系统调用是否为非法调用就可肯定被保护系统是否遭到缓冲区溢出攻击。例如,若是发现系统调用的返回地址为堆栈,则可认为其为非法调用,由于不多有程序在堆栈上运行代码。
上面三种方法是针对如何检测已经发生的缓冲区漏洞, 方法虽然多, 可是相对比较麻烦, 因此咱们最好能从根本上防范它,防止缓冲区漏洞的发生。首先在编写程序过程当中, 程序员有责任和义务养成安全编程的思想, 应该熟悉那些可能会产生漏洞或需慎用的函数,清楚那些在编程中要当心使用的函数 ( 特别是在使用 C语言时 ) ,例如: gets() 、 strcpy() 等等。在软件测试阶段,要专门对程序中的每一个缓冲区做边界检查和溢出检测。可是,因为程序编写者的经验不足和测试工做不够全面、充分,目前还不可能彻底避免缓冲区溢出漏洞,所以这些漏洞在已经使用以及正在开发的软件中仍是有存在的可能,还须要在使用软件时,对它作实时的监测。
其次是使用安全语言编写程序, 应使用 Java等安全的语言编写程序, 由于 Java在对缓冲区进行操做时,有相应的边界检查,因此能够有效地防止缓冲区溢出漏洞的产生。可是, Java也并不是绝对安全, Java的解释器是用 C语言编写的,而 C并非一种安全的语言,因此 Java解释器仍是可能存在缓冲区溢出漏洞并受到攻击。最后能够经过改进编译器,它的主要思想是在编译器中增长边界检查以及保护堆栈的功能,使得含有漏洞的程序和代码段没法经过编译。 针对 gcc编译器的不少补丁就提供了这些功能,好比说 Stackguard 等等。
BSQL Hacker是由Portcullis实验室开发的,BSQL Hacker 是一个SQL自动注入工具(支持SQL盲注),其设计的目的是但愿能对任何的数据库进行SQL溢出注入。 BSQL Hacker的适用群体是那些对注入有经验的使用者和那些想进行自动SQL注入的人群。BSQL Hacker可自动对Oracle和MySQL数据库进行攻击,并自动提取数据库的数据和架构。
Sqlmap是一个自动SQL 注入工具。其可胜任执行一个普遍的数据库管理系统后端指纹,
检索DBMS数据库、usernames、表格、列、并列举整个DBMS信息。Sqlmap提供转储数据库表以及MySQL、PostgreSQL、SQL Server服务器下载或上传任何文件并执行任意代码的能力。
sqlsus是一个开放源代码的MySQL注入和接管工具,sqlsus使用perl编写并基于命令行界面。sqlsus能够获取数据库结构,注入你本身的SQL语句,从服务器下载文件,爬行web站点可写目录,上传和控制后门,克隆数据库等。