sql注入原理基础(入门)
sql内重要的表(sql注入基石)
-
在Mysql 5.0以上版本,定义了information_schema数据库,用来存储数据库元信息。
其中schemata表中:schema_name用来存储数据库名. -
tables表中:table_schema和table_name分别用来存储数据库名和表名。
-
columns表中:table_schema(数据库名),table_name(表名),column_name(字段名)
sql注入就是在注入点(可以理解为应该输入数据的地方)输入了相关的sql命令,导致命令被执行的情况。
有了以上的表我们就可以通过命令来获取我们想要的信息。
集中常见的注入类型(包括实例)
整型注入(以ctfhub 技能树web中sql注入的整型注入为例)
题目输入1后,我们可以看到相关的sql语句
sele *from news where id =1
这是一个简单的sql查询语句,也是一个最基本的整型注入,当没有相关sql提示语句时,我们可以通过一下三个步骤判断该题存在整数型注入
- 加单引号
对应的sql:select * from table where id=3’ 这时sql语句出错,程序报错; - 加and 1=1
对应的sql:select * from table where id=3’ and 1=1 此时语句正常运行 - 加and 1=2
对应的sql:select * from table where id=3 and 1=2 语句可以正常执行,但是无法查询出结果
若以上三点都满足,则该题存在整数型注入
接下来是解题方法:
-
判断字段的数目
order by 在sql中通常用于排序,但在sql注入中通常用于判断字段的数目,如select * from news where id=1 order by 2
如果程序正常运行,当order by 3时程序报错,则说明数据库中只有两个字段
-
判断插入位置
select * from news where id=-1 union select 1,2
id后面一定是能让数据库报错的数
union select 是联合语句在执行 select * from news where id=-1后
又执行select 1,2语句,由于前半句报错不能回显不能正确显示,所以回显只显示后半句
-
获取数据库名和版本
select *from news where id=-1 union select database(),version()
database()和version()分别用于查看当前数据库和mysql版本
如果msql版本属于5.0版本则,我们可以通过前文所提到的information_schema中表来获取关键信息 -
获取所有库名
select * from news where id=-1 union select 1, group_concat(schema_name)from information_schema.schemata
group _concat()可以讲列中的所有信息给合在一起,
途中红框内就是我们所有的数据库 -
通过相同方法,我们可以用schemata表和tables表和columns表获取数据库中所有的表和字段的信息
这就是最基础的sql整型注入原理
字符型注入
字符型注入在整数型注入上由较少改动
整数型的sql查询语句为
selsect * from news where id =1
而字符型注入的查询语句 为
select * from news where id = ' 1 '
用户真正输入的内容为1,倘若输入sql语句则会被自动当作字符串,就不能起到我们输入的sql语句被运行的作用
此时我们需要用到注释符号
mysql中注释符号有- -,/* */,#
通过注释符号我们可以把后面的 ’ 给注释掉,例如:
select * from news where id ='1'#'
我们在输入框中输入的是1’#
这样就导致系统识别的sql语句为select * from news where id =‘1’
之后的注入步骤便与整型注入相同了,例如判断诸如点:
select * from news where id ='-1' union select 1,2 #'
报错注入
-
原理:
通常我们在sql注入时,并不会有相关内容的回显,我们只能看见输入正确或错误类的信息。所以用之前的sql注入我们无法获取我们想要的信息。此时我们可以的输入错误的sql语句,把自己想要的信息写入报错语句中,系统会将错误的地方给显示出来,从而实现报错注入
select * from news where id=-1 Union select count(*),concat(database(),0x26,floor(rand(0)*2))x
from information_schema.columns group by x;
最后会如图显示:
布尔盲注
- 原理:
有些时候在我们注入时,没有任何回显,不会返回任何信息。但是我们可以判断输入信息正确,会返回正确的页面,错误则返回错误的页面。
此时我们可以使用布尔盲注,例如select * from news where -1 union select 1,length(database())=3 //用来判断database()的长度,如果长度为3,则返回正确的页面 select * from news where -1 union select 1,ascll(substr(database(),1,1)=100 //用于判断database()的第一个字母的ascll码是否为100,使用ascll码的原因是方便python循环
在遇到布尔盲注时,由于我们只能一个一个地判断字符,人工输入很麻烦,通常搭配python脚本去做,在判断关键信息的字符时,通常使用ascll码去做,一是方便循环,二是可以使用二分法等算法,节省时间
时间盲注
-
原理
部分网页注入时,既不返回信息,也不报错,同时输入错误的注入信息也不会返回错误的页面,我们无法判断自己的sql语句是否正确在sql语句中sleep(n)函数的意思是在查询时等待n秒,利于这个函数,我们可以通过等待时间来判断我们注入的sql语句是否正确,例如
select * from news where -1 union select 1,if(length(database())=3,1,sleep(2)) //该代码的意思为:如果数据库的长度为3,则返回1,否则返回延迟2秒
我们可以通过返回页面是否有延迟来判断语句是否对错,判断关键信息的方法和布尔盲注类似。
Cookie注入、UA注入、Refer注入
注入点除了文本框和url之外,在用户提交的包中可能也有注入点
-
原理:
在用户提交的包中,用户通过Cookie、UA、Referer三种方式,把自己的一些信息传递给服务器,管理员可能会通过连接数据库来获取这三种信息。就Referer举例,是服务器用来知道你是从哪个地方访问该服务器的,也就是你点击该服务器的来源,从而判断你的权限。
Cookie、UA同样如此,都是管理员为了获取你的信息,一但管理员将你的信息和数据库连接并且没有任何过滤时,就可以使用sql注入了