tcpdump: como obter saída grepable?

13

Estou tentando solucionar um problema em que só tenho o tcpdump disponível em um dispositivo. Eu quero usar o tcpdump para filtrar o tráfego da web e exibir apenas o tráfego que contém determinadas strings.

Eu faço o seguinte:

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

A saída é um hexview com 16 bytes de linha pr. Não consigo grep esses dados, pois os dados são apresentados em várias linhas.

Existe uma maneira do tcpdump apresentar os dados capturados em uma única linha? Isso tornaria possível usar o grep para encontrar pacotes interessantes.

O cão come o mundo do gato
fonte
1
bem, não posso testar isso agora, mas se você tiver várias linhas, poderá fazer | tr -d '\ n' ou grep -C 3 para obter algumas linhas antes e depois do
barlop
@barlop, grep -C meio que funciona, mas não é confiável, pois eu nunca sei quantas linhas o cabeçalho terá e não vou ver as linhas abaixo da partida. O comando tr equilibra toda a saída para 1 linha, então é um pouco demais.
Dog eat cat world
O seguinte não seria grep, mas o tcpdump pode corresponder a strings por hex, o que é essencialmente grep sem nenhum regex. Você pode especificar um deslocamento. Tenho esta anotou em um arquivo (feito com WinDump mas isso é apenas uma versão Windows do tcpdump assim assumir tcpdump) tcpdump -nXr zfile "tcp [32: 4] = 0x47455420"
barlop
tcpdump -nei eth0 -X | grep --line-buffered "something interesting"fará, por razões não discernidas, minha resposta de trabalho válida foi excluída.
sjas 26/03/19

Respostas:

11

Para pessoas como você, que não podem usar ngrep, eis como usar awkpara tornar a tcpdumpsaída do conteúdo do pacote aceitável.

Primeiro, alguns exemplos de saída, conforme fornecido por tcpdump -x, para apresentar a tarefa a seguir:

$ 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
...

E este é o script de copiar e colar para o qual awkvocê pode canalizar a saída

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() }'

para obter a seguinte saída grepable

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...
...

Abaixo está uma versão comentada do script acima:

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
fonte
2

Na página de tcpdumpmanual:

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

Certifique-se de usar também a -s 0opção para garantir que o pacote inteiro seja exibido.

Flup
fonte
Obrigado, mas os dados ainda são apresentados em linhas de multiplicação - onde quer que a página tenha novas linhas. Estou com problemas para associar o cabeçalho (e o restante dos dados) à saída grepped.
Dog eat cat world
Eu só percebi por que a ferramenta é chamada awk ala
cão come o mundo do gato
1

Você pode querer dar uma olhada no ngrepcomando:

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

Onde:

  • -W single especifica a formatação de linha única
  • regex to match significa apenas despejar pacotes contendo determinada string.
  • 'port 80' é um filtro pcap para cheirar apenas pacotes da ou para a porta 80
LatinSuD
fonte
1
Gostaria de usar o ngrep, mas não existe essa ferramenta - é um aparelho ...
Dog eat cat world
ngrep é incrível. Eu estava pesquisando por horas qual host está gerando tráfego HTTP para o meu host. Com o sudo ngrep único "GET ..", a resposta foi encontrada em minutos.
Bartosz Bilicki
0

A razão pela qual sua saída é hexadecimal é a -Xbandeira. Experimentar:

tcpdump -ni eth1 | grep something_interesting

Você obterá a saída legível despejada diretamente no CLI.

DaveA
fonte
Sim, mas não conterá o conteúdo do pacote.
RalfFriedl 31/05/19
0

Não consegui que o script awk fizesse o que eu queria e o ngrep não funcionaria em uma Ethernet sobre USB. Por isso, escrevi um pequeno programa C para juntar as linhas de saída do tcpdump para que sejam grepable. É em https://gitlab.com/dargaud/TcpDumpJoin

dargaud
fonte