Сканирование сети на предмет выявления модулей управления ИБП APC уязвимых к Ripple20

APC Network Management Cards and Ripple20В прошлом году компанией JSOF была публично раскрыта информация о целом наборе уязвимостей, корни которых уходят в древнюю библиотеку компании Treck, реализующую функции стека протоколов TCP/IP. Эту библиотеку на протяжении многих лет использовали разные производители аппаратного обеспечения для обеспечения работы TCP/IP во встроенном микрокоде firmware на множестве разных типов устройств. Данный пакет уязвимостей получил общее название Ripple20.

Уязвимости, входящие в состав Ripple20, имеют разные уровни критичности и среди них есть некоторые опасные уязвимости, позволяющие удалённо вызвать отказ в обслуживании или даже получать полный доступ над устройством со всеми вытекающими последствиями.

Данная проблема была освещена на множестве интернет-ресурсов, связанных с темой информационной безопасности. Вот некоторые из них:

Часть вендоров на протяжении нескольких месяцев после огласки Ripple20 выпустили обновления микрокода для своих продуктов, в которых закрываются данные уязвимости. Однако некоторые производители намеренно отказались от обновления микрокода некоторых своих продуктов, снятых с текущей поддержки. Таким образом, все уязвимые устройства, не имеющие обновления, но по прежнему эксплуатируемые в рамках локальных/глобальных сетей, вошли в группу повышенных рисков нарушения режима ИБ.

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

Применительно к вопросу обновления микрокода на эксплуатируемых сетевых устройствах, требуется отдельное планирование и немалый объём работы по устройствам каждого отдельно взятого производителя и модели. В данной заметке мы рассмотрим вариант сбора информации относительно модулей управления источников бесперебойного питания (ИБП) марки APC ("APC by Schneider Electric"), которые широко используются для защиты электропитания серверного и сетевого оборудования.

Модули управления ИБП APC и Ripple20

На сайте вендора опубликован специальный, периодически обновляемый, бюллетень безопасности, где можно найти информацию о том, какие типы и модели устройств получили "заплатки" микрокода:

Security Notification – Treck TCP/IP Vulnerabilities (Ripple20) (V2.10)

Применительно к модулям управления ИБП (в терминологии APC - Network Management Card, NMC) разных поколений есть отдельный уточняющий документ:

Security Notification - APC by Schneider Electric Network Management Cards (V2.2)

В этом документе говорится о том, что модули управления третьего поколения NMC3 (такие, как AP9640/AP9641) и модули второго поколения NMC2 (такие, как AP9630/AP9631/AP9635/AP9537SUM) имеют обновления микрокода, закрывающие уязвимости из состава Ripple20. Минимальные рекомендуемые (на данный момент времени) версии микрокода AOS таковы:

  • Для модулей NMC2 - версия 6.9.6 (версии 6.9.4 и старше - уязвимы)
  • Для модулей NMC3 - версия 1.4 (версии 1.3.3.1 и старше - уязвимы)

Скачать файлы обновлений микрокода для NMC2/NMC3 можно по ссылке:

FAQ - FA410359 - Treck TCP/IP Vulnerabilities (Ripple20)

Если же говорить о модулях управления первого поколения NMC1 (таких, как AP9617/AP9618/AP9619), то здесь ситуация обстоит совсем иначе. Фактически, уязвимыми к Ripple20 объявлены все модули NMC1 c любыми версиями микрокода AOS до самой крайней, поддерживаемой на NMC1, версии 3.9.2. При этом отсутствует какая-либо возможность последующего обновления с целью закрытия уязвимостей.

Что делать с уязвимыми модулями NMC1?

