akheron
도구는 Python으로 작성되었으며 UART 칩 간 통신에 대한 가시성을 제공하고 이러한 통신을 이해, 반전 및 조작하여 장치 기능(의도한 것과 의도하지 않은 것 모두)을 식별하는 데 도움을 주도록 설계되었습니다. 이는 여러 가지 작동 모드를 지원하여 수행됩니다.
UART를 통한 칩 간 통신은 여전히 많은 장치에서 볼 수 있는 일반적인 설계 선택이며 다음과 같습니다.
+------------+ +------------+
| TXD +-------------------------->+ RXD |
| CHIP A | | CHIP B |
| RXD +<--------------------------+ TXD |
+------------+ +------------+
이 예에서 칩 A는 칩 A의 송신(TX) 핀으로 데이터를 전송하여 칩 B에 데이터를 보내고 칩 B는 수신(RX) 핀에서 들어오는 데이터를 수신합니다. 칩 B는 칩 A의 수신(RX) 핀에 있는 칩 A가 수신할 데이터를 전송(TX) 핀으로 보냅니다.
그런데 그들은 정확히 무엇을 서로 주고받고 있습니까?
우리 자신을 물리적인 중간 기계로 만들면 알아낼 수 있습니다!
akheron
도구는 두 개의 직렬 포트(시스템의 OS가 지원하는 한 USB-직렬 어댑터도 괜찮음)가 있는 시스템에서 실행되도록 설계되어 두 포트 간에 트래픽을 전송하기 위한 프록시 역할을 합니다. 다음과 같은 것 :
^ + ^ +
| v | v
+---------------------------------+
| |TXD1 RXD1| |TXD2 RXD2| |
| +---------+ +---------+ |
| UART 1 UART 2 |
| |
| Machine-in-the-Middle |
| (running Akheron Proxy) |
| |
+---------------------------------+
칩 A와 칩 B 사이의 통신 추적을 물리적으로 잘라낸 다음 이를 중간 기계의 직렬 포트로 라우팅하면 해당 칩이 akheron
사용하여 UART 통신을 통해 서로 무엇을 보내는지 확인할 수 있습니다.
+------------+ +------------+
| TXD +--------+ +------->+ RXD |
| CHIP A | | | | CHIP B |
| RXD +<-+ | | +--+ TXD |
+------------+ | | | | +------------+
| | | |
| v | v
+---------------------------------+
| |TXD1 RXD1| |TXD2 RXD2| |
| +---------+ +---------+ |
| UART 1 UART 2 |
| |
| Machine-in-the-Middle |
| (running Akheron Proxy) |
| |
+---------------------------------+
이러한 설정을 통해 akheron
사용할 준비가 되었습니다!
akheron
버전 0.1은 이러한 노력의 첫 번째 반복이며 개념 증명 코드로 탄생했습니다. 상호 작용을 위해 표준 REPL을 사용하는 명령줄 도구입니다.
akheron
도구에는 Python 3.6 이상이 필요하며 시스템의 직렬 포트와 인터페이스하기 위해 pyserial
라이브러리를 사용합니다. macOS 10.15와 Ubuntu 18.04 모두에서 테스트되었습니다.
pip install -r requirements.txt
저장소의 최상위 디렉터리에 있는 터미널 창에서 akheron
시작할 수 있습니다.
./akheron.py
많은 시스템에서는 직렬 장치에 대한 액세스가 제한되어 있습니다. 높은 권한으로 akheron
실행하지 않으려면 사용자 계정이 사용하려는 장치와 동일한 그룹에 속해 있는지 확인하십시오. Linux에서는 직렬 장치가 dialout
그룹의 구성원일 가능성이 높습니다. 해당 그룹에 사용자 계정을 추가하면(예: sudo usermod -a -G dialout $USER
) 장치에 액세스할 수 있습니다. 변경 사항을 보려면 로그아웃했다가 계정에 다시 로그인하거나 시스템을 재부팅해야 할 수도 있습니다.
실행하면 배너와 >
프롬프트가 표시됩니다.
$ ./akheron.py
######################################################
Akheron Proxy, UART proxy tool for inter-chip analysis
version 0.1
######################################################
>
이 프롬프트에서는 help
입력하여 액세스할 수 있는 여러 명령을 사용할 수 있습니다.
> help
Documented commands (type help <topic>):
========================================
capturedump checksumget delimset portget replaceset stop
capturestart checksumset help portset replay watch
capturestop delimget list replaceget start
Undocumented commands:
======================
exit quit version
help <command>
입력하면 특정 명령에 대한 추가 도움말을 얻을 수 있습니다.
> list
/dev/ttyS0
/dev/ttyUSB0
/dev/ttyUSB1
/dev/ttyUSB2
/dev/ttyUSB3
자세한 목록을 얻을 수도 있습니다.
> list -v
/dev/ttyS0
desc: ttyS0
hwid: PNP0501
/dev/ttyUSB0
desc: Quad RS232-HS
hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.0
/dev/ttyUSB1
desc: Quad RS232-HS
hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.1
/dev/ttyUSB2
desc: Quad RS232-HS
hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.2
/dev/ttyUSB3
desc: Quad RS232-HS
hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.3
다음 단계는 포트 간 트래픽을 전달하고 '감시'한 다음 트래픽 전달을 중지합니다.
> portset A /dev/ttyUSB1 115200
> portset B /dev/ttyUSB2 115200
> start
Data now PASSING between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2"...
> watch
Watching data passed between ports. Press CTRL-C to stop...
A -> B: 0x61 0x61 0x73 0x73 0x64 0x64
B -> A: 0x31 0x32 0x33 ^C
Watch mode exited.
> stop
Data now BLOCKED between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2".
>
이는 동일한 흐름이지만 메시지 시작 구분 기호가 0x37
로 설정되어 있습니다.
> portset A /dev/ttyUSB1 115200
> portset B /dev/ttyUSB2 115200
> delimset start 0x37
> start
Data now PASSING between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2"...
> watch
Watching data passed between ports. Press CTRL-C to stop...
A -> B: 0x37 0x71 0x77 0x65 0x65 0x72
0x37 0x64 0x66 0x61 0x64
0x37 0x73
0x37 0x68 0x68
B -> A: 0x37 0x6e 0x6d 0x62
0x37 0x69 0x69
A -> B: 0x37 0x61 0x73 0x64 ^C
Watch mode exited.
> stop
Data now BLOCKED between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2".
>
다음 단계에서는 포트 간에 트래픽을 전달하고, 이를 파일로 캡처하고, 감시한 다음, 캡처 내용을 중지 및 덤프하고, 트래픽 전달을 중지합니다.
> portset A /dev/ttyUSB1 115200
> portset B /dev/ttyUSB2 115200
> start
Data now PASSING between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2"...
> capturestart mycap.out
Saving captured traffic to "mycap.out"...
> watch
Watching data passed between ports. Press CTRL-C to stop...
A -> B: 0x31 0x32 0x33
B -> A: 0x33 0x32 0x31
A -> B: 0x20 0x20 0x20
B -> A: 0x36 0x36 0x37 0x38 0x39 ^C
Watch mode exited.
> capturestop
Capture stopped
> capturedump mycap.out
1: A -> B: 0x31 0x32 0x33
2: B -> A: 0x33 0x32 0x31
3: A -> B: 0x20 0x20 0x20
4: B -> A: 0x36 0x36 0x37 0x38 0x39
> stop
Data now BLOCKED between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2".
>
다음 단계에서는 이 순서대로 데이터(이 예에서는 단일 라인을 포함하는 캡처 파일)를 재생하여 포트 간 트래픽을 전달하는 방법을 보여줍니다.
0x64 0x61
시퀀스를 0x99 0x91
로 교체하고 재생하도록 교체 작업을 설정합니다(출력에서 대체된 데이터 참고).Checksum8Modulo256Plus1
로 메시지의 마지막 바이트를 업데이트하고 재생하는 체크섬 방법을 설정합니다. > portset A /dev/ttyUSB1 115200
> portset B /dev/ttyUSB2 115200
> start
Data now PASSING between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2"...
> replay /tmp/aaa
Replaying data from A -> B, press CTRL-C to exit watch mode...
A -> B: 0x61 0x73 0x64 0x61 0x73 0x64 ^C
Watch mode exited.
> replaceset A 0x64 0x61 -> 0x99 0x91
> replaceget
Replace port A pattern X -> pattern Y:
0x64 0x61 -> 0x99 0x91
Replace port B pattern X -> pattern Y:
> replay /tmp/aaa
Replaying data from A -> B, press CTRL-C to exit watch mode...
A -> B: 0x61 0x73 0x99 0x91 0x73 0x64 ^C
Watch mode exited.
> checksumset A 3
> checksumget
Replace on port A using checksum 'Checksum8Modulo256Plus1'
No replace checksum specified on port B
> replay /tmp/aaa
Replaying data from A -> B, press CTRL-C to exit watch mode...
A -> B: 0x61 0x73 0x99 0x91 0x73 0x72 ^C
Watch mode exited.
> stop
Data now BLOCKED between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2".
>