sql注入详解

Posted 红客突击队

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql注入详解相关的知识,希望对你有一定的参考价值。

sql注入详解 





1、什么是sql注入

  sql,Structured Query Language,叫做结构化查询语言,管理数据库时用到的一种语言
  常见的结构化数据库有 mysql,MS SQL ,Oracle 以及 Postgresql

  SQLI,sql injection,我们称之为 sql 注入
  即把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力


2、sql注入原理

当出现以下条件时,有sql注入的可能:

  程序编写者在处理程序和数据库交互时,使用了字符串拼接的方式构造SQL语句

  不安全的数据库配置,比如对查询集不合理处理,对sql查询语句错误时不当的处理,导致其错误信息暴露在前端

  过于信任用户在前端所输入的数值,没有对输入的数据进行过滤(过滤输入),也没有对发送到数据库的数据进行转义(转义输出)

一个简单的例子

  前端URL:https://blog.csdn.net/example.php?id=1
其后台sql语句:$sql="SELECT 123 FROM abc WHERE id='1'"

  这条语句是采用拼接方式去对数据库内容进行查询的

  未对用户在前端输入的内容做过滤

  用户对id这个参数可控

于是攻击者上传?id=-1' union select password from admin--+
后台语句就变成了$sql="SELECT 123 FROM abc WHERE id='-1' union select password from admin--+"
用一个'闭合了前面的语句,用--+注释后面的内容,使得第二句union查询的语句得到执行,获取admin的密码

这就是sql注入的方法


3、必备知识

一些sql语句知识

(1)sql语句对大小写不敏感

也导致了后台程序对大小写的检测失效

(2)SQL 注释语句

  --:表示单行注释,在mysql中也用#注释

  /*…*/:用于多行(块)注释

(3)SELECT 查询语句

基础的查询方法

SELECT 列名称 FROM 表名称;

(4)UNION 操作符

用于合并两个或多个 SELECT 语句的结果集

  Union前后的两个SQL语句的选择列数必须相同才可以

  如果第一个Sql查询语句为错误的话,那么它会将第二个SQL语句的查询结果作为最后的输出,所以前面id输入一个非正确值,如-1

SELECT column_name(s) FROM table_name1UNIONSELECT column_name(s) FROM table_name2;

(5)concat()

用于将两个字符串连接为一个字符串

语法及使用特点:

CONCAT(str1,str2,…)

  返回结果为连接参数产生的字符串

  如有任何一个参数为NULL ,则返回值为 NULL

  可以有一个或多个参数

使用示例:

SELECT CONCAT(id, ',', name) AS con FROM info LIMIT 1;

(6)concat_ws()

语法

CONCAT_WS(separator,str1,str2,…)

CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式

  第一个参数是其它参数的分隔符,分隔符的位置放在要连接的两个字符串之间

  分隔符可以是一个字符串,也可以是其它参数

  如果分隔符为 NULL,则结果为 NULL

  函数会忽略任何分隔符参数后的 NULL 值

  但是CONCAT_WS()不会忽略任何空字符串

SELECT CONCAT_WS('_',id,name) AS con_ws FROM info LIMIT 1;

(7)group_concat()

返回一个字符串结果,该结果由分组中的值连接组合而成

使用语法及特点:

GROUP_CONCAT([DISTINCT] expr [,expr ...][ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] [,col ...]][SEPARATOR str_val])

  在 MySQL 中,可以得到表达式结合体的连结值

  通过使用 DISTINCT 可以排除重复值

  如果希望对结果中的值进行排序,可以使用 ORDER BY 子句。

  SEPARATOR 是一个字符串值,它被用于插入到结果值中

  缺省为一个逗号 (","),可以通过指定 SEPARATOR “” 完全地移除这个分隔符

  可以通过变量 group_concat_max_len 设置一个最大的长度

 在运行时执行的句法如下:SET [SESSION | GLOBAL] group_concat_max_len = unsigned_integer;

  如果最大长度被设置,结果值被剪切到这个最大长度

  如果分组的字符过长,可以对系统参数进行设置:SET @@global.group_concat_max_len=40000;

SELECT locus,GROUP_CONCAT(id) FROM info WHERE locus IN('AB086827','AF040764') GROUP BY locus;

(8)order by

用于根据指定的列对结果集进行排序

  默认按照升序对记录进行排序

  如果要按照降序对记录进行排序,可以使用 DESC 关键字

SELECT Company, OrderNumber FROM Orders ORDER BY Company (DESC);

(9)group by

用于结合合计函数,根据一个或多个列对结果集进行分组

语法

SELECT column_name, aggregate_function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name

(10)extractvalue() 和 updatexml()

对XML文档进行查询和修改的函数

EXTRACTVALUE(XML_document, XPath_string);
UPDATEXML(XML_document, XPath_string, new_value);

第一个参数:XML_document是String格式,为XML文档对象的名称;
第二个参数:XPath_string (Xpath格式的字符串) ,
第三个参数:new_value,String格式,替换查找到的符合条件的数据

SELECT * FROM message WHERE id = 1 and updatexml(1, (concat(0x7c, (SELECT @@version))), 1);

(11)if()

语法

IF(expr1,expr2,expr3)

其中,expr1是判断条件,expr2和expr3是符合expr1的自定义的返回结果。

selectif(il.status_id = 'INV_STTS_AVAILABLE','全新','二手') as status_idfrom inventory_location as il;

12)sleep()

执行select sleep(N)可以让此语句运行N秒钟

(13)left()

语法

LEFT(str,len)

  返回最左边的n个字符的字符串str,或NULL如果任何参数是NULL。

SELECT LEFT('foobarbar', 5);

14)count()

  COUNT(column_name)返回指定列的值的数目(NULL 不计入)

SELECT COUNT(column_name) FROM table_name

  COUNT(*) 函数返回表中的记录数:

SELECT COUNT(*) FROM table_name

  COUNT(DISTINCT column_name) 函数返回指定列的不同值的数目:

SELECT COUNT(DISTINCT column_name) FROM table_name

  注:COUNT(DISTINCT) 适用于 ORACLE 和 Microsoft SQL Server,但是无法用于 Microsoft Access。

(15)floor()

  返回最大整数,使这个整数小于或等于指定数的数值运算

(16)round()

  四舍五入一个正数或者负数,结果为一定长度的值

(17)rand()

  用于产生 0 至 1 之间的随机数

(18)length()

  返回字符串的长度,以字节为单位

(19)extract()

  用于返回日期/时间的单独部分,比如年、月、日、小时、分钟等等

EXTRACT(unit FROM date)


以上是关于sql注入详解的主要内容,如果未能解决你的问题,请参考以下文章

SQL注入详解

SQL注入详解

sql注入详解

sql注入详解

SQL注入详解

SQL注入详解-转发