В ранее упомянутом документе даётся несколько рекомендаций относительно того, как можно сузить область возможных атак на NMC1, например, предлагается отказаться от использования протоколов DHCP и DNS. Но подобные действия кажутся полумерами и, похоже, что в данном случае какой-то более или менее ощутимый эффект может дать только жесткая сетевая изоляция модулей управления на уровне сетевого маршрутизирующего оборудования. Однако, подобная изоляция, по разным причинам, возможна не всегда и не везде. К тому же, даже при обеспечении изоляции на уровне маршрутизатора, незакрытой может остаться возможность атаки со стороны хостов, расположенных в одном физическом сегменте сети с уязвимыми модулями управления.

В качестве альтернативного варианта решения вопроса можно использовать физическую замену съёмных SmartSlot-модулей управления первого поколения NMC1 на модули NMC2/NMC3, если это позволяют сделать финансовые возможности компании. Такая замена позволит поднять уровень безопасности сетевого доступа к ИБП на приемлемый уровень. Модули управления NMC2/NMC3 имеют поддержку современных безопасных протоколов SSH/HTTPS (не имеют проблем при работе с современными браузерами с TLS в отличие от NMC1) и, что более важно, имеют встроенный функционал брандмауэра, который позволит максимально эффективно ограничить к ним сетевой доступ и нивелировать возможные риски от обнаруживаемых в будущем уязвимостей.

При планировании замены NMC1 может возникнуть желание использовать более современные модули NMC3, однако следует учесть то, что модули NMC3 совместимы не со всеми старыми моделями ИБП. Информацию о совместимости разных поколений NMC c модельным рядом ИБП можно найти по ссылке:

FAQ - FA237786 - APC UPS Network Management Card (NMC) Compatibility Chart

При этом также следует учесть, что приобретение модулей второго поколения уже сегодня может оказаться не совсем тривиальной задачей, так как эти модули сняты c производства в конце 2020 года. Разумеется, это не означает, что вендор прекратил поддержку NMC2 в плане выпуска обновлений безопасности микрокода и такие обновления будут доступны ещё, как минимум, год-два (по информации из разных источников).

Обнаружение в сети модулей NMC

Перед планированием мероприятий по закрытию уязвимостей NMC может потребоваться проведение "инвентаризации" всех эксплуатируемых в сети модулей управления.

Для сканирования сети на предмет выявления модулей APC NMC можно воспользоваться такими простыми и свободно-распространяемыми инструментами, как, например, утилита APC Device IP Configuration Wizard или сетевой сканер nmap.

Утилита Device IP Configuration Wizard позволит просканировать небольшую сеть и может дать информацию о версии микрокода AOS для всех обнаруженных устройств.

APC Device IP Configuration Wizard tool in action

Но эта утилита использует только протокол SNMP со стандартной строкой подключения Community "public". Поэтому, если на модуле управления выключен данный протокол или изменены его стандартные настройки, то утилита не отобразит информации по такому модулю.

Сетевой сканер nmap имеет специальный механизм определения ОС сканируемого хоста при использовании опций  -O --osscan-guess, но попытки его использования для опроса TCP-портов NMC показали, что результат получается, мягко говоря, неконкретный.

Try to detect APC NMC type and AOS verion via nmap tool

Учитывая то обстоятельство, что на модулях управления NMC реализована работа разных протоколов, каждый из которых мог быть ранее намеренно или по ошибке включен/выключен разными администраторами, стало понятно, что какого-то готового решения для обнаружения всех таких устройств нет и нужно сделать что-то своё. В результате был сделан PowerShell-скрипт, который для сканирования сети не требует никаких сторонних средств, а использует возможности, встроенные в ОС Windows (скрипт проверялся на Windows 10 20H2 c PowerShell 5.1).

[System.Net.IPAddress]$StartScanIP = "10.1.0.1"
[System.Net.IPAddress]$EndScanIP =   "10.10.10.254"
[int]$EchoCount = 2
[string]$SNMPCommunity = "public"
[int]$SNMPTimeout = 4000
[int]$FTPPort  = 21
[int]$FTPTimeout  = 1000
[int]$HTTPTimeout = 10000
[string]$CSVReportPath = "C:\Temp\APC-NMC-Scan.csv"
[bool]$DataInList = $false

