tcpdump: jak uzyskać grepowalne wyjście?

13

Próbuję rozwiązać problem polegający na tym, że w urządzeniu mam tylko tcpdump. Chcę użyć tcpdump do filtrowania ruchu w sieci i wyświetlania tylko ruchu zawierającego określone ciągi.

Wykonuję następujące czynności:

tcpdump -nei eth0 -X | grep "something interesting"

Dane wyjściowe to widok szesnastkowy z 16 bajtami wiersza pr. Nie mogę grepować tych danych, ponieważ dane są prezentowane w wielu wierszach.

Czy istnieje sposób, aby tcpdump prezentował przechwycone dane w jednym wierszu? Umożliwiłoby to użycie grep do znalezienia interesujących pakietów.

Pies je świat kotów
źródło
1
cóż, nie mogę teraz tego przetestować, ale jeśli masz wiele linii, możesz to zrobić tr -d '\ n' lub grep -C 3, aby uzyskać kilka linii przed i po
barlop
@barlop, grep -C działa, ale zawodnie, ponieważ nigdy nie wiem, ile wierszy będzie w nagłówku, i nie zobaczę linii poniżej dopasowania. Polecenie tr tranzuje wszystkie dane wyjściowe do 1 wiersza, więc jest to trochę za dużo.
Pies zjada świat kotów
Następujące polecenie nie byłoby grep, ale tcpdump może dopasowywać ciągi szesnastkowe, które są zasadniczo grep bez żadnego wyrażenia regularnego. Możesz określić przesunięcie. Mam to zapisane w pliku (zrobione z windumpem, ale to tylko wersja Windows tcpdump, więc załóżmy tcpdump) tcpdump -nXr zfile "tcp [32: 4] = 0x47455420"
barlop
tcpdump -nei eth0 -X | grep --line-buffered "something interesting"zrobi, z powodów, których nie zauważyłem, moja ważna robocza odpowiedź została usunięta.
sjas

Odpowiedzi:

11

Dla tych, którzy nie mogą używać ngrep, oto jak użyć, awkaby tcpdumpwyjście zawartości pakietu było grepowalne.

Najpierw kilka przykładowych danych wyjściowych dostarczonych przez tcpdump -x, aby przedstawić zadanie przed:

$ tcpdump -xr dump.pcap 2>/dev/null
12:04:59.590664 IP 10.17.14.93.51009 > 239.194.1.9.51009: UDP, length 370
        0x0000:  4500 018e 0000 4000 fa11 7625 0a11 0e5d
        0x0010:  efc2 0109 c741 c741 017a 6f28 1120 2020
        0x0020:  3337 3030 3039 3031 3835 3635 3430 3130
...

I jest to skrypt do skopiowania i wklejenia, do awkktórego możesz przesłać dane wyjściowe

awk '{ if (match($0, /^[0-9]/, _)) { printf (NR == 1 ? "%s " : "\n%s "), $0; fflush() } else { sub(/^\s+0x[0-9a-z]+:\s+/, " "); gsub(" ", ""); printf "%s", $0 } } END { print ""; fflush() }'

w celu uzyskania następującego grepowalnego wyniku

12:04:59.590664 IP 10.17.14.93.51009 > 239.194.1.9.51009: UDP, length 370 4500018e00004000fa1176250a...
12:04:59.590798 IP 10.17.14.113.51011 > 239.194.1.11.51011: UDP, length 370 4500018e00004000fa11760f...
...

Poniżej znajduje się skomentowana wersja powyższego skryptu:

awk '
{
    # if this is a header line
    if (match($0, /^[0-9]/, _)) 
    {
        # print the header, but:

        # except for the first line,
        # we need to insert a newline,
        # as the preceding data lines
        # have been stripped of theirs

        # we also append a space to
        # separate header info from the
        # data that will get appended
        printf (NR == 1 ? "%s " : "\n%s "), $0
        # enforce line-buffering
        fflush()
    }
    # otherwise it is a data line
    else 
    {
        # remove the data address
        sub(/^\s+0x[0-9a-z]+:\s+/, " ");
        # remove all spaces
        gsub(" ", "");
        # print w/o newline
        printf "%s", $0 
    }
}
END
{
    # print final newline, as
    # the preceding data lines
    # have been stripped of theirs
    print ""
    # enforce line-buffering
    fflush()
}'
Eugene Beresovsky
źródło
2

Z strony tcpdumppodręcznika:

-A      Print each packet (minus its link level header) in ASCII.  Handy
        for capturing web pages.

Upewnij się, że korzystasz z -s 0opcji, aby upewnić się, że cały pakiet jest wyświetlany.

Flup
źródło
Dzięki, ale dane wciąż są prezentowane w wielu wierszach - wszędzie tam, gdzie na stronie znajdują się nowe linie. Mam problem z powiązaniem nagłówka (i reszty danych) z grepped output.
Pies zjada świat kotów
Właśnie zdałem sobie sprawę, dlaczego narzędzie to nazywa się awk tot
Pies jedzą świat kotów
1

Możesz rzucić okiem na ngreppolecenie:

ngrep -W single -d eth0 'regex to match' 'port 80'

Gdzie:

  • -W single określa formatowanie jednowierszowe
  • regex to match oznacza zrzucanie tylko pakietów zawierających określony ciąg znaków.
  • 'port 80' to filtr pcap do wąchania tylko pakietów z lub do portu 80
LatinSuD
źródło
1
Chciałbym użyć ngrep, ale nie ma takiego narzędzia - jest to urządzenie ...
Pies jedz świat kota
ngrep jest niesamowity. Szukałem godzin, które hosty generują ruch HTTP do mojego hosta. Z pojedynczym sudo ngrep „GET ..” znalazłem odpowiedź w ciągu minuty.
Bartosz Bilicki
0

Powodem, dla którego dane wyjściowe jest hex, jest -Xflaga. Próbować:

tcpdump -ni eth1 | grep something_interesting

Dostaniesz czytelne dane wyjściowe bezpośrednio do cli.

DaveA
źródło
Tak, ale nie będzie zawierał zawartości pakietu.
RalfFriedl
0

Nie mogłem zmusić skryptu awk do zrobienia tego, co chciałem, a ngrep nie działałby w sieci Ethernet przez USB, więc napisałem mały program w C, który dołącza do wyjścia wiersza przez tcpdump, aby były grepowe. Jest na https://gitlab.com/dargaud/TcpDumpJoin

dargaud
źródło