Антивирус на батниках в прошлом ㅡ пришло время сниффера на PowerShell


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


    Готовые варианты


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


    Tcpdump. Консольный и довольно известный сниффер для UNIX-систем.


    Пингуем 8.8.8.8 и любуемся выводом tcpdump.


    Wireshark. Пожалуй, сегодня это один из самых известных кроссплатформенных снифферов с GUI. Для расширения возможностей можно использовать скриптовый язык LUA. Также программой удобно анализировать трафик, захваченный на других устройствах в различных форматах.



    Продолжаем пинговать 8.8.8.8, но смотрим уже с помощью Wireshark.


    Microsoft Message Analyzer (в прошлом Microsoft Network Monitor). Помимо функций сниффера, может анализировать сообщения программ и устройств, системные события.



    Возможностей много, поэтому и интерфейс громоздкий.


    Наконец, WinDump. Аналог tcpdump, но для Windows.


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


    1. В маршрутизаторах Mikrotik сниффер стоит искать в Tools ― Packet Sniffer.


      Сниффер на Микротике.

      Любопытной возможностью является настройка потока (Streaming), позволяющая отправлять трафик с роутера прямо на компьютер с запущенным Wireshark.


    2. В маршрутизаторах D-link DFL также присутствует сниффер. Искать в Tools ― Packet Capture.


      Сниффер в D-Link DFL.

    К сожалению, через GUI пакеты не посмотреть, но можно скачать дамп трафика в формате .cap и открывать привычным анализатором Wireshark или Microsoft Message Analyzer.


    А теперь представим, что сниффер почему-то вот прямо сейчас не скачать, а инструмент нужен ― приступим к упражнениям с PowerShell.


    «Мощная оболочка» спешит на помощь


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


    Ловить пакеты будем из командной строки с использованием набора командлетов NetEventPacketCapture в Windows 8.1/2012R2. Для примера представим, что на компьютере с именем REIKO пользователь работает в терминальной сессии ― подглядим за его работой при помощи PowerShell.


    Для начала создадим подключение к компьютеру пользователя:


    $Cim = New-CimSession -ComputerName 'REIKO'

    После этого создадим сессию обработчика событий:


    New-NetEventSession -Name "Session01" -CimSession $Cim -LocalFilePath "C:\Windows\Temp\Trace.etl" -CaptureMode SaveToFile

    И добавим поставщика событий:


    Add-NetEventProvider -CimSession $Cim -Name 'Microsoft-Windows-TCPIP' -SessionName "Session01"

    Посмотреть всех возможных поставщиков можно командой logman query providers.

    После чего осталось запустить трассировку:


    Start-NetEventSession -Name "Session01" -CimSession $Cim

    Для остановки достаточно в той же команде заменить Start на Stop.


    Результаты можно посмотреть следующей командой:


    Get-WinEvent -Path "\\REIKO\C$\Windows\Temp\Trace.etl" -Oldest


    По результатам трассировки видно, что с компьютера не только работают на терминальном сервере, но и на самом компьютере кто-то сидит в локальной терминальной сессии.


    Для автоматизации процессов такой трассировки (привет коллегам из ИБ) системный администратор Dan Franciscus написал скрипт Invoke-PSTrace.


    С листингом скрипта можно ознакомиться под спойлером.
    #requires -Modules NetEventPacketCapture
    
    function Invoke-PSTrace {
    [OutputType([System.Diagnostics.Eventing.Reader.EventLogRecord])]
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true)]
            [string]$ComputerName,
            [switch]$OpenWithMessageAnalyzer,
            [pscredential]$Credential
        )  
            DynamicParam 
            {
                $ParameterName = 'ETWProvider' 
                $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
                $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
                $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
                $ParameterAttribute.Mandatory = $true
                $AttributeCollection.Add($ParameterAttribute)
                $arrSet = logman query providers | Foreach-Object {$_.split('{')[0].trimend()} | Select-Object -Skip 3 | Select-Object -SkipLast 2
                $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
                $AttributeCollection.Add($ValidateSetAttribute)
                $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
                $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
                return $RuntimeParameterDictionary
            }
    
        begin 
        {
            $ETWProvider = $PsBoundParameters[$ParameterName]
        }
    
        process 
        {
            #Remove any existing sessions
            Get-CimSession -ComputerName $ComputerName -ErrorAction SilentlyContinue | Remove-CimSession -Confirm:$False
            Get-NetEventSession -Name "Session1" -ErrorAction SilentlyContinue | Remove-NetEventSession -Confirm:$False
            Remove-Item -Path "C:\Windows\Temp\$ComputerName-Trace.etl" -Force -Confirm:$False -ErrorAction SilentlyContinue
            #Create new session
    
            try 
            {
                $Cim = New-CimSession -ComputerName $ComputerName -Credential $Credential -ErrorAction Stop
                New-NetEventSession -Name "Session1" -CimSession $Cim -LocalFilePath "C:\Windows\Temp\$ComputerName-Trace.etl" -ErrorAction Stop -CaptureMode SaveToFile | Out-Null
            }
    
            catch 
            {
                Write-Error $_
                Break
            }    
    
            Add-NetEventProvider -CimSession $Cim -Name $ETWProvider -SessionName "Session1" | Out-Null
            Start-NetEventSession -Name "Session1" -CimSession $Cim | Out-Null
    
            if (Get-NetEventSession -CimSession $Cim)
            {
                Read-Host 'Press enter to stop trace' | Out-Null
            }
    
            Stop-NetEventSession -Name 'Session1' -CimSession $Cim   
            Remove-NetEventProvider -Name $ETWProvider -CimSession $Cim  
            Remove-NetEventSession -Name 'Session1' -CimSession $Cim  
            Remove-CimSession -CimSession $Cim -Confirm:$False 
    
            if ($ComputerName -ne 'LocalHost')
            {
                Copy-Item -Path "\\$ComputerName\C$\Windows\Temp\$ComputerName-trace.etl" -Destination 'C:\Windows\Temp' -Force
            }
    
            Get-CimSession -ComputerName $ComputerName -ErrorAction SilentlyContinue | Remove-CimSession -Confirm:$False
    
            if ($OpenWithMessageAnalyzer)
            {
                 Start-Process -FilePath 'C:\Program Files\Microsoft Message Analyzer\MessageAnalyzer.exe' -ArgumentList "C:\Windows\Temp\$ComputerName-trace.etl"
            }
    
            else 
            {
                 Get-WinEvent -Path "C:\Windows\Temp\$ComputerName-trace.etl" -Oldest 
            }
        }
    }

    При запуске скрипта можно задать имя удаленной машины, поставщика событий, а при необходимости открыть трассировку в Microsoft Message Analyzer.



    Пример работы скрипта.


    Поскольку в PowerShell можно использовать инструментарий .NET, еще до появления набора командлетов NetEventPacketCapture в сообществе появился скрипт сниффера Get-Packet. Ознакомиться с одним из вариантов доработанного скрипта можно в блоге у автора, я же приведу пример его работы.



    Пингуем и смотрим трафик скриптом PowerShell.


    Из-за использования методов .NET работает значительно быстрее командлетов, но создать его «на коленке» и без доступа к интернету будет непросто. Тем не менее это неплохая альтернатива проприетарным программам.


    Старичок CMD тоже не промах


    Если вы также любите батники, как их люблю я, то можете заинтересоваться трассировкой без всяких PowerShell, средствами привычного netsh.exe. Помимо создания можно ещё и сконвертировать файл трассировки из формата .etl в удобные форматы вроде .txt и .html.


    Конечно, батники уходят в прошлое, но все же спрячу под спойлер аналогичный скрипт для CMD.
    @echo off
    
    rem запускаем трассировку
    netsh trace start InternetClient provider=Microsoft-Windows-TCPIP level=5 tracefile=trace.etl > nul
    rem ждем 5 секунд
    timeout 5 > nul
    
    rem останавливаем трассировку
    netsh trace stop > nul
    
    rem конвертируем файл .etl в удобный .txt, чтоб не открывать Microsoft Message Analyzer
    netsh trace convert input=trace.etl output=trace.txt dump=txt > nul
    
    rem посмотрим, кто у нас занимается RDP
    type trace.txt | findstr "3389"
    
    rem убираем временные файлы
    del trace*


    Результат работы скрипта.


    Подробнее с синтаксисом netsh для сбора трассировки можно ознакомится в документации Microsoft.


    С CMD самое большое неудобство в том, что без дополнительных утилит не так просто выполнить запуск скрипта, поэтому PsExec.exe или команду WMIC стоит держать под рукой:


    wmic /user:"username" /password:"password" /node:"computer" process call create "sniffer.bat > log.txt"

    В качестве «домашнего задания» предлагаю читателям запустить сбор трассировки на файловом сервере или сервере печати с помощью поставщика событий Microsoft-Windows-SMBServer. Особенно интересные результаты выходят, если с сервером работают как клиенты SMB v1, так и SMB v2 и старше.

    Сервер Молл
    серверы HP, Dell и Lenovo: новые и восстановленные

    Comments 3

      0
      А в нормальный pcap это дело сконвертировать можно? Иначе смысла как-то в этом мало…
        0

        message analyser умеет сохранять собранный etl в другие форматы.

        0
        Когда PS был 2-й приходилось делать так: system.net.sockets.socket([Net.Sockets.AddressFamily]::InterNetwork,[Net.Sockets.SocketType]::Raw,[Net.Sockets.ProtocolType]::IP)

        Only users with full accounts can post comments. Log in, please.