& "C:\Program Files\Wireshark shark.exe" -i Wi-Fi -l -T fields -e data "icmp[0]=8" | % { -join ($_ -split "(.{2})" -match "." | % { [char][byte]"0x$_"}) } - wyświetl payload pakietów ICMP
tshark to konsolowy brat znanego i lubianego sniffera pakietów - Wiresharka. Powyższy oneliner będzie nasłuchiwał na interfejsie o nazwie Wi-Fi pakietów ICMP Echo Request (pakiety ICMP o typie 8), czyli na popularne pingi. Następnie, będzie wyświetlał ładunek takich pakietów w wersji tekstowej. Co ciekawe, analizując domyślny ładunek takich pingów, możemy stwierdzić z jakiego systemu operacyjnego został wysłany.
W celu wygodniejszej pracy w konsoli z tsharkiem, moglibyśmy dodać katalog Wiresharka do zmiennej środowiskowej $env:PATH, co zostało omówione w /pl/0075:
[Environment]::SetEnvironmentVariable('Path', [Environment]::GetEnvironmentVariable('Path','Machine')+';C:\Program Files\Wireshark', 'Machine')
Moglibyśmy wtedy po prostu użyć:
tshark -i Wi-Fi -l -T fields -e data "icmp[0]=8" | % { -join ($_ -split "(.{2})" -match "." | % { [char][byte]"0x$_"}) }
Jak to działa — krok po kroku
Rozłóżmy onelinera na czynniki pierwsze:
& "C:\Program Files\Wireshark\tshark.exe
uruchamiamy aplikację tshark.exe wykorzystując operator wywołania &, który pozwala uruchomić aplikację, skrypt bądź blok skryptu,
-i Wi-Fi
wskazujemy interfejs, na którym chcemy sniffować pakiety, w naszym wypadku jest to interfejs Wi-Fi; by zobaczyć dostępne interfejsy sieciowe, możemy wykorzystać tshark a z parametrem -D, czyli: & "C:\Program Files\Wireshark\tshark.exe" -D lub jeśli Wireshark jest w zmiennej $env:PATH, po prostu: tshark -D,
-l
wyświetlaj natychmiast każdy przechwycony pakiet,
-T fields -e data
wskazujemy, że interesuje nas jedynie pole data pakietu, które w przypadku pakietów ICMP Echo request będzie zawierało payload pinga,
"icmp[0]=8"
definiujemy filtr, przekazując, że interesują nas jedynie pakiety ICMP o typie 8 (ICMP Echo request),
| % { ... }
każdy przechwycony pakiet wysyłamy do dalszego przetwarzania wykorzystując cmdlet ForEach-Object posiadający alias %,
-join ($_ -split "(.{2})" -match "." | % { [char][byte]"0x$_" })
jako, że tshark w polu danych zwróci strumień bajtów w postaci szesnastkowej, dzielimy cały string na dwuznakowe łańcuchy (wykorzystując trick z operatorem -split omówiony już w protipie aptm.in/protip/0072), następnie każdy taki szesnastkowy dwuliterowiec rzutujemy na bajt, a następnie na znak; operator -join na początku wyrażenia, składa nam tak wygenerowaną tablicę znaków w jeden string.