SQL注入攻击介绍
Posted 99度灰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL注入攻击介绍相关的知识,希望对你有一定的参考价值。
SQL注入攻击介绍
一、SQL注入攻击简介
SQL注入攻击是指,后台数据库操作时,如果拼接外部参数到SQL语句中,就可能导致欺骗服务器执行恶意的SQL语句,造成数据泄露、删库、页面篡改等严重后果。按变量类型分为:数字型、字符型;按HTTP提交方式分为:GET注入、POST注入、Cookie注入;按注入方式分为:报错注入、盲注(布尔盲注、时间盲注)、堆叠注入等等。
二、SQL注入分类
按变量类型分类:如SQL语句为select *from user where param=1(数字型)、select *from user where param=”abc”(字符型)。
按HTTP提交方式分类:通常GET注入变量在query string里、POST注入变量在body中、Cookie注入变量在Cookie中。
按注入方式分类:报错注入是指利用数据库的某些机制,故意制造错误条件,使得查询结果出现在错误信息中;盲注是指数据不能回显到前端页面,需要利用一些方法进行判断或者尝试。返回true或flase(布尔盲注),返回延时sleep()(时间盲注);堆叠注入是指多条SQL语句一起执行。
三、SQL注入利用
对于循环SQL语法的数据库而言,SQL注入的原理基本相似,但由于语法、函数的不同,也存在许多细微的差异。对于不同数据库注入时,思路、方法不可能完全一样。下面SQL注入利用以mysql 5.7.26为例。先介绍几个MySQL的特性。
1:通过注释获取版本信息
MySQL支持3种注释风格:
#:注释从“#”字符到行尾;
--:注释从“--”序列到行尾。
/* */:注释从/*序列到后面的*/序列中间的字符。
其中,“/* */”注释存在一个特点,在“/*!*/”中感叹号是有特殊意义。如果“!”后面不加入版本号,MySQL将会直接执行SQL语句;若MySQL版本号高于或等于!后的版本号,语句将会执行SQL语句。
如:
因此对于MySQL可利用该特性进行SQL注入获取版本信息。再根据当前版本是否有安全漏洞,进一步做利用。
2:获取元数据
MySQL 5.0及其以上版本提供了INFORMATION_SCHEMA,INFORMATION_SCHEMA是信息数据库,它提供了访问数据库元数据的方式。如下面几个例子:
查询用户数据库名称:
select SCHEMA_NAME from INFORMATION_SCHEMA.SCHEMATA(show databases的结果从SCHEMATA表取)
查询当前数据库表:
select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = database()
查询指定表的所有字段:
select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = "user"
3:UNION查询
即使连接的select语句的数据类型不匹配,但也能正常执行。而SQL Server、Oracle则会认为语句错误,无法执行。如下(select username, password from test_user union select 1, 2):
攻击者对数据库注入,无非是利用数据库获取更多的数据或者更大的权限,那么利用方式可以归为一下:查询数据、读写文件、执行命令
1.查询数据
注入点在user参数,传参时使用单引号闭合前一个单引号,使用#注释后面的引号。结合MySQL结合MySQL的特性2、3可以查询用户数据库名称、当前数据库表、指定表的所有字段。由于前后查询字段的编码方式不同,需要做转换后才能正常执行。
MySQL存在报错注入,通过updatexml、extractvalue、floor函数利用。Updatexml(返回替换的XML片段)、extractvalue(使用XPath表示法从XML字符串中提取值),用法如下:
两个函数的第二个参数为xpath,如果语法错误,则会从错误的语法开始报错。利用concat拼接想要获取的数据库内容到第二个参数,第一个参数为错误的语法开始,报错时则会输出内容。floor函数报错注入则是利用group by时会建立虚拟表,而插入虚拟表的前后rand都会执行,导致插入数据冲突而报错。
2.读写文件
MySQL提供了load_file()函数,可用于读取文件,文件路径可用16进制转换或char(ASCII码)的方式传入。MySQL也提供了into outfile写文件的操作,写入内容也可以使用char(ASCII码)的方式表示。
如果读不到文件,可能是因为mysql的secure_file_priv的值默认为NULL,可通过 show global variables like '%secure%' 查看,然后在mysql配置文件下的[mysqld] 下添加条目:"secure_file_priv =",并重启mysql即可。
3.执行命令
MySQL的system函数可以执行系统命令,但这仅限本地执行。如果使用windows远程连接mysql root身份登录时,则无法执行shell。
Linux本地:
Windows远程连接:
通常是通过UDF提权、MOF提权进行利用。UDF是用户自定义函数,通过文件写入,利用UDF创建一个执行命令的函数。MOF只适用在WinServer2003,原理是C:/Windows/system32/wbem/mof目录下的mof文件每隔一段时间都会被系统执行,同样也是通过文件写入进行利用。条件和场景比较复杂,此处不做展开,有兴趣可以自行了解。
4.宽字节注入及长字符截断
php配置的magic_quotes_gpc(魔术引号)启用时,接收到的“’”、“””、“\\”和NULL字符都会被自动加上反斜线转义,这样就无法闭合单引号,造成字符型注入。如果mysql使用GBK编码,则会认为两个字节是一个汉子,前一个ascii要大于128,故如果输入“%df’”经过php转义为“%df\\’”后,“%df\\”会被mysql识别为中文,从而绕过转义。
MySQL的sql_mode选项默认值对插入超长值并不会报错,导致了一些截断问题。
5.时间盲注及二次SQL注入
如果SQL查询的结果并不会返回给前端页面,往往只能通过盲注,即页面无差异的注入。时间盲注则是一种盲注。在语句中使用if及sleep函数,猜测数据内容。
二次SQL注入是一种非常难以防范的SQL注入攻击。如下面的例子:在数据插入时由于php转义了单引号,故插入的SQL语句没有注入。但在查询时,直接从数据库获取数据,而数据库数据存在单引号,造成注入。
6.使用Sqlmap工具
1.首先验证漏洞是否存在:id=2 and 1=1页面返回,id=2 and 1=2页面返回为空。
2.使用sqlmap扫描后台数据库:sqlmap.py -u "http://www.xxx.com/xxx.php?id=2" --dbs
返回:[*] hdm1060277_db [*] information_schema
3.查找存储账号密码信息的表:sqlmap.py -u "http://www.xxx.com/xxx.php?id=2-1" -D hdm1060277_db --search -C user
返回:Table: dl
4.查看表内容:sqlmap.py -u "http://www.hechemist.com/hxydetailpro.php?id=2-1" -D hdm1060277_db -T dl -C username7,password7 --dump
返回:hxyuan | xxx
5.登录后台:http://www.xxx.com/hy/mn.php
四、SQL注入的防御
根据变量类型可以将SQL注入分为数字型和字符串型。对于数字型注入的防御,只要严格判断数据类型非字符串即可。对于字符串的SQL注入,主要通过预编译&参数化查询、校验白名单或正则匹配进行防御。
预编译语句在创建时已经将SQL语句发送给DBMS,完成了解析、检查、编译等工作,我们需要做的仅仅是将变量传给SQL语句而已。预编译技术可以有效的防御SQL注入。
五、NoSQL注入
SQL注入是由于SQL语句拼接了不可信参数导致的,而NoSQL数据库(如:Mongodb)使用JSON格式查询数据交互的方法也同样可能存在不可信参数拼接。因此,即使这些数据库没有使用传统的SQL语法,它们仍然可能的存在NoSQL注入攻击。
对代码感兴趣的,关注公众号“吴花果的吴花火”,输入”sql注入“获取sql注入实例代码的下载链接。
以上是关于SQL注入攻击介绍的主要内容,如果未能解决你的问题,请参考以下文章
2019-2020-2 20175315陈煜扬《网络对抗技术》 Exp9 Web安全基础
2019-2020-2 20175326 李一潇《网络对抗技术》Exp9 Web安全基础