$Watch = [System.Diagnostics.Stopwatch]::StartNew()
$Watch.Start()

$ScanIPRange = @() 
if($EndScanIP -ne $null) 
{
  $StartIP = $StartScanIP -split '\.' 
  [Array]::Reverse($StartIP)   
  $StartIP = ([System.Net.IPAddress]($StartIP -join '.')).Address
  $EndIP = $EndScanIP -split '\.' 
  [Array]::Reverse($EndIP)   
  $EndIP = ([System.Net.IPAddress]($EndIP -join '.')).Address
  For ($x=$StartIP; $x -le $EndIP; $x++) {     
      $IP = [System.Net.IPAddress]$x -split '\.' 
      [Array]::Reverse($IP)    
      $ScanIPRange += $IP -join '.'  
  }
} 
  else 
{ 
 $ScanIPRange = $StartScanIP 
} 

Workflow Network-Scan {
  param($wIPPool,$wEchoCount,$wSNMPCommunity,$wSNMPTimeout,$wFTPPort,$wFTPTimeout,$wHTTPTimeout)
  $WFResult = @()
  ForEach -parallel -throttlelimit 32 ($ip in $wIPPool)
  {   
    $ItemReturn = inlinescript 
    {
      $HostIP   = $USING:ip
      $HostName = "-"

      # First check host is online
      #
      If (Test-Connection -Computername $HostIP -BufferSize 16 -Count $USING:wEchoCount -Quiet)
      {        
        [bool]$FindNMC = $false
        [bool]$ProtoSNMPAvailable = $false
        [bool]$ProtoFTPAvailable  = $false
        [bool]$ProtoHTTPAvailable = $false
        [string]$SNMPSysOID = ""
        [string]$SNMPNMCHost = ""
        [string]$SNMPNMCDesc = ""
        [string]$GLB_NMC_Model = ""
        [string]$GLB_NMC_AOS = ""
        [string]$SNMPNMCApp = ""
        [string]$SNMPNMCSN = ""
        [string]$SNMPUPSMod = ""
        [string]$SNMPUPSSN = ""

        # Trying to examine a host using SNMP
        #
        $SNMP = New-Object -ComObject OlePrn.OleSNMP
        Try {
            $SNMP.Open($HostIP,$USING:wSNMPCommunity,3,$USING:wSNMPTimeout)
            $SNMPSysOID = $SNMP.Get('.1.3.6.1.2.1.1.2.0')
        } Catch {}
        If ($SNMPSysOID -like "*318.1.3*") {
            $ProtoSNMPAvailable = $true
            $FindNMC = $true
            Try { $SNMPNMCHost = $SNMP.Get('.1.3.6.1.2.1.1.5.0') } Catch {}
            Try { 
                $SNMPNMCDesc  = $SNMP.Get('.1.3.6.1.2.1.1.1.0')
                $GLB_NMC_Model = (($SNMPNMCDesc -split ' *..MN:')[1] -split ' ')[0]
            } Catch {}
            Try { $GLB_NMC_AOS = $SNMP.Get('.1.3.6.1.4.1.318.1.4.2.4.1.4.1') } Catch {}
            Try { $SNMPNMCApp = $SNMP.Get('.1.3.6.1.4.1.318.1.4.2.4.1.4.2') } Catch {}
            Try { $SNMPNMCSN  = $SNMP.Get('.1.3.6.1.4.1.318.1.4.2.4.1.2.1') } Catch {}
            Try { $SNMPUPSMod = $SNMP.Get('.1.3.6.1.4.1.318.1.1.1.1.1.1.0') } Catch {}
            Try { $SNMPUPSSN  = $SNMP.Get('.1.3.6.1.4.1.318.1.1.1.1.2.3.0') } Catch {}
        }
        $SNMP.Close()

        # Trying to examine a host using FTP
        #
        [string]$FTPNMCModel = ""
        [string]$FTPNMCAOS   = ""
        [string]$FTPBanner    = ""              
        $TCPSocket = New-Object System.Net.Sockets.TCPClient
        Try {
            $Connected = ($TCPSocket.BeginConnect($HostIP,$USING:wFTPPort,$Null,$Null)).AsyncWaitHandle.WaitOne($USING:wFTPTimeout)
            If ($Connected -eq "True"){
                $ProtoFTPAvailable = $true
                $Stream = $TCPSocket.GetStream() 
                Start-Sleep -m 1000; 
                $FTPBanner = ""
                While ($Stream.DataAvailable) { 
                    $FTPBanner += [char]$Stream.ReadByte() 
                }
                If ($FTPBanner -like "*Network Management Card*") {
                    $FTPNMCModel = ($FTPBanner -split ' ')[1]
                    $FTPNMCAOS = (($FTPBanner -split ' *AOS')[1] -split ' ')[1]
                    If (![string]::IsNullOrWhiteSpace($FTPNMCModel) -and [string]::IsNullOrWhiteSpace($GLB_NMC_Model)) {
                        $GLB_NMC_Model = $FTPNMCModel
                        $FindNMC = $true
                    }
                    If (![string]::IsNullOrWhiteSpace($FTPNMCAOS) -and [string]::IsNullOrWhiteSpace($GLB_NMC_AOS)) {
                       $GLB_NMC_AOS = $FTPNMCAOS
                    }
                }
            }
        } Catch {}
        $TCPSocket.Close() 

        # Trying to examine a host using HTTP
        #
        $CheckUrl = "http://$HostIP/images/smapc.gif"
        Try {                            
           $WebRequest = [System.Net.WebRequest]::Create($CheckUrl)
           $WebRequest.Timeout = $USING:wHTTPTimeout
           $WebRequest.AuthenticationLevel = "None"
           $WebResponse = $WebRequest.GetResponse()
           If (($WebResponse.StatusCode -eq "OK") -and ($WebResponse.ContentType -eq "image/gif") -and ($WebResponse.ContentLength -gt 0)) {
               $ProtoHTTPAvailable = $true                
               $FindNMC = $true
               If ([string]::IsNullOrWhiteSpace($GLB_NMC_Model)) {
                   $GLB_NMC_Model = "Uknown" 
               }     
           } 
        } Catch {}

        # Return NMC data
        #
        If ($FindNMC) {
            Try{
                $HostName = [System.Net.Dns]::GetHostByAddress($HostIP).HostName
            } Catch {}
            $Item = New-Object System.Object
            $Item | Add-Member -MemberType NoteProperty -Name "HostIP" $HostIP
            $Item | Add-Member -MemberType NoteProperty -Name "HostDNSName" $HostName
            $Item | Add-Member -MemberType NoteProperty -Name "pSNMP" $ProtoSNMPAvailable
            $Item | Add-Member -MemberType NoteProperty -Name "pFTP" $ProtoFTPAvailable
            $Item | Add-Member -MemberType NoteProperty -Name "pHTTP" $ProtoHTTPAvailable
            $Item | Add-Member -MemberType NoteProperty -Name "SNMPNMCHost" $SNMPNMCHost
            $Item | Add-Member -MemberType NoteProperty -Name "GLB_NMC_Model" $GLB_NMC_Model
            $Item | Add-Member -MemberType NoteProperty -Name "SNMPNMCSN" $SNMPNMCSN
            $Item | Add-Member -MemberType NoteProperty -Name "GLB_NMC_AOS" $GLB_NMC_AOS
            $Item | Add-Member -MemberType NoteProperty -Name "SNMPNMCApp" $SNMPNMCApp
            $Item | Add-Member -MemberType NoteProperty -Name "SNMPUPSMod" $SNMPUPSMod
            $Item | Add-Member -MemberType NoteProperty -Name "SNMPUPSSN" $SNMPUPSSN
            return $Item
        }      
      }               
     }
     $WORKFLOW:WFResult += $ItemReturn
   }
  return $WORKFLOW:WFResult
}

