Cleanup Refactor and QoL Improvements #6
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
First off, thanks so much for dropping all this code! I was working on an internal project for these attacks before the release, and decided to bail on on that, bring over some of my code, and work to prep this code base for some long term support. This PR is quite large, but the majority of the changes are basic code cleanup and re-organization. I've also tried to add some bug fixes and stability improvements, but quality is in the eye of the beholder. I'll try to break down everything I went through, but there might be small things here/there that I forget about.
Code Cleanup
Most of this is relates to organizing the Interop code layer, structure definitions, breaking out component files, and cleaning up all the
DllImport
calls so they are more consistent. There were quite a few instances of structures being re-defined in different places under various names. I've also moved some code files around into the following rough layout:Some random specifics:
.editorconfig
file for OmniSharp, C# in VSCode, or Visual Studio so code formatting stays more consistent..gitignore
file to exclude common VS stuffEnumThing.Value
where it made senseProgram.cs
so it only focuses on parsing arguments, preparing for run tasks, validating conflictsWriteLine
statements with an#ifdef DEBUG
so it still applies when debugging. This can probably be done to many more statementsNtQueryProcessInformation
APIs or the like, we can simply use(IntPtr)(-1)
for the current process pseudo value, this cleans up the PEB parsing code quite a bit.SSPI Hooks / Buffers
A fair bit of my time was spent bringing over better implementations of
SecurityBuffer
andSecurityBufferDescriptor
from my code. This includes a lot of helper functions for enumerating buffers, their types, extracting theSEC_TOKEN
buffer value, and replacing it as well. This essentially means we no longer have to use byte searching code and hard-coded offsets when working withAcceptSecurityContext
. I haven't dug too deep into their memory management when external buffers are supplied, so we might need to revisit some of theDispose
functions.https://github.com/monoxgas/KrbRelay/blob/65bed1a77f1400fff00a162d39a780224e1ded6d/KrbRelay/Common/Hooks.cs#L150
In addition, I migrated the hooking to it's own
SSPIHooks
class, which handles installing the hooks, and uninstalling them when the class disposes. It will also not only hook insspicli.dll!SecTableW
, but also go hunting through module data sections that might have already stored the address to SSPI code. This is part of a larger effort to make the code compatible with in-memory assembly loads. Essentially removing the assumption that the code will load only once, in it's own process, and terminate that process after finishing. To the point above, I've also stripped out allEnvironment.Exit
calls, but it's a bit unclear to me what other issues this might introduce in edge cases.LDAP Client / Features
Generics
helpers for LDAP attacks, adding support for querying objects by different name, sid, or DN values. I also clarified the difference between Adding (Replacing), Removing, or Listing attributes on objects.-ssl
is passed when doing gMSA accounts, otherwise the LDAP query will fail to pull back themsDs-ManagedPassword
attributeThis is getting quite large, but I hope I've communicated the main points. I tried to strike a balance with better organization for long term support, and keeping the general project framework in tact. I didn't touch much of the spoofing code files.
Feel free to ping specific code blocks for comment, request changes, or ask any questions. I have (as I'm sure you do as well) as large TODO list of things I'd like to look at, but I didn't want stuff to get too far from the original fork.