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_name1
UNION
SELECT 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的自定义的返回结果。
如
select
if(il.status_id = 'INV_STTS_AVAILABLE','全新','二手') as status_id
from 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注入详解的主要内容,如果未能解决你的问题,请参考以下文章