[array]$Result = Network-Scan $ScanIPRange $EchoCount $SNMPCommunity $SNMPTimeout $FTPPort $FTPTimeout $HTTPTimeout 

If (!$DataInList) {
$Result | Sort-Object GLB_NMC_Model,GLB_NMC_AOS,HostIP | Format-Table -GroupBy GLB_NMC_Model -Autosize `
  @{Name="Host IP";Expression = { $_.HostIP }; Alignment="Center"},
  @{Name="Host Name from DNS";Expression = { $_.HostDNSName }; Alignment="Center"},
  @{Name="SNMP";Expression = { $_.pSNMP }; Alignment="Center"},
  @{Name="FTP";Expression = { $_.pFTP }; Alignment="Center"},
  @{Name="HTTP NMCv1";Expression = { $_.pHTTP }; Alignment="Center"},
  @{Name="NMC Host Name";Expression = { $_.SNMPNMCHost }; Alignment="Center"},
  @{Name="NMC Model";Expression = { $_.GLB_NMC_Model }; Alignment="Center"},
  @{Name="NMC SN";Expression = { $_.SNMPNMCSN }; Alignment="Center"},
  @{Name="NMC AOS";Expression = { $_.GLB_NMC_AOS }; Alignment="Center"},
  @{Name="NMC App";Expression = { $_.SNMPNMCApp }; Alignment="Center"},
  @{Name="UPS Model";Expression = { $_.SNMPUPSMod }; Alignment="Left"},
  @{Name="UPS SN";Expression = { $_.SNMPUPSSN }; Alignment="Center"}
} Else {
$Result | Sort-Object HostIP | Format-List `
  @{Name="Host IP";Expression = { $_.HostIP }},
  @{Name="Host Name from DNS";Expression = { $_.HostDNSName }},
  @{Name="Protocol SNMP available";Expression = { $_.pSNMP }},
  @{Name="Protocol FTP available";Expression = { $_.pFTP }},
  @{Name="Protocol HTTP NMCv1 available";Expression = { $_.pHTTP }},
  @{Name="NMC Host Name";Expression = { $_.SNMPNMCHost }},
  @{Name="NMC Model Name";Expression = { $_.GLB_NMC_Model }},
  @{Name="NMC Serial Number";Expression = { $_.SNMPNMCSN }},
  @{Name="NMC AOS version";Expression = { $_.GLB_NMC_AOS }},
  @{Name="NMC App version";Expression = { $_.SNMPNMCApp }},
  @{Name="UPS Model Name";Expression = { $_.SNMPUPSMod }},
  @{Name="UPS Serial Number";Expression = { $_.SNMPUPSSN }}
}

