In this lab we will use a fake SSH server, sshesame 1
github.com/jaksi/sshesame
, and an interactive packet manipulation program, scapy 2
scapy.net/
, to disrupt an ongoing SSH session between victim and server, position ourself in the middle of the traffic, and capture the username and password victim is using.
For this lab our IP addresses are configured statically and are known to the attacker. It is also assumed that the attacker is on the local network. Lastly victim has been poorly configured to ignore changes to the host key. This is not entirely unreasonable as many users just ignore the warnings and clear out the known_hosts file when prompted anyway.
We will use scapy, a Python-based interactive packet manipulation program and library Scapy can forge or decode packets, send them on the wire, capture them, and match requests and replies. It can also handle tasks like scanning, tracerouting, probing, unit tests, attacks, and network discovery.
Be sure to either stop or delete this codespace when you are done by clicking the "Stop" button or the "Delete" button in the Codespaces tab of your repository.
WARNING:
Do NOT unzip this zip file on your host machine.
It is intended to be used only inside a Docker container.
Running it directly on your host may present a security risk.
Subsection5.7.3Continue with the MitM with Scapy Lab
This lab will require us to use three terminal windows/tabs: one for the docker-compose up command which will show the output of everything running in the background, one for the victim which will show an SSH session with the server, and one for the attacker which we will use to make the attack.
The diagram displays three stylized representations of terminal windows, each associated with a different role in a network security lab. The top-left window, titled "docker-compose up," shows the command "$ docker-compose up" being entered, indicating the initiation of services or an environment using Docker Compose. The top-right window, labeled "victim," shows the command "$ ssh server," suggesting the victim machine is establishing an SSH connection to a server. Positioned below these two, the third window is titled "attacker." Inside this window, the command "$ scapy" is shown, followed by the Scapy interactive prompt ">>>", indicating that the attacker is using the Scapy tool for packet manipulation. Together, these windows depict the initial command setup for an exercise or demonstration involving these three components.
Open three terminals and cd into the directory where you uncompressed the lab zip file in each of them. There should be a docker-compose.yml file and server, victim, and attacker directories in the directory you are in.
If you receive the error failed to create network scapy_testnet: Error response from daemon:Pool overlaps with other one on this address space check to see if you have other containers running and stop them. You may also need to run docker network prune to remove the old networks Docker built.
PS C:\Users\rxt1077\it230\labs\scapy> docker-compose run victim bash
Creating scapy_victim_run ... done
bash-5.0# ssh server
Warning: Permanently added 'server,172.20.0.5' (ECDSA) to the list of known hosts.
root@server's password: (3)
You are now logged into 'server' (presumably from 'victim') via SSH for this assignment.
Leave this connection open while you experiment with scapy from 'attacker'.
bf9ebe42a108:~#
Note5.7.5.
(3) The password is "password". It will not be echoed to the screen as you type it.
If for some reason the password will not work and you are sure you are typing it in correctly you can run the following command docker compose exec server passwd (note it’s passwd and not password). Type in the password twice and it will be reset to whatever you typed. What you type will not be echoed to the screen. You should now be able to ssh from victim to server with the password you typed in.
In the third terminal we’ll start by executing (recall that at this point it’s already running sshesame in the background) a BASH shell on attacker and configuring it to accept packets not only for its own IP address, but also for the server’s IP address. Once traffic is routed to us, this will allow attacker to also respond to packets destined for 172.20.0.5.
root@5195de3d330c:/# scapy
INFO: Can't import matplotlib. Won't be able to plot.
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
INFO: No IPv6 support in kernel
INFO: Can't import python-cryptography v1.7+. Disabled WEP decryption/encryption. (Dot11)
INFO: Can't import python-cryptography v1.7+. Disabled IPsec encryption/authentication.
WARNING: IPython not available. Using standard Python shell instead.
AutoCompletion, History are disabled.
aSPY//YASa
apyyyyCY//////////YCa |
sY//////YSpcs scpCY//Pp | Welcome to Scapy
ayp ayyyyyyySCP//Pp syY//C | Version 2.4.5
AYAsAYYYYYYYY///Ps cY//S |
pCCCCY//p cSSps y//Y | https://github.com/secdev/scapy
SPPPP///a pP///AC//Y |
A//A cyP////C | Have fun!
p///Ac sC///a |
P////YCpc A//A | To craft a packet, you have to be a
scccccp///pSP///p p//Y | packet, and learn how to swim in
sY/////////y caa S//P | the wires and in the waves.
cayCyayP//Ya pY/Ya | -- Jean-Claude Van Damme
sY/PsY////YCc aC//Yp |
sc sccaCY//PCypaapyCP//YSs
spCPY//////YPSps
ccaacs
>>>
You’ll notice that scapy’s prompt is >>>, just like python because it is python. Since we’re working in python, let’s make our lives easier by defining a few simple variables:
Now let’s see how scapy allows us to build packets. We’ll make an Ethernet frame, with an IP packet inside it, with an ICMP echo request in that, with the data being set to our name:
>>> ping = Ether()/IP(dst=server_ip)/ICMP()/"Ryan Tolboom" (7)
>>> ping.show() (8)
###[ Ethernet ]###
dst = 02:42:ac:14:00:05
src = 02:42:ac:14:00:07
type = IPv4
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 64
proto = icmp
chksum = None
src = 172.20.0.7
dst = 172.20.0.5
\options \
###[ ICMP ]###
type = echo-request
code = 0
chksum = None
id = 0x0
seq = 0x0
unused = ''
###[ Raw ]###
load = 'Ryan Tolboom'
>>> result = srp1(ping) (9)
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> result.show()
###[ Ethernet ]###
dst = 02:42:ac:14:00:07
src = 02:42:ac:14:00:05
type = IPv4
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 40
id = 62086
flags =
frag = 0
ttl = 64
proto = icmp
chksum = 0x301a
src = 172.20.0.5
dst = 172.20.0.7
\options \
###[ ICMP ]###
type = echo-reply
code = 0
chksum = 0xea7a
id = 0x0
seq = 0x0
unused = ''
###[ Raw ]###
load = 'Ryan Tolboom'
>>> server_mac = result[0][0].src
>>> server_mac
'02:42:ac:14:00:05'
Note5.7.9.Things to note in the previous codeblock.
(7) Scapy uses the ’/’ operator to nest protocols. This is my name in an ICMP packet, in an IP packet, in an Ethernet frame. Be sure you use your own name!
Your instructor may wish for you to take a screenshot of your scapy session at this point showing that you completed an ICMP echo request/response with your name in it.
We can also determine MAC addresses at Layer 2 with an ARP "who-has" request. Let’s craft and send a broadcast ethernet frame with an ARP "who-has" request for the victims’s IP address. The result will tell use what the victim’s MAC address is:
This is how an ARP exchange is supposed to work. We broadcast out asking what MAC we should use for a certain IP and we get a response from the person who legitimately has that MAC and IP.
This packet posits itself as coming from the server, it is aimed at the victim in both IP and MAC, but the MAC address that will be used to send it is ours (by default, we don’t specify with hwsrc). This means the victim will update their ARP cache such that frames destined for server go to attacker. This effectively reroutes all layer 2 traffic that was going to the server from the victim.
Now go back to the victim terminal with the SSH connection to server and try typing something. As soon as SSH has to send data, you will get a broken pipe error and the connection will drop. Faced with such a problem, what do you think most users will do? Probably try to reconnect, let’s try that too. Remember the password is "password".
You are now logged into 'server' (presumably from 'victim') via SSH for this assignment.
Leave this connection open while you experiment with scapy from 'attacker'.
bf9ebe42a108:~# client_loop: send disconnect: Broken pipe (11)
bash-5.0# ssh server
Warning: Permanently added 'server,172.20.0.5' (ECDSA) to the list of known hosts.
root@server's password:
#
Note5.7.12.
(11) This happened when they tried to type something right after we sent the malicious ARP.
Wait, that prompt looks a little different and where’s the message about staying logged in? It turns out the victim actually signed into our fake SSH server and their username and password were logged! Take a look at the output from the terminal running docker-compose up, you’ll see the credentials entered:
If you chose to use a Github codespace, don’t forget to stop or delete the codespace by clicking the "Stop" button or the "Delete" button in the Codespaces tab of your repository.