Intercept terminal sessions

Tip

Try it first

The interactive tutorial covers both session interception techniques in a safe environment — no target server needed:

  • Chapter 4 intercepts a non-interactive SSH command (exec channel).

  • Chapter 5 attaches to a live session via mirrorshell.

$ ssh-mitm tutorial

See Get Started for the full tutorial list.

Mirror a live SSH session

When a client connects through SSH-MITM and opens a shell, the proxy automatically creates a mirrorshell — a live copy of the session on a local port. The port number is printed immediately when the connection arrives:

INFO     ℹ created mirrorshell on port 34463. connect with: ssh -p 34463 127.0.0.1

Attach to it from a second terminal — no password required:

$ ssh -p 34463 127.0.0.1

Both sides of the connection now share the same session. Commands typed in either window appear in both, and output from the server is visible everywhere. The original user has no indication that a second party is connected.

Note

An auditor who attaches to the mirrorshell can also inject commands independently of what the user is doing. If the user steps away from their terminal, the auditor has full access to everything the user’s session can reach.

Intercept non-interactive commands

Non-interactive SSH commands (ssh user@host "command") use the exec channel type. SSH-MITM intercepts the exec channel before it reaches the real server and logs the exact command string:

INFO     session b3f1... - SSH Exec request: cat ~/.aws/credentials

The command is forwarded to the server and the response is returned to the client, so the user notices nothing unusual.

Record terminal sessions

To capture a full session for later review, enable session logging:

$ ssh-mitm server --session-log-dir ~/sshlogs --store-ssh-session

SSH-MITM creates a sub-directory per session with a typescript-compatible recording that can be replayed with scriptreplay:

$ tree ~/sshlogs
.
└── 7c43d2b2-51e7-4351-a468-c6768ea04d30
    ├── publickeys
    └── terminal_testuser@127.0.0.1
        ├── ssh_in_1665144225_7vjwtrur.log    # user input (includes passwords, control chars)
        ├── ssh_out_1665144225_70d5m57y.log   # server output
        └── ssh_time_1665144225_7qgv99bo.log  # timing file for scriptreplay

Replay a recorded session:

$ scriptreplay -t ssh_time_1665144225_7qgv99bo.log ssh_out_1665144225_70d5m57y.log