SQL注入-基础

SQL注入流程

  1. 找到注入点:判断是否有漏洞,寻找插入位置
  2. 构造注入语句,并在注入点注入形成新的SQL语句
  3. 新形成的SQL语句提交数据库处理
  4. 数据库执行新的SQL语句,引发注入攻击

前置知识

1.特别的数据库

在MySQL 5.0版本之后,MySQL默认在数据库中存放一个information_schema的数据库,在该库中,需要记住三个表名,分别是:schematatablescolumns

  1. schemata表存储该用户创建的所有数据库的库名。

    >>>>其中记录数据库库名的字段名为schema_name

  2. tables表存储该用户创建的所有数据库的库名和表名。

    >>>>其中记录数据库库名表名的字段名分别是tables_schematable_name

  3. columns表存储该用户创建的所有数据库的库名、表名和字段名。

    >>>>其中记录数据库库名、表名和字段名的字段名分别是tables_schematable_namecolumn_name

2.注释符

在MySQL中,常见注释符的表达方式:

# ……#号后面的都会被注释

-- ……--号后面的都会被注释,不过在 -- 的前后都需要加空格再加数据(GET传参时只能使用--,后的空格用+代替)

/* ... */ :在查询语句中使用斜杠星号注释,从 / 开始到 */ 结束的部分都被视为注释,不会被执行。


  • 但**/* ... */** 的特殊用法--条件注释

条件注释是一种特殊的注释语法,它允许在注释中使用关键字,而这些关键字在执行查询时会被解析为相应的操作

语法格式为:

1
/*!<conditional_keyword> <query_part> */

例如:index?id=-10 /*!union*/ /*!select*/ 1,2,3等同于index?id=-10 union select 1,2,3

SQL注入常用基础语句

1
2
3
4
5
6
7
8
9
10
11
12
13
select version(); #查看数据库版本 

select user(); #查看数据库用户

select database(); #查看当前库名;

select table_name from information_schema.tables where table_schema=database() ; #查看当前库下的表名

select group_concat(table_name) from information_schema.tables where table_schema=database() ;
#只回显一行数据下查看当前库下的全部表名

select column_name from information_schema.columns where table_schema=database() and table_name='xxx';
#查询列名-把xxx缓存前面查询到的表名

SQL注入常用函数

联合查询(union)注入使用

1.concat()函数

concat()函数:将多个不同字段的字符串连接成一个字符串。

1
concat(str1,str2) #语法

注意:返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。

2.group_concat()函数

group_concat() 将多个同个字段的字符串连接成一个字符串。

1
group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc] [separator ‘分隔符’]) #语法

报错注入使用

1.extractvalue()函数

从 MySQL 5.7.8 版本开始,ExtractValue() 函数已被弃用

ExtractValue() 函数来提取 XML 字符串中的特定路径的值。

1
ExtractValue(xml_string, xpath_expression)
  • xml_frag:xml文档对象的名称,是一个string类型。
  • xpath_expr:使用xpath语法格式的路径。

2.updataxml()函数

  • xml_target:xml文档对象的名称,是一个string类型。
  • xpath_expr:使用xpath语法格式的路径。
  • new_xml:需要更新的内容。

3.count()+rand()+floor()+group by()函数

rand()函数:rand()返回0到1的随机数。rand(0)返回一个固定的0到1的伪随机数。

floor()函数:floor(x)返回小于或等于 x 的最大整数。

group by语句:group by语句可以根据一个或多个列对结果集进行分组,在分组的列上我们可以使用 COUNT, SUM, AVG,等函数。

布尔盲注使用

1.substr()/substring()函数

substr()/substring()函数:用来截取数据库某个字段中的一部分。

1
substr(string,start开始位置,length截取长度)  #语法

参数

  • string:必选,数据库中需要截取的字段
  • start:必选。正数,从字符串指定位置开始截取;负数,从字符串结尾指定位置开始 截取;0,在字符串中第一个位置开始截取。
  • length:可选,需要截取的长度。缺省。即截取到结束位置

2.ascii()函数

ascii()函数:返回字符串str的最左边的数值。

1
ascii(str)  #语法

2.length() 函数,返回字符串的长度

1
length(str) #语法

注入点分类

①数字型注入点

类似的后端语句

1
2
3
4
$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

在 Web 端大概是 http://xxx.com/index.php?id=1 这种形式,其注入点 id 类型为数字,所以叫数字型注入点。

1 and 1=1进行组合出来的sql注入语句为:

1
select * from news where id=1 and 1=1

②字符型注入点

类似的后端语句

1
2
3
4
$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

在 Web 端大概是 http://xxx.com/index.php?id=admin 这种形式,其注入点id 类型为字符类型,所以叫字符型注入点。

使用id=1' and 1=1 --+组合出来的sql注入语句为:

1
select * from news where id='admin' and 1=1 --+' LIMIT 0,1";

注意多了一个引号。由于注入拼接语句后多了一个',需要用注释符进行消除对语句的影响

③搜索型注入点

这是一类特殊的注入类型。这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有“keyword=关键字”,有的不显示在的链接地址里面,而是直接通过搜索框表单提交。此类注入点提交的 SQL 语句,其原形大致为:

1
2
3
4
5
6
7
select * from 表名 where 字段 like '%关键字%'`。

组合出来的sql注入语句为:
select * from news where search like '%测试 %' and '%1%'='%1%'

测试%' union select 1,2,3,4 and '%'='

判断注入点

注意区别语句报错与页面报错、页面数据不正确的区别

​ 1.?id=1 and 1=1?id=1 and 1=2进行测试如果1=1页面显示正常和原页面一样,并且1=2页面报错或者页面部分数据显示不正常,那么可以确定此处为数字型注入。

​ 2.?id=1' and 1=1 --+ / #?id=1' and 1=2 --+ / #或使用?id' and '1'='1?id' and '1'='2进行测试如果1=1页面显示正常和原页面一样,并且1=2页面报错或者页面部分数据显示不正常,那么可以确定此处为字符型注入。

​ 3.?id=1%' and 1=1 --+ / #?id=1%' and 1=2 --+ / #进行测试如果1=1页面显示正常和原页面一样,并且1=2页面报错或者页面部分数据显示不正常,那么可以确定此处为搜索型注入。

注入方法