เครื่องมือ akheron
เขียนด้วยภาษา Python และออกแบบมาเพื่อช่วยให้มองเห็นการสื่อสารระหว่างชิป UART และช่วยในการทำความเข้าใจ การย้อนกลับ และจัดการการสื่อสารเหล่านั้นเพื่อแยกแยะการทำงานของอุปกรณ์ (ทั้งที่ตั้งใจและไม่ได้ตั้งใจ) ทำได้โดยรองรับโหมดการทำงานหลายรูปแบบ:
การสื่อสารระหว่างชิปผ่าน UART ยังคงเป็นตัวเลือกการออกแบบทั่วไปที่พบในอุปกรณ์หลายชนิด และมีลักษณะดังนี้:
+------------+ +------------+
| TXD +-------------------------->+ RXD |
| CHIP A | | CHIP B |
| RXD +<--------------------------+ TXD |
+------------+ +------------+
ในตัวอย่างนี้ ชิป A ส่งข้อมูลไปยังชิป B โดยการส่งข้อมูลออกพินการส่ง (TX) ของชิป A และชิป B จะได้รับข้อมูลขาเข้านั้นบนพินการรับ (RX) ชิป B ส่งข้อมูลออกพินการส่ง (TX) ที่ชิป A ได้รับบนพินรับ (RX) ของชิป A
แต่พวกเขาส่งอะไรกลับไปกลับมาระหว่างกัน?
ถ้าเราสร้างตัวเองให้เป็นเครื่องจักรที่อยู่ตรงกลาง เราจะค้นพบคำตอบ!
เครื่องมือ akheron
ได้รับการออกแบบมาให้ทำงานบนระบบที่มีพอร์ตอนุกรมสองพอร์ต (อะแดปเตอร์ USB เป็นอนุกรมนั้นใช้ได้ ตราบใดที่ระบบปฏิบัติการของระบบรองรับ) ทำหน้าที่เป็นพร็อกซีสำหรับการส่งการรับส่งข้อมูลระหว่างสองพอร์ตเหล่านั้น บางสิ่งเช่นนี้:
^ + ^ +
| v | v
+---------------------------------+
| |TXD1 RXD1| |TXD2 RXD2| |
| +---------+ +---------+ |
| UART 1 UART 2 |
| |
| Machine-in-the-Middle |
| (running Akheron Proxy) |
| |
+---------------------------------+
หากเราตัดการติดตามการสื่อสารระหว่างชิป A และชิป B ทางกายภาพแล้วกำหนดเส้นทางพวกมันไปยังพอร์ตอนุกรมของเครื่องที่อยู่ตรงกลาง เราจะสามารถดูว่าชิปเหล่านั้นส่งอะไรถึงกันผ่านการสื่อสาร UART กับ akheron
:
+------------+ +------------+
| 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
ได้จากหน้าต่างเทอร์มินัลในไดเร็กทอรีระดับบนสุดของ repo:
./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".
>