Все мы в качестве сниффера обычно используем готовые программы. Однако, можно обойтись и встроенными средствами 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 и старше.

Поделиться с друзьями
-->

Комментарии (3)


  1. vanyas
    22.07.2017 12:34

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


    1. avelor
      25.07.2017 10:47

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


  1. andyrootman
    22.07.2017 12:59

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