Write-Host $Result.Count "hosts found on network range " $StartScanIP "-" $EndScanIP

If (($CSVReportPath) -and ($Result.Count -gt 0)) {
  If(!(Test-Path $CSVReportPath)) {
    Try {
        New-Item -ItemType File -Path $CSVReportPath -ErrorAction Stop | Out-Null
    } Catch {
        Write-Warning "Failed to create report file ($CSVReportPath)!`r`n$_`r`nPlease check the variable `$CSVReportPath in the script."
        Break
    }
  }
  $Result + (Import-Csv $CSVReportPath) `
  | Select-Object -Property "HostIP","HostDNSName","pSNMP","pFTP","pHTTP", `
  "SNMPNMCHost","GLB_NMC_Model","SNMPNMCSN","GLB_NMC_AOS","SNMPNMCApp","SNMPUPSMod","SNMPUPSSN" `
  | Sort-Object -Unique  HostIP `
  | Export-Csv -NoTypeInformation -Path $CSVReportPath
}

$Watch.Stop()
Write-Host "`r`nScript time:" $Watch.Elapsed

В переменных $StartScanIP и $EndScanIP указывается начало и конец диапазона сканирования сети. Доступность каждого хоста в указанном диапазоне проверяется отсылкой 2 echo-пакетов. В проблемных сетях, где ответ от устройства можно получить не сразу, можно увеличить количество пакетов через переменную $EchoCount. Кроме того, можно увеличить значения таймаутов ожидания ответа для разных протоколов через переменные $SNMPTimeout, $FTPTimeout, $HTTPTimeout. Манипуляции с этими переменными могут как увеличить, так и уменьшить общее время сканирования, влияя при этом на конечный результат.

Для каждого, ответившего по ICMP хоста, предпринимаются попытки последовательного опроса по протоколам SNMP/FTP/HTTP. Именно эти протоколы выбраны для опроса по той причине, что через них мы прямо или косвенно можем идентифицировать сетевой хост, как модуль управления APC NMC, не предоставляя при этом никаких учётных данных.

В первую очередь опрашиваем хост по протоколу SNMP, так как, в случае его доступности, мы сможем извлечь максимум необходимой нам информации. Опрос выполняется с использованием стандартной строки подключения "public", которая может быть изменена через переменную $SNMPCommunity. На практике бывает так, что администраторы, настраивая NMC, не всегда уделают должное внимание правильной настройке SNMP, не редко оставляя настройки в конфигурации по умолчанию. Тем самым они разрешают ничем не ограниченный удалённый сбор информации об устройстве и даже удалённое управление этим устройством.

Опрос по протоколу FTP для нас интересен тем, что встроенный в NMC FTP-сервер уже на этапе подключения (ещё до ввода учётных данных) бесстыдно раскрывает нам модель NMC и версию AOS в FTP-баннере.

FTP Server banner disclose NMC model and AOS version

И если на модуле NMC выключен или ограничен к использованию протокол SNMP, но при этом не выключен протокол FTP, то из этого баннера мы сможем получить интересующую нас информацию.

В последнюю очередь мы выполняем нехитрый запрос по протоколу HTTP, пытаясь получить с веб-сервера хоста определённый графический файл с логотипом APC - /images/smapc.gif. Положительный ответ от веб-сервера является косвенным признаком того, что нам отвечает модуль первого поколения NMC1 (на модуле второго поколения такого файла уже нет). Эта информация может оказаться полезна в том случае, если на опрашиваемом хосте не удалось получить данных по протоколам SNMP/FTP.

По окончании процесса сканирования результат выводится на консоль PowerShell в табличном виде с группировкой по моделям NMC, либо в виде списка, если была включена переменная $DataInList. Результирующие данные выгружаются в файл формата CSV, который в дальнейшем можно будет дополнительно анализировать в табличных редакторах или передавать профильным специалистам для проведения работ по устранению рисков. Путь к файлу отчёта указывается в переменной $CSVReportPath, а очистка значения этой переменной приводит к отключению формирования отчёта. При многократном запуске скрипта для разных подсетей данные могут накапливаться в одном файле, исключая при этом дублирование информации.

Интерпретация результатов работы скрипта

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

В этом примере мы видим, что обнаружен и идентифицирован модуль NMC AP9630 через доступные нам протоколы SNMP и FTP:

PowerShell script found NMC AP9630 via SNMP and FTP

Какие выводы можно сделать в данном случае:

  • Это модуль управления второго поколения NMC2 и это хорошо, так как вендор поддерживает эту модель и у нас имеется возможность обновления микрокода для закрытия уязвимостей Ripple20;
  • Текущая версия микрокода AOS ниже рекомендуемой на данный момент версии 6.9.6, и это уже совсем не хорошо. Необходимо оперативно выполнять обновление;
  • На модуле включен небезопасный протокол FTP, который, к тому же, раскрывает модель NMC и версию AOS. Следует отключить данный протокол;
  • Протокол SNMP на модуле активен, поэтому следует проверить текущие настройки протокола. Доступ к протоколу должен быть строго ограничен по средствам правил встроенного брандмауэра и списка контроля доступа службы SNMP-сервера.

В следующем примере обнаружен модуль NMC AP9618 через протоколы FTP и HTTP:

PowerShell script found NMC1 AP9618 via FTP

Выводы в этом случае следующие:

  • Это модуль первого поколения NMC1 с микрокодом AOS, имеющим уязвимости Ripple20. На этот модуль нет и не будет обновлений микрокода и требуется его жёсткая сетевая изоляция или замена на модуль NMC2/NMC3;
  • Если модуль продолжает эксплуатироваться, следует выключить на нём небезопасный протокол FTP.

Ещё один пример, в котором мы обнаружили два хоста, которые не ответили по протоколам SNMP/FTP, но ответили через протокол HTTP:

PowerShell script found NMC1 via HTTP

Похоже, что в данном случае мы обнаружили уязвимые модули управления NMC1, и, после подтверждения этой информации, необходимо выполнять работы по их сетевой изоляции или замене на NMC2/NMC3.

Устройства с встраиваемыми модулями NMC1

Помимо силовых устройств APC, использующих съёмные модули управления NMC в виде плат под разъём SmartSlot, встречаются устройства и со встроенными модулями управления. К таким устройствам можно отнести, например, автоматические переключатели нагрузки ATS (Automatic Transfer Switch).

Авто-переключатели APC ATS можно встретить в виде двух модельных рядов - AP77XX и AP44XX.

В первом типе моделей, например, у модели AP7723, используется встроенный модуль управления первого поколения NMC1. На мой запрос в тех.поддержку Schneider Electric о перспективах возможности обновления микрокода встроенного модуля управления (для закрытия уязвимостей Ripple20) для этого типа устройств был получен однозначный ответ о том, что выпуск обновлений производителем не планируется. Поэтому, учитывая невозможность физической замены модуля управления на более современную модель, единственным вариантом остаётся суровая сетевая изоляция такого устройства.

Переключатели AP44XX (например, модель AP4423) представляют собой более новую модельную линию и комплектуются более безопасными встроенными модулями NMC2, для которых на ранее упомянутой странице доступно обновление микрокода AOS до закрывающей уязвимости версии 6.9.6.

Несколько замечаний по настройке модулей NMC2/NMC3

Даже после замены модулей NMC1 на модули NMC2/NMC3 и обновления микрокода AOS до актуальной версии, закрывающей известные уязвимости, необходимо уделить особое внимание правильной настройке каждого такого модуля. А именно:

  • В обязательном порядке настраиваем и включаем механизм встроенного в модуль брандмауэра. Любой сетевой доступ к устройству должен настраиваться из принципа "что явно не разрешено - запрещено", а разрешающие правила должны быть описаны по принципу "разумный минимум", а не "открою … вдруг пригодится";
  • Выключаем все неиспользуемые, и тем более, небезопасные протоколы, такие как FTP, Telnet, HTTP(без TLS);
  • Внимательно настраиваем используемые протоколы SSH/HTTPS/SNMP, ограничивая возможность их удалённого использования. Например, доступ по протоколу SNMP следует ограничить только "на чтение" (отключить возможность записи) и разрешить подключения только с серверов мониторинга и, при необходимости, из подсетей администраторов;
  • Удаляем неиспользуемые встроенные учётные записи "device" и "readonly";
  • Настраиваем синхронизацию времени по протоколу NTP с доверенным источником (например, в сетях с поддержкой доменов это может быть контроллер домена). Правильное время на модуле управления гарантирует не только корректную регистрацию записей во встроенных логах, но и избавит от возможных ошибок в работе других протоколов (например, при использовании HTTPS);
  • Ну и раз уж мы упомянули о логировании, то неплохо бы настроить отсылку логов с устройства по протоколу Syslog на сервер сбора логов. Это может оказаться полезным при последующих разборах инцидентов.

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

Проверенный жизнью закон Мерфи гласит "Если что-то может пойти не так, пойдёт не так", поэтому задача администратора заключается в том, чтобы свести к минимуму всё то, что может "пойти не так".

Добавить комментарий