首页 网络安全 安全学院 查看内容

CVE-2009-1285: phpMyAdmin Code Injection

2009-4-27 11:36 715 0

摘要: Trace注:原文在http://xorl.wordpress.com/2009/04/23/cve-2009-1285-phpmyadmin-code-injection/  貌似有的地方...
关键词: nbsp crlf configuration ret foreach server persistKeys Servers phpmyadmin export

Trace注:原文在http://xorl.wordpress.com/2009/04/23/cve-2009-1285-phpmyadmin-code-injection/  貌似有的地方需要用代理看。 Well, I usually don’t blog about these bugs but phpMyAdmin is a project that is used almost everywhere and this is a quick and dirty way to get code execution. This issue affects phpMyAdmin 3.x before 3.1.3.2 and it was disclosed on 14 April 2009. The bug is present at setup/lib/ConfigFile.class.php file. Here is an outline of that file from 3.1.3.1 release: 1 <?php    ...10 class ConfigFile11 {12     /**13      * Stores default PMA config from config.default.php14      * @var array15      */16     private $cfg;    ...259     /**260      * Creates config file261      *262      * @return string263      */264     public function getConfigFile()265     {266         $crlf = (isset($_SESSION['eol']) && $_SESSION['eol'] == 'win') ? "\r\n" : "\n";267         $c = $_SESSION['ConfigFile'];268269         // header270         $ret = '<?php' . $crlf    ...279         // servers280         if ($this->getServerCount() > 0) {281             $ret .= "/* Servers configuration */$crlf\$i = 0;" . $crlf . $crlf;282             foreach ($c['Servers'] as $id => $server) {283                 $ret .= '/* Server: ' . $this->getServerName($id) . " [$id] */" . $crlf284                     . '$i++;' . $crlf;285                 foreach ($server as $k => $v) {286                     $ret .= "\$cfg['Servers'][\$i]['$k'] = "287                         . var_export($v, true) . ';' . $crlf;288                 }289                 $ret .= $crlf;290             }291             $ret .= '/* End of servers configuration */' . $crlf . $crlf;292         }    ...So… function getConfigFile() retrieves various information. Here it constructs a configuration file and $ret includes the PHP code. At line 281 it starts the file with comment: /* Servers configuration */Then, as you can clearly see at line 283 the configuration will have a new comment which is: /* Server: <getServerName()> "id" */However, $id is completely user controlled since it’s derived from the session variable ConfigFile at line 267. For example, if a user specifies an $id of: bleh */ <?php echo date(); ?> /* He will end up with a configuration file that includes this: /* Server: <getServerName()> bleh */ <?php echo date(); ?> /* */This simple code injection was patched by limiting the user input using preg_replace() function like this:              foreach ($c['Servers'] as $id => $server) {+                $k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);                 $ret .= '/* Server: ' . $this->getServerName($id) . " [$id] */" . $crlfWhich replaces any matches of /[^A-Za-z0-9_]/ with _ and moves on with the next element. The same bug was also in the following code of the same function: 296         // other settings297         $persistKeys = $this->persistKeys;298         foreach ($c as $k => $v) {299             $ret .= "\$cfg['$k'] = " . var_export($v, true) . ';' . $crlf;300             if (isset($persistKeys[$k])) {301                 unset($persistKeys[$k]);302             }303         }Where the exact same logic applies and also the same patch :-P          foreach ($c as $k => $v) {+            $k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);             $ret .= "\$cfg['$k'] = " . var_export($v, true) . ';' . $crlf;There was another instance of that bug at the last loop of that function which was this: 305         // keep 1d array keys which are present in $persist_keys (config_info.inc.php)306         foreach (array_keys($persistKeys) as $k) {307             if (strpos($k, '/') === false) {308                 $ret .= "\$cfg['$k'] = " . var_export($this->getDefault($k), true) . ';' . $crlf;309             }310         }311         $ret .= '?>';312313         return $ret;314     }315 }316 ?>Again, the concept is the same in the foreach() loop at line 306 and the patch was of course:              if (strpos($k, '/') === false) {+                $k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);                 $ret .= "\$cfg['$k'] = " . var_export($this->getDefault($k), true) . ';' . $crlf;The evil auditors among us would have caught that the bug is still there ;-) Don’t tell anyone… (I usually don’t write publicly about such things but what the hell… It’s just phpMyAdmin)!
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部