{"id":29603148,"url":"https://github.com/rapid7/akheron-proxy","last_synced_at":"2025-07-20T14:06:02.039Z","repository":{"id":41982338,"uuid":"261897221","full_name":"rapid7/akheron-proxy","owner":"rapid7","description":"UART proxy tool for inter-chip analysis.","archived":false,"fork":false,"pushed_at":"2025-03-14T20:20:25.000Z","size":163,"stargazers_count":16,"open_issues_count":0,"forks_count":8,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-14T21:29:25.218Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rapid7.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-06T22:58:31.000Z","updated_at":"2025-03-14T20:20:29.000Z","dependencies_parsed_at":"2022-08-12T01:20:33.498Z","dependency_job_id":"5a82cb52-3916-4e40-ab87-62dbe0f2a0ac","html_url":"https://github.com/rapid7/akheron-proxy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rapid7/akheron-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fakheron-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fakheron-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fakheron-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fakheron-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rapid7","download_url":"https://codeload.github.com/rapid7/akheron-proxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fakheron-proxy/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266135685,"owners_count":23881803,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-20T14:06:00.968Z","updated_at":"2025-07-20T14:06:02.027Z","avatar_url":"https://github.com/rapid7.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Akheron Proxy\n\n## Introduction\n\nThe `akheron` tool is written in python and designed to help lend visibility to UART inter-chip communications and aid in understanding, reversing, and manipulating those communications to discern device functionality (both intended and unintended).  It does this by supporting several modes of operation:\n\n* Bridging communications - proxies data between devices while providing visibility to the data\n* Capturing communications - saves UART communication data to a file for examination and replay\n* Replaying communications - loads captured data from a file and replays it on the UART connection\n  * Supports replay with user-provided pattern match and replacement values\n  * Supports replay with checksum recalculation and message updates\n\n## Physical setup\n\nInter-chip communication via UART is still a common design choice found in many devices, and it looks something like this:\n\n```\n+------------+                           +------------+\n|        TXD +--------------------------\u003e+ RXD        |\n| CHIP A     |                           |     CHIP B |\n|        RXD +\u003c--------------------------+ TXD        |\n+------------+                           +------------+\n\n```\n\nIn this example, chip A sends data to chip B by sending data out chip A's transmit (TX) pin and chip B receives that incoming data on its receive (RX) pin. Chip B sends data out its transmit (TX) pin to be received by chip A on chip A's receive (RX) pin.\n\nBut what exactly are they sending back and forth between each other?\n\nIf we make ourselves a physical machine-in-the-middle, we can find out!\n\nThe `akheron` tool is designed to be run on a system with two serial ports (USB-to-serial adapters are fine, so long as the OS of the system supports them), acting as a proxy for sending traffic between those two ports.  Something like this:\n\n```\n    ^     +             ^     +\n    |     v             |     v\n+---------------------------------+\n| |TXD1 RXD1|         |TXD2 RXD2| |\n| +---------+         +---------+ |\n|   UART  1             UART  2   |\n|                                 |\n|     Machine-in-the-Middle       |\n|    (running Akheron Proxy)      |\n|                                 |\n+---------------------------------+\n```\n\nIf we physically cut the communication traces between chip A and chip B and then route them to our machine-in-the-middle's serial ports, we'll be able to see what those chips are sending each other over their UART communications with `akheron`:\n\n```\n+------------+                               +------------+\n|        TXD +--------+             +-------\u003e+ RXD        |\n| CHIP A     |        |             |        |     CHIP B |\n|        RXD +\u003c-+     |             |     +--+ TXD        |\n+------------+  |     |             |     |  +------------+\n                |     |             |     |\n                |     v             |     v\n            +---------------------------------+\n            | |TXD1 RXD1|         |TXD2 RXD2| |\n            | +---------+         +---------+ |\n            |   UART  1             UART  2   |\n            |                                 |\n            |     Machine-in-the-Middle       |\n            |    (running Akheron Proxy)      |\n            |                                 |\n            +---------------------------------+\n```\n\nWith a setup as such, `akheron` is ready for use!\n\n## Command-Line Tool\n\n`akheron` version 0.1 is the first iteration on this effort and born of proof-of-concept code. It is a command-line tool, using a standard REPL for interaction.\n\n### Requirements\n\nThe `akheron` tool requires Python 3.6 or later, and uses the [`pyserial`](https://pyserial.readthedocs.io/en/latest/pyserial.html) library for interfacing with the system's serial ports. It was tested on both macOS 10.15 and Ubuntu 18.04.\n\n#### Install Requirements\n```\npip install -r requirements.txt\n```\n\n### Starting the tool\n\nYou can start `akheron` from a terminal window in the top-level directory of the repo:\n\n`./akheron.py`\n\nOn many systems, access to serial devices is restricted. To avoid running `akheron` with elevated privileges, ensure that your user account belongs to the same group as the device you wish to use. On Linux, the serial device is likely a member of the `dialout` group. Adding your user account to that group (e.g. `sudo usermod -a -G dialout $USER`) should allow you to access the device. In order for you to see the changes, you may need to logout and log back in to your account, or possibly reboot the system.\n\nOnce running, you'll see a banner and a `\u003e ` prompt:\n\n```\n$ ./akheron.py\n\n######################################################\nAkheron Proxy, UART proxy tool for inter-chip analysis\n                     version 0.1\n######################################################\n\n\u003e \n```\n\nA number of commands are available at this prompt, which you can access by typing `help`:\n\n```\n\u003e help\n\nDocumented commands (type help \u003ctopic\u003e):\n========================================\ncapturedump   checksumget  delimset  portget     replaceset  stop\ncapturestart  checksumset  help      portset     replay      watch\ncapturestop   delimget     list      replaceget  start\n\nUndocumented commands:\n======================\nexit  quit  version\n```\n\nYou can get more help about a specific command by typing `help \u003ccommand\u003e`.\n\n## Examples\n\n### List available serial ports\n\n```\n\u003e list\n/dev/ttyS0\n/dev/ttyUSB0\n/dev/ttyUSB1\n/dev/ttyUSB2\n/dev/ttyUSB3\n```\n\nYou can also get a verbose listing:\n```\n\u003e list -v\n/dev/ttyS0\n    desc: ttyS0\n    hwid: PNP0501\n/dev/ttyUSB0\n    desc: Quad RS232-HS\n    hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.0\n/dev/ttyUSB1\n    desc: Quad RS232-HS\n    hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.1\n/dev/ttyUSB2\n    desc: Quad RS232-HS\n    hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.2\n/dev/ttyUSB3\n    desc: Quad RS232-HS\n    hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.3\n```\n\n### Forward traffic and watch\n\nThe following steps will forward traffic between ports, 'watch' it, then stop traffic forwarding:\n\n```\n\u003e portset A /dev/ttyUSB1 115200\n\u003e portset B /dev/ttyUSB2 115200\n\u003e start\nData now PASSING between ports \"/dev/ttyUSB1\" \u003c-\u003e \"/dev/ttyUSB2\"...\n\u003e watch\nWatching data passed between ports. Press CTRL-C to stop...\nA -\u003e B: 0x61 0x61 0x73 0x73 0x64 0x64 \nB -\u003e A: 0x31 0x32 0x33 ^C\nWatch mode exited.\n\u003e stop\nData now BLOCKED between ports \"/dev/ttyUSB1\" \u003c-\u003e \"/dev/ttyUSB2\".\n\u003e \n```\n\n#### With start-of-message delimiter\n\nThis is the same flow, but with a start-of-message delimiter of `0x37` set:\n\n```\n\u003e portset A /dev/ttyUSB1 115200\n\u003e portset B /dev/ttyUSB2 115200\n\u003e delimset start 0x37\n\u003e start\nData now PASSING between ports \"/dev/ttyUSB1\" \u003c-\u003e \"/dev/ttyUSB2\"...\n\u003e watch\nWatching data passed between ports. Press CTRL-C to stop...\nA -\u003e B: 0x37 0x71 0x77 0x65 0x65 0x72 \n        0x37 0x64 0x66 0x61 0x64 \n        0x37 0x73 \n        0x37 0x68 0x68 \nB -\u003e A: 0x37 0x6e 0x6d 0x62 \n        0x37 0x69 0x69 \nA -\u003e B: 0x37 0x61 0x73 0x64 ^C\nWatch mode exited.\n\u003e stop\nData now BLOCKED between ports \"/dev/ttyUSB1\" \u003c-\u003e \"/dev/ttyUSB2\".\n\u003e\n```\n\n### Forward and capture (and watch) traffic\n\nThe following steps will forward traffic between ports, capture it to a file, watch it, then stop and dump capture contents, and then stop traffic forwarding:\n\n```\n\u003e portset A /dev/ttyUSB1 115200\n\u003e portset B /dev/ttyUSB2 115200\n\u003e start\nData now PASSING between ports \"/dev/ttyUSB1\" \u003c-\u003e \"/dev/ttyUSB2\"...\n\u003e capturestart mycap.out\nSaving captured traffic to \"mycap.out\"...\n\u003e watch\nWatching data passed between ports. Press CTRL-C to stop...\nA -\u003e B: 0x31 0x32 0x33 \nB -\u003e A: 0x33 0x32 0x31 \nA -\u003e B: 0x20 0x20 0x20 \nB -\u003e A: 0x36 0x36 0x37 0x38 0x39 ^C\nWatch mode exited.\n\u003e capturestop\nCapture stopped\n\u003e capturedump mycap.out\n    1: A -\u003e B: 0x31 0x32 0x33\n    2: B -\u003e A: 0x33 0x32 0x31\n    3: A -\u003e B: 0x20 0x20 0x20\n    4: B -\u003e A: 0x36 0x36 0x37 0x38 0x39\n\u003e stop\nData now BLOCKED between ports \"/dev/ttyUSB1\" \u003c-\u003e \"/dev/ttyUSB2\".\n\u003e \n```\n\n### Forward and replay traffic, then replay-with-pattern-replace, then replay-with-pattern-replace-and-recalculate-checksum\n\nThe following steps show forwarding traffic between ports with replay of data (in this example, a capture file that contains a single line) in this sequence:\n\n1. replay captured data exactly as it was originally captured (i.e. no modification)\n1. set a replace operation to swap `0x64 0x61` sequences with `0x99 0x91` and replay (note the substituted data in the output)\n1. set a checksum method to update the final byte of the message with a `Checksum8Modulo256Plus1` of the preceding bytes and replay\n\n\n```\n\u003e portset A /dev/ttyUSB1 115200\n\u003e portset B /dev/ttyUSB2 115200\n\u003e start\nData now PASSING between ports \"/dev/ttyUSB1\" \u003c-\u003e \"/dev/ttyUSB2\"...\n\u003e replay /tmp/aaa\nReplaying data from A -\u003e B, press CTRL-C to exit watch mode...\nA -\u003e B: 0x61 0x73 0x64 0x61 0x73 0x64 ^C\nWatch mode exited.\n\u003e replaceset A 0x64 0x61 -\u003e 0x99 0x91\n\u003e replaceget\nReplace port A pattern X -\u003e pattern Y:\n  0x64 0x61 -\u003e 0x99 0x91\nReplace port B pattern X -\u003e pattern Y:\n\u003e replay /tmp/aaa\nReplaying data from A -\u003e B, press CTRL-C to exit watch mode...\nA -\u003e B: 0x61 0x73 0x99 0x91 0x73 0x64 ^C\nWatch mode exited.\n\u003e checksumset A 3\n\u003e checksumget\nReplace on port A using checksum 'Checksum8Modulo256Plus1'\nNo replace checksum specified on port B\n\u003e replay /tmp/aaa\nReplaying data from A -\u003e B, press CTRL-C to exit watch mode...\nA -\u003e B: 0x61 0x73 0x99 0x91 0x73 0x72 ^C\nWatch mode exited.\n\u003e stop\nData now BLOCKED between ports \"/dev/ttyUSB1\" \u003c-\u003e \"/dev/ttyUSB2\".\n\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frapid7%2Fakheron-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frapid7%2Fakheron-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frapid7%2Fakheron-proxy/lists"}