1. 什么时SQL注入
SQL注入是通过应用程序把带有SQL代码的参数传递给数据库引擎。
2. SQL注入的根本原因
是应用程序的问题,而不是系统或者数据库的问题。
因为程序没有对用户输入数据的合法性进行检查,对传入参数的安全性没有明确定义,导致没有完全过滤。
3. SQL语言分类
DDL\DML\DCL
3.1 DDL(data definition language)
数据定义语言(创建,修改,删除 数据库和表)
Kali>mysql;
Mysql>show databases; #展示数据库
Mysql>use hxl; #打开‘hxl’数据库
Mysql>create database hxf2 default charset utf 8 #创建数据库
Mysql>drop database hxf2; #删除数据库
Mysql>use hxf;
Mysql>show tables;
Mysql>create table user2(uid int,uname varchar(32),regtime datatime);
#其中,int(整数型) varchar(文本字符串) datatime(日期时间类型)为所要创建表内,对应列(uid uname regtime)内数据的属性。
Mysql>drop table users2 #删除表格“users2”
①增加和删除某一列
Mysql>alter table users add column mobile biginit default0;#增加表格内列(列头名mobile)
Mysql>alter table users drop column mobile;删除表内,列头名为“mobile”的那一列
③改列头名
Mysql>alter table users change uname username varchar(100);
#将表“users”中,列头名“uname”改为“username ”,对应属性也更改为“varchar(100)”。
④调整字段(列)的顺序
Mysql>alter table users change uid uid int first;#将uid那一列(字段),排在第一。
Mysql>alter table users change uname uname varchar(100) after uid;#将unmae那一列排在uid后面。
⑤修改表名
Mysql>alter table users rename emp;#将表“users”改为“emp”。
3.2 DML(data manipulation language)
数据操作语言(对表内数据进行增删改查。)
3.2.1插入数据
Mysql>insert into users (uid,uname,password,isadmin) values(1,’hxf’,’hxf13’,1);
#利用insert into,在表‘users’中,对应列下插入对应的值,根据先前创建表时,表中的属性,输入对应的整数值,或者字符串。
Mysql>insert into users (uid,uname,password,isadmin) select 1,’hxf’,’hxf13,1;
#遇上一种不太一样的表达方式。
Mysql>insert into users set uid=1,uname=’hxf’;#直接赋值
#在数据库的操作过程中,若是因为,insert插入导致的语法或者输入的参数有问题,都会直接在终端中报错,这些报错信息会指出,那一列的那个数值属性不对。以此,在sql注入中,就可以判断出该表格中,对应列下的列头名,已经列中的数据属性是什么,以此来猜测数据库中的信息。
3.2.2删除delete数据
删除指定数据:
Mysql>delete from users where uname =’hxf’;
Mysql>delete from users;#删除所有信息
关联删除:
Mysql>delete a,b from emp a,dept b where a.deptno=b.deptno and a.detpno=1;
#首先,删除变量a,b
#将表emp赋给变量a,将dept赋给变量b
#删除条件是,表a中deptno值和表b中deptno值相等的那一行数据全部删除,而且,将a中detpno值为1的那一行数据也全部删除。
Kali>mysql;
Mysql> show databases;
Mysql>use hxf;
Mysql>show tables;
Mysql>select * from users;#展示表‘users‘中的所有数据。
Mysql>delete from users where uname=’mechnical’;
等同于
Kali>mysql hxf -e “delete from users where uname=’mechnical’”;
3.2.3Update
修改用户名(uname)为liufeng的密码(password)为123456:
update users set password =’123456’ where uname=’liufeng’;
修改所有用户的密码为123456:
Update users set password = ‘123456’;
注入列子:
$sql=“UPDATE users SET gold=gold+100000 WHERE uname=’$uname';
正常传参:$name=hxf
结果:UPDATE users SET gold=gold+100000 where uname=‘hxf';
注入传参:$name= ' or '1'='1
结果:UPDATE game_user SET gold=gold+100000 where username=' ' or '1'='1';
因为是or语句,前后满足一个条件就可以执行,所以注入后的结果,就是将所有用户的gold的数值都加了10000。
正常传参: hxf123
结果:Update users SET password=MD5(' hxf123 ') Where uname='$uname'
注入传参:hxf') Where uname='admin'#
之后SQL语句变为
Update users SET password=MD5('hxf123') Where uname='admin'#)'Where uname='$uname'
#号将后续内容全部注释掉,所以变为将用户名为admin的密码修改了。
正常传参:id=123
结果:Update users SET password=MD5('hxf123') Where uid='123'
注入传参:' or uname='admin
结果:Update user SET password=MD5('hxf123') Where uid='' or uname='admin'
将用户名为admin的密码进行修改。
3.2.4 select和条件查询
①查询用户表的所有记录
MySQL>selecet from users;
②条件查询
Mysql>select *from users where uname=’admin’ and password =’abc123’;
- 按照一定顺序查询
Mysql>select *from users order by uid;
#按照uid的正序排序
Mysql>selcet *from users order by uid desc;
#按照uid的倒叙将表个内容进行排序,并显示出来。
Mysql>selcet *from users order by 3;
#按照第3列的数据正序排序并显示。
Mysql>selcet *from users order by 3 limit 10;
#按照第3列数据正序排列并只显示前十行的数据;
- 子查询
Mysql>select * from users where uid in (selcet uid from admin);
#查询出表“users”和表“admin”中,uid相同的,所有数据都展示出来。
Mysql>select* from users where exsits(select uid from admin);
#判断exists后语句是否为真,若为真,则输出所有数据。
#这里的输出所有数据是因为select后跟的语句是*号。
- 连接查询
左连接:
返回的数据为,左表“a”(game_user)中“uname”列中所有的数据,而只返回右表“b”(game_user_ext)中“mobile”中满足条件的数据,剩下不符合条件的数据返回NULL。
此处,select后跟的“a.uname”和“b.mobile”,所以返回的数据也都是这两列中的数据,而不是所有列下的数据。
Mysql>SELECT a.uname,b.mobile FROM game_user a left JOIN game_user_ext b ON a.uid=b.uid;
内连接:(返回a,b两表中,uid相等的,a中的uname的数据,以及b中mobile中的数据)
Mysql>SELECT a.uname,b.mobile FROM game_user a inner JOIN game_user_ext b ON a.uid=b.uid;
3.2.5 select 注入逻辑
①报错逻辑
通过在语句后添加单引号‘,如果显示语法错误,则表示,此处可以进行sql注入。
- 猜处理逻辑
通过order by 5语句(对第五列的数据排序并展示),依次增加,直至网页报错,以此来判断,表中共有几列数据。
- 空集逻辑
通过’ or ‘1’=‘2,添加在变量处,因为填入后,变成‘’or ‘1’=‘2’,前边为空,后边是错误语句,所以结果是,网页不报错,但是页面内没有内容。
- 全集逻辑
通过’ or ‘1’=‘1,添加在变量处,因为填入后,变成‘’or ‘1’=‘1’,
前边为空,后边为真,所以结果是,页面不报错,但页面显示正常,或者页面页数增加,将所有内容全部显示。
3.2.6 记录联合与注入逻辑
①
Mysql>select *from users1 union select union select *from users2;
#将两表内的数据去重后,合并为一个表。
Mysql>select *from users1 union ALL select union select *from users2;
#此上两种情况,需要注意的是,两个表中的列头名必须是一致的,如果存在不一致,就无法合并,就会报错。
Mysql>select uid from users union selcet address from users2;
#首先需要注意的是,users和users2两个表中都具有uid和address这两列。
#其次,合并的数据,是将uid和address这两列的具体数据,直接合并在一列中。
②
Mysql>selcet uid,uname from users union select 1,’mechnical’;
#结果是,将union后一条记录(两个数据),添加到了对应的uid和uname的列中。
Mysql>select *from users union select 1;
#此时,就会报错,类比上面的例子,选择了两个列‘uid’和‘uname’,union后跟着两个数据‘1’和‘mechanical’,两列对应添加两个值。
而此例中,选择了表‘users’中的所有数据,但union中添加了一个值,就会因为,列和值的数量对不住而报错。
该种报错方法可用于sql注入判断字段数量。
③
注入语句:and 0=9 UNION SELECT 1,2,3
Mysql>SELECT uname,mobile FROM users where uid=1 and 0=9 UNION SELECT 1,2,3
通过0=9为假,使得union select 内容回显出来。
3.3 DCL(data control language)
数据控制语言(用来对数据库账户提权或创建一个新用户)
Mysql>select host ,user,password from mysql.user;#查看用户字典。
创建一个从任意IP灯具的超级权限用户:
Mysql>grant all privileges on *.* to admin@’%’ identified by ‘abc’;
all privileges:所有权限
*.*:任意数据库下的任意表
Admin:账户名称
@:从哪里登录
’%’:任意IP
identified by ‘abc’:密码设置为abc。
创建指定用户权限的账号
grant select,insert on *.* to admin2@`%` identified by ‘abc’;