Wireshark: UART를 통한 원격 캡처

Wireshark: UART를 통한 원격 캡처

요약:UART를 통해 원격 출력을 tcpdump로컬로 올바르게 파이프하는 방법은 무엇입니까 wireshark?

나는 아무것도 설치할 수 없는 내장 장치를 통해 흐르는 패킷을 캡처하려고 합니다. 다행히 직렬 인터페이스에 getty가 열려 있고 tcpdump가 설치되어 있습니다. 안타깝게도 SSH도, 덤프캡도, tshark도 없습니다.

직접파이프

먼저 tty를 구성하고 파이프를 통해 데이터를 Wireshark에 전달하려고 했습니다.

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는 입력이 유효한 libpcap 형식이 아니라고 불평합니다. 확실히 명령이 다시 에코되어 이를 제거하지 못했기 때문입니다.

원시 PySerial 사용

그래서 배관 작동 방식을 제어하기 위해 Python 스크립트를 만들기로 결정했습니다.

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

스크립트가 어떻게 올바르게 끝나야 하는지에 대한 몇 가지 문제를 제외하면 생각만큼 잘 작동하지 않았습니다. Wireshark는 한동안 만족했지만 곧 입력이 손상되고 녹음이 중지됩니다. 나는 이것이 호스트의 tty가 여전히 일부 특수 문자(아마도 라인 피드 또는 캐리지 리턴)를 변환하기 때문이라고 생각합니다.

멍청해지기: PySerial을 통한 hexdump

그래서 나는 이것이 형편없다는 것을 알고 있지만 다른 아이디어가 없었기 때문에 이것이 내가 생각해낸 것입니다:

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

아쉽게도 이전 버전보다 조금 더 오래 작동하지만 프레임이 너무 크면 Wireshark에서 프레임이 너무 크고 길이가 정말 터무니없다는 문제가 발생합니다(예: -1562980309832). 녹음이 중지됩니다.

도와주세요! :)

tcpdump 옵션 을 사용하려고 시도했지만 -s적은 양으로도 작동하지 않았습니다.

나는 또한 picocom에서 배관을 시도했지만 아무 소용이 없었습니다.

따라서 작동할 UART 터널링 소프트웨어, stty의 (무능한) 사용에 대한 의견 또는 Python 스크립트에 대한 개선 사항에 대한 아이디어가 있으면 매우 기쁠 것입니다!

Wireshark는 2.2.5이고 tcpdump는 4.5.0이며 libpcap 1.5.0입니다.

답변1

마침내 실제로 작동하게 되었습니다. 이것은 완벽한 설정은 아니지만 적어도 작동하므로 나중에 누군가에게 도움이 될 수 있습니다.

나는 Python 스크립트를 사용했습니다.파이직렬UART를 통해 tcpdump를 시작하고 hexdump를 사용하여 바이너리 데이터가 tty 전사 규칙에 의해 수정되지 않고 링크를 통과할 수 있도록 합니다. 그런 다음 Python 스크립트는 데이터를 다시 변환하고 이를 Wireshark로 파이프합니다. 아래 스크립트는 질문의 스크립트와 비교하여 -v동일한 줄을 압축하지 않도록 hexdump에 옵션을 추가한 결과입니다.

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

관련 정보