Com base no este documento , primeiro precisamos decidir qual é a nossa característica de identificação, para que o filtro é bem sucedido e só escolhe os batimentos cardíacos. Então, precisamos obter a representação hexadecimal desse identificador. Começando com a própria pulsação de saída (que é essencialmente apenas uma consulta / comando), é um comando admin e contém a seguinte cadeia:
replSetHeartBeat = 0x7265706c536574486561727446265174 (16 bytes)
Agora que temos a string de identificação, precisamos descobrir onde procurar dentro do TCP. O deslocamento é calculado da seguinte forma:
32 bytes para o TCP leva você ao protocolo de transferência do MongoDB , e depois:
- 4 bytes - tamanho da mensagem
- 4 bytes - ID do pedido
- 4 bytes - resposta a
- 4 bytes - opcode
- 4 bytes - sinalizadores
- 11 bytes - nome da coleta (sempre é o mesmo neste caso, mas pode variar em geral)
- 4 bytes - numtoskip
- 4 bytes - numtoreturn
- 4 bytes - comprimento do documento
- 1 byte - tipo
Portanto, o deslocamento total é: (32 + 4 + 4 + 4 + 4 + 4 + 11 + 4 + 4 + 4 + 1) = 76 bytes
Assim, você pensaria que algo assim é o que é necessário:
sudo tcpdump -i eth0 'tcp[76:16] = 0x7265706c536574486561727446265174'
Infelizmente, o tcpdump permite apenas correspondências de até 4 bytes por vez, portanto, é necessário dividi-lo em blocos de 4 x 4 bytes e usar um AND lógico para combinar as correspondências:
sudo tcpdump -i eth0 '(tcp[76:4] = 0x7265706c) and (tcp[80:4] = 0x53657448) and (tcp[84:4] = 0x65617274) and (tcp[88:4] = 0x62656174)'
Isso cobre a parte de saída da pulsação, mas e a resposta?
Felizmente a resposta no heartbeat é muito mais fácil de combinar - estamos procurando a parte rs: true do documento, e isso se traduz da seguinte maneira, cabendo facilmente em 4 bytes:rs : true = 0x72730001 (4 bytes)
Calculando o deslocamento de maneira semelhante (a única diferença real é um ID do cursor de 8 bytes em vez do nome da coleção de 11 bytes) obtemos um deslocamento de 73 bytes e isso nos leva a esse filtro:
sudo tcpdump -i eth0 'tcp[73:4] = 0x72730001'
Finalmente, vamos juntar tudo isso e adicionar algumas das minhas opções preferidas do tcpdump. No final, recebemos este comando:
sudo tcpdump -Xs0 -nnpi eth0 -w heartbeats.pcap '((tcp[76:4] = 0x7265706c) and (tcp[80:4] = 0x53657448) and (tcp[84:4] = 0x65617274) and (tcp[88:4] = 0x62656174)) or tcp[73:4] = 0x72730001'
(Testado com sucesso usando o MongoDB 2.4.4 no Mac OS X e no Linux)
É claro que isso também pode ser aplicado de forma mais geral, você só precisa descobrir os critérios de correspondência, deslocamento e byte correspondentes.
Para referência, você pode usar os mesmos critérios, mas com uma sintaxe ligeiramente diferente para testar esse tipo de filtragem no Wireshark. Os filtros Wireshark equivalentes para os critérios acima são:
tcp[76:16]==72:65:70:6c:53:65:74:48:65:61:72:74:62:65:61:74
tcp[73:4]==72:73:00:01