Wireshark: Remote-Erfassung über UART

Wireshark: Remote-Erfassung über UART

Kurz zusammengefasst:Wie leitet man die Ausgabe einer Fernbedienung ordnungsgemäß über UART tcpdumpan eine lokale Steuerung weiter wireshark?

Ich versuche, Pakete zu erfassen, die durch ein eingebettetes Gerät fließen, auf dem ich nichts installieren kann. Glücklicherweise ist ein Getty auf der seriellen Schnittstelle geöffnet und tcpdump installiert. Leider kein SSH, kein Dumpcap, kein Tshark.

Direktleitung

Ich habe zuerst versucht, das TTY zu konfigurieren und die Daten über Pipes an Wireshark zu übergeben.

stty -F /dev/ttyUSB0 raw
stty -F /dev/ttyUSB0 -echo -echoe -echok
cat /dev/ttyUSB0 | wireshark -k -i -
# On another terminal:
echo "tcpdump -U -s0 -i eth0 -w - 2>/dev/null" > /dev/ttyUSB0

Wireshark beschwert sich, dass die Eingabe kein gültiges Libpcap-Format habe, sicherlich weil der Befehl zurückgesendet wird und ich es nicht geschafft habe, das zu beheben.

Verwenden von reinem PySerial

Daher habe ich beschlossen, ein Python-Skript zu erstellen, um die Funktionsweise der Rohrleitungen zu steuern:

import serial
import sys
import subprocess
import fcntl

def main(args):
    with serial.Serial('/dev/ttyUSB0', 115200, timeout=0) as ser:
        length = ser.write(b"tcpdump -U -s0 -i eth0 -w - 2> /dev/null\n") + 1
        # Discard the echoed command line
        while length > 0:
            discard = ser.read(length)
            length -= len(discard)
        # Spawn wireshark
        wireshark = subprocess.Popen(
            ["wireshark", "-k", "-i", "-"], stdin=subprocess.PIPE
        )
        # Pipe data from serial to wireshark's input
        while True:
            data = ser.read(256)
            wireshark.stdin.write(data)
            try:
                wireshark.stdin.flush()
            except BrokenPipeError as e:
                break
            if len(data) > 0: print(data)
        # Send "Ctrl+C" to tcpdump
        ser.write(b"\x03")
        wireshark.wait()
    return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

Abgesehen von einigen Problemen mit der korrekten Beendigung des Skripts funktionierte dies nicht so gut, wie ich es mir vorgestellt hatte. Wireshark funktioniert eine Zeit lang einwandfrei, aber schon bald wird die Eingabe beschädigt und die Aufzeichnung stoppt. Ich denke, das liegt daran, dass das TTY auf dem Host immer noch einige Sonderzeichen konvertiert, wahrscheinlich den Zeilenvorschub oder den Wagenrücklauf.

Wird langsam dumm: Hexdump über PySerial

Ich weiß, das klingt blöd, aber da mir keine anderen Ideen eingefallen sind, ist mir Folgendes eingefallen:

import serial
import sys
import subprocess
import binascii

def main(args):
    with serial.Serial('/dev/ttyUSB0', 115200, timeout=5) as ser:
        # Spawn tcpdump on the host and convert the raw output to stupid hex format
        # We need hexdump -C because that's the only format that doesn't mess up with the endianess
        length = ser.write(b"tcpdump -U -s256 -i eth0 -w - 2> /dev/null | hexdump -C\n")
        # Discard command line that is echoed
        discard = ser.readline()
        # Spawn wireshark
        wireshark = subprocess.Popen(
            ["wireshark", "-k", "-i", "-"], stdin=subprocess.PIPE
        )
        while True:
            # Process each line separately
            data = ser.readline().decode('ascii')
            elements = data.split()
            # Remove the address and ascii convertion of hexdump and spaces
            hexa = "".join(elements[1:17])
            # Convert back hex to binary
            real_data = binascii.unhexlify(hexa)
            # Feed to the shark
            wireshark.stdin.write(real_data)
            try:
                wireshark.stdin.flush()
            except BrokenPipeError as e:
                break
        # Stop tcpdump
        ser.write(b"\x03")
        wireshark.wait()
    return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

Obwohl es etwas länger funktioniert als die vorherige Version, zeigt Wireshark leider ein Problem an, wenn die Frames etwas zu groß sind und besagt, dass der Frame zu groß ist und eine tatsächlich lächerliche Länge aufweist (wie -1562980309832), und die Aufzeichnung wird erneut gestoppt.

Bitte helfen Sie! :)

-sSie können feststellen, dass ich versucht habe, mit der Option „tcpdump“ zu spielen , aber es hat nicht funktioniert, nicht einmal mit geringen Mengen.

Ich habe auch versucht, die Weiterleitung von Picocom zu übernehmen, jedoch ohne Erfolg.

Wenn Sie also eine Idee oder eine funktionierende UART-Tunneling-Software haben, einen Kommentar zu meinem (inkompetenten) Einsatz von stty abgeben oder eine Verbesserung meiner Python-Skripte vorschlagen möchten, würde ich mich sehr freuen!

Wireshark ist 2.2.5, tcpdump ist 4.5.0 mit libpcap 1.5.0.

Antwort1

Endlich habe ich es wirklich zum Laufen gebracht. Das ist nicht das perfekte Setup, aber zumindest funktioniert es, sodass es vielleicht in Zukunft jemandem helfen kann.

Ich habe ein Python-Skript darüber verwendetPySerialum tcpdump über den UART zu starten und hexdump zu verwenden, damit die Binärdaten die Verbindung durchlaufen können, ohne von den TTY-Transkriptionsregeln geändert zu werden. Dann konvertiert das Python-Skript die Daten zurück und leitet sie an Wireshark weiter. Das folgende Skript ist das Ergebnis. Im Vergleich zu dem aus der Frage habe ich die -vOption zu hexdump hinzugefügt, damit es nicht versucht, gleiche Zeilen zu komprimieren.

import serial
import sys
import subprocess
import binascii

def main(args):
    with serial.Serial('/dev/ttyUSB0', 115200, timeout=5) as ser:
        # Spawn tcpdump on the host and convert the raw output to stupid hex format
        # We need hexdump -C because that's the only format that doesn't mess up with the endianess
        length = ser.write(b"tcpdump -U -s256 -i eth0 -w - 2> /dev/null | hexdump -Cv\n")
        # Discard command line that is echoed
        discard = ser.readline()
        # Spawn wireshark
        wireshark = subprocess.Popen(
            ["wireshark", "-k", "-i", "-"], stdin=subprocess.PIPE
        )
        while True:
            # Process each line separately
            data = ser.readline().decode('ascii')
            elements = data.split()
            # Remove the address and ascii convertion of hexdump and spaces
            hexa = "".join(elements[1:17])
            # Convert back hex to binary
            real_data = binascii.unhexlify(hexa)
            # Feed to the shark
            wireshark.stdin.write(real_data)
            try:
                wireshark.stdin.flush()
            except BrokenPipeError as e:
                break
        # Stop tcpdump
        ser.write(b"\x03")
        wireshark.wait()
    return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

verwandte Informationen