Обнаружена и устранена опасная уязвимость в Netcat CMS версий 3.х - 5.7

Уязвимость в системе управления сайтом Netcat, дающая злоумышленникам возможность получить полный доступ к сайту, затронула все сайты, которые работают на этой CMS версий начиная от 4.х и вплоть до 5.7 (апдейты ниже 5.7.0.16119 от 29.04.2016) . Очевидно, уязвимость имеется также и в netcat 3.x

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

Но ради справедливости стоит сразу оговориться, что в других системах управления уязвимостей обнаруживается еще больше и чаще. Пожалуй, обнаруженная брешь говорит о росте популярности CMS - ведь подобные лазейки обнаруживаются регулярно даже в самых крупных программных проектах - таких, как MS Windows, Linux и даже в протоколах шифрования (взять, к примеру, SSL3).

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

Сигнализация о том, что на многие обслуживаемые у нас сайты была попытка вторжения, сработала в ночь с 27 на 28 апреля. Получив сигнал, мы рано утром предприняли все необходимое, чтобы закрыть системы от дальнейшего вторжения. Следом появилось и официальное заявление от Неткэт о данной проблеме, вместе с инструкцией по лечению, которое мы приводим ниже. Если вы или обслуживающие вас программисты еще не исправляли уязвимость вашего сайта – воспользуйтесь этой инструкцией по лечению:

Если в файле /netcat/require/s_list_inc.php есть код, похожий на


        switch ($fldType[$i]) {
            case 1: // Char
                $result .= $fldNameTempl . "<br><input type='text' name='".$srchPatName."[" . $j . "]' size='50' maxlength='255' value='" . htmlspecialchars(stripcslashes($srchPatValues[$j]), ENT_QUOTES) . "'>" . $fld_suffix;
                $j++;
                break;
            case 3: // Text
                $result .= $fldNameTempl . "<br><input type='text' name='".$srchPatName."[" . $j . "]' size='50' maxlength='255' value='" . htmlspecialchars(stripcslashes($srchPatValues[$j]), ENT_QUOTES) . "'>" . $fld_suffix;
                $j++;
                break;
            case 6: // File
                $result .= $fldNameTempl . "<br><input type='text' name='".$srchPatName."[" . $j . "]' size='50' maxlength='255' value='" . htmlspecialchars(stripcslashes($srchPatValues[$j]), ENT_QUOTES) . "'>" . $fld_suffix;
                $j++;
                break;

то ваш сайт подвержен уязвимости.

Чтобы закрыть уязвимость, выполните следующие шаги:

Для версий 5.х

В файле /netcat/require/s_list.inc.php в функции showSearchForm замените
код


        switch ($fldType[$i]) {
            case 1: // Char
                $result .= $fldNameTempl . "<br><input type='text' name='".$srchPatName."[" . $j . "]' size='50' maxlength='255' value='" . htmlspecialchars(stripcslashes($srchPatValues[$j]), ENT_QUOTES) . "'>" . $fld_suffix;
                $j++;
                break;
            case 3: // Text
                $result .= $fldNameTempl . "<br><input type='text' name='".$srchPatName."[" . $j . "]' size='50' maxlength='255' value='" . htmlspecialchars(stripcslashes($srchPatValues[$j]), ENT_QUOTES) . "'>" . $fld_suffix;
                $j++;
                break;
            case 6: // File
                $result .= $fldNameTempl . "<br><input type='text' name='".$srchPatName."[" . $j . "]' size='50' maxlength='255' value='" . htmlspecialchars(stripcslashes($srchPatValues[$j]), ENT_QUOTES) . "'>" . $fld_suffix;
                $j++;
                break;

на


        $stringValue = htmlspecialchars(stripcslashes($srchPatValues[$j]), ENT_QUOTES);
        $stringValue = addcslashes($stringValue, '$');
        switch ($fldType[$i]) {
            case 1: // Char
                $result .= $fldNameTempl . "<br><input type='text' name='".$srchPatName."[" . $j . "]' size='50' maxlength='255' value='" . $stringValue . "'>" . $fld_suffix;
                $j++;
                break;
            case 3: // Text
                $result .= $fldNameTempl . "<br><input type='text' name='".$srchPatName."[" . $j . "]' size='50' maxlength='255' value='" . $stringValue . "'>" . $fld_suffix;
                $j++;
                break;
            case 6: // File
                $result .= $fldNameTempl . "<br><input type='text' name='".$srchPatName."[" . $j . "]' size='50' maxlength='255' value='" . $stringValue . "'>" . $fld_suffix;
                $j++;
                break;

Для версий 4.x и 3.х

В файле /netcat/require/s_list.inc.php в функции showSearchForm замените код


    switch ($fldType[$i]) {
      case 1:   // Char
        $result .= $fldNameTempl . "<br><input type='text' name='srchPat[" . $j . "]' size='50' maxlength='255' value='" . htmlspecialchars(stripcslashes($srchPat[$j]), ENT_QUOTES) . "'>" . $fld_suffix;
        $j++;
        break;
      case 3:   // Text
        $result .= $fldNameTempl . "<br><input type='text' name='srchPat[" . $j . "]' size='50' maxlength='255' value='" . htmlspecialchars(stripcslashes($srchPat[$j]), ENT_QUOTES) . "'>" . $fld_suffix;
        $j++;
        break;
      case 6:   // File
        $result .= $fldNameTempl . "<br><input type='text' name='srchPat[" . $j . "]' size='50' maxlength='255' value='" . htmlspecialchars(stripcslashes($srchPat[$j]), ENT_QUOTES) . "'>" . $fld_suffix;
        $j++;
        break;

на


        $stringValue = htmlspecialchars(stripcslashes($srchPat[$j]), ENT_QUOTES);
        $stringValue = addcslashes($stringValue, '$');

        switch ($fldType[$i]) {
            case 1: // Char
                $result .= $fldNameTempl . "<br><input type='text' name='srchPat[" . $j . "]' size='50' maxlength='255' value='" . $stringValue . "'>" . $fld_suffix;
                $j++;
                break;
            case 3: // Text
                $result .= $fldNameTempl . "<br><input type='text' name='srchPat[" . $j . "]' size='50' maxlength='255' value='" . $stringValue . "'>" . $fld_suffix;
                $j++;
                break;
            case 6: // File
                $result .= $fldNameTempl . "<br><input type='text' name='srchPat[" . $j . "]' size='50' maxlength='255' value='" . $stringValue . "'>" . $fld_suffix;
                $j++;
                break;

2. если ваш сайт отдаёт 500 ошибку, проверьте файл e404.php. В конце может быть вредоносный код.

3. если у вас в корне есть файл new.vars.inc.php, удалите его.

4. поищите на сайте файлы содержащие

<?php eval(base64_decode(<<<EOD

в начале. Удалите найденные файлы.

От себя добавим, что изменять по второй методике (которая «для 3.х и 4.х») нужно не только эти версии системы, но и все остальные версии, где в функции showSearchForm для инпутов не используется переменная $srchPatName. К таким сайтам точно относятся, в частности, версии Netcat с 5.0 до 5.4 включительно.

Для тех, кто «в теме», возможно, будет интересно знать, что суть уязвимости заключается в том, что некоторые html-формы, используемые в CMS Netcat, обрабатываются функцией eval, которая и позволяет выполнить любой php-код – например, закачать бэкдор (веб-шелл) или просто выполнить определенную команду. Мы сейчас исследуем систему на предмет того, требуется ли в связи с этой уязвимостью, кроме html-полей, генерируемых через API Netcat, дорабатывать также и самодельные аналоги этих html-инпутов. Об этом мы напишем отдельно. Но уже сейчас видно, что вышеприведенные изменения закрывают ту дыру в Netcat, которой пользуются злоумышленники.

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

Если своими силами вам не удается вылечить сайт на netcat от вирусов и троянов – напишите нам заявку и попросите нас вылечить сайт, мы все сделаем максимально оперативно.

UPD: Позднее была найдена ещё одна уязвимость, работающая по сходной схеме. Признаков массового взлома с её использованием не обнаружено. Патч, исправляющий данную узявимость также выпущен, однако, если вы хотите исправить её своими силами, добавьте одну строку в начало файла /netcat/message_fields.php после <?php

$fldID = $fld = $fldName = $fldType = $fldFmt = $fldNotNull = $fldInheritance = $fldDefault = $fldTypeOfEdit = $fldDoSearch = array();