Convert Figma logo to code with AI

eladshamir logoInternal-Monologue

Internal Monologue Attack: Retrieving NTLM Hashes without Touching LSASS

1,375
242
1,375
1

Top Related Projects

4,078

Trying to tame the three-headed dog.

19,244

A little tool to play with Windows security

13,272

Impacket is a collection of Python classes for working with network protocols.

A tool to perform Kerberos pre-auth bruteforcing

Kerberos unconstrained delegation abuse toolkit

Quick Overview

Internal-Monologue is a tool designed to retrieve NTLM hashes without touching LSASS or SAM databases. It leverages the built-in Windows cryptographic functionality to calculate NetNTLM responses, providing a stealthy method for obtaining NTLM hashes on Windows systems.

Pros

  • Avoids detection by many antivirus and EDR solutions
  • Does not require elevated privileges to run
  • Can retrieve NTLM hashes for the current user and computer account
  • Useful for both offensive security testing and defensive analysis

Cons

  • Limited to retrieving hashes for the current user and computer account only
  • May not work on all Windows versions or configurations
  • Requires some understanding of Windows authentication mechanisms to use effectively
  • Not actively maintained (last update was in 2018)

Code Examples

As Internal-Monologue is a compiled executable rather than a code library, there are no code examples to provide. The tool is used by running the executable with various command-line arguments.

Getting Started

To use Internal-Monologue:

  1. Download the latest release from the GitHub repository.
  2. Open a command prompt or PowerShell window.
  3. Navigate to the directory containing the InternalMonologue.exe file.
  4. Run the tool with desired options:
InternalMonologue.exe -Downgrade False -Restore False -Impersonate True -Verbose False -Challenge 1122334455667788

This command runs Internal-Monologue without downgrading NTLM, with impersonation enabled, and using a specific challenge. Adjust the options as needed for your use case.

Competitor Comparisons

4,078

Trying to tame the three-headed dog.

Pros of Rubeus

  • More comprehensive Kerberos toolkit with broader functionality
  • Actively maintained with regular updates and improvements
  • Supports a wider range of attack vectors and techniques

Cons of Rubeus

  • Larger codebase, potentially more complex to use and understand
  • May be more likely to trigger security alerts due to its extensive features
  • Requires more setup and dependencies compared to Internal-Monologue

Code Comparison

Internal-Monologue:

public static string InvokeNetNTLMv1()
{
    return InvokeNetNTLM(1);
}

Rubeus:

public static string InvokeNetNTLMv1()
{
    return Crypto.KerberosPasswordHash(Interop.KERB_ETYPE.rc4_hmac, password, user, domain);
}

Both projects aim to extract and manipulate Windows authentication data, but Rubeus offers a more extensive set of features for Kerberos-related operations. Internal-Monologue focuses specifically on extracting NetNTLM hashes without sending traffic over the network, while Rubeus provides a broader range of Kerberos ticket manipulation capabilities.

The code comparison shows a simplified example of how both projects might approach generating NetNTLMv1 hashes, with Rubeus utilizing more advanced Kerberos-specific functions.

19,244

A little tool to play with Windows security

Pros of Mimikatz

  • More comprehensive functionality for credential extraction and manipulation
  • Actively maintained with frequent updates and improvements
  • Supports a wider range of Windows versions and authentication mechanisms

Cons of Mimikatz

  • Higher detection rate by antivirus and security software
  • Requires administrative privileges for most operations
  • More complex to use, with a steeper learning curve

Code Comparison

Internal-Monologue:

public static string InvokeNetNTLMv1()
{
    return InvokeNetNTLM(1);
}

Mimikatz:

BOOL kuhl_m_sekurlsa_pth(int argc, wchar_t * argv[])
{
    return kuhl_m_sekurlsa_pth_ex(argc, argv, MIMIKATZ_NT_BUILD_NUMBER, NULL);
}

Internal-Monologue focuses on a specific technique to extract NTLM hashes without touching LSASS, while Mimikatz offers a broader range of credential manipulation functions. Internal-Monologue is written in C#, making it easier to integrate into .NET projects, whereas Mimikatz is primarily written in C, providing lower-level access to Windows internals.

13,272

Impacket is a collection of Python classes for working with network protocols.

Pros of Impacket

  • Broader scope and functionality for network protocols and Windows interactions
  • More actively maintained with regular updates and contributions
  • Extensive documentation and examples for various use cases

Cons of Impacket

  • Larger codebase and dependencies, potentially more complex to use
  • Not specifically focused on NTLM authentication like Internal-Monologue
  • May require more setup and configuration for specific tasks

Code Comparison

Internal-Monologue focuses on retrieving NTLM hashes:

public static string InternalMonologueForCurrentUser()
{
    return InternalMonologue(Environment.UserName, Environment.UserDomainName);
}

Impacket provides a wider range of functionality, including NTLM-related operations:

from impacket.ntlm import getNTLM
from impacket.smb3structs import SMB2Packet

ntlm_hash = getNTLM(password)
smb_packet = SMB2Packet()

Internal-Monologue is more specialized for Windows NTLM hash extraction, while Impacket offers a comprehensive toolkit for various network protocols and Windows interactions. Internal-Monologue is simpler to use for its specific purpose, but Impacket provides more flexibility and features for broader security testing and network analysis tasks.

A tool to perform Kerberos pre-auth bruteforcing

Pros of Kerbrute

  • Written in Go, making it cross-platform and easy to distribute as a single binary
  • Focuses specifically on Kerberos bruteforcing, offering multiple attack modes
  • Actively maintained with regular updates and improvements

Cons of Kerbrute

  • Limited to Kerberos-related attacks, less versatile than Internal-Monologue
  • Requires more setup and configuration for specific attack scenarios
  • May be more easily detected by security tools due to its focused nature

Code Comparison

Internal-Monologue:

public static string InvokeNetNTLMv1()
{
    return InvokeNetNTLM(1);
}

Kerbrute:

func (k *Kerbrute) UserEnum(users []string) {
    k.userEnum(users, k.cfg.Threads)
}

Summary

Internal-Monologue is a PowerShell script that focuses on extracting NTLM hashes from the local system, while Kerbrute is a Go-based tool specifically designed for Kerberos bruteforcing. Internal-Monologue offers a broader range of internal Windows authentication mechanisms, whereas Kerbrute excels in targeted Kerberos attacks. The choice between the two depends on the specific use case and target environment.

Kerberos unconstrained delegation abuse toolkit

Pros of krbrelayx

  • Offers a suite of tools for Kerberos relay attacks, providing more comprehensive functionality
  • Includes features like SMB and LDAP server implementations for capturing and relaying tickets
  • Actively maintained with recent updates and contributions

Cons of krbrelayx

  • Requires more setup and configuration compared to Internal-Monologue's simpler approach
  • May be more complex to use for beginners or in simpler scenarios
  • Focuses specifically on Kerberos relay attacks, while Internal-Monologue has a broader scope

Code Comparison

Internal-Monologue:

public static string InvokeNetNTLMv1()
{
    return Invoke(Version.NetNTLMv1);
}

krbrelayx:

def parse_ticket(data):
    return decoder.decode(data, asn1Spec=krb5_asn1.AS_REP())[0]

The code snippets show different approaches:

  • Internal-Monologue uses C# and focuses on invoking NTLM authentication
  • krbrelayx uses Python and deals with parsing Kerberos tickets

Both projects serve different purposes in the realm of Windows authentication and attacks, with krbrelayx being more specialized for Kerberos relay attacks and Internal-Monologue offering a broader approach to extracting authentication information.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Internal Monologue Attack: Retrieving NTLM Hashes without Touching LSASS

Introduction

Mimikatz, developed by Benjamin Delpy (@gentilkiwi), is a well-regarded post-exploitation tool, which allows adversaries to extract plain text passwords, NTLM hashes and Kerberos tickets from memory, as well as perform attacks such as pass-the-hash, pass-the-ticket or build a golden ticket. Arguably, the primary use of Mimikatz is retrieving user credentials from LSASS process memory for use in post exploitation lateral movement.

Recently, Microsoft has introduced Credential Guard in Windows 10 Enterprise and Windows Server 2016, which uses virtualization-based security to isolate secrets, and it is very effective in preventing Mimikatz from retrieving hashes directly from memory. Also, Mimikatz has become a prime target of most endpoint protection solutions, and they are very aggressive in their efforts to detect and prevent it. Although these efforts are bound to fail, they are increasingly becoming a nuisance.

NetNTLM

NetNTLM is Windows’ challenge-response protocol that is mainly used where Kerberos is not supported. In NetNTLM, the server sends to the client a random 8-byte nonce as a challenge, and the client calculates a response that processes the challenge with the NTLM hash as the key, which is the MD4 hash of the user’s password. There are two versions of the NetNTLM authentication protocol, and both are vulnerable to certain attacks. Naturally, version 1 is significantly weaker than version 2, and therefore as of Windows Vista/2008 NetNTLM version 1 is disabled by default.

Pass the Hash

Because the NTLM hash is the key to calculating the response, an adversary does not necessarily need to obtain the victim’s plain text password to authenticate, hence retrieving the hash from LSASS memory using Mimikatz is almost equivalent to stealing a plain text password. Chris Hummel has published an article describing this technique in 2009 and named it “Pass the Hash” [https://www.sans.org/reading-room/whitepapers/testing/crack-pass-hash-33219].

Divide and Conquer

At Defcon 2012, Moxie Marlinspike and David Hulton presented a “Divide and Conquer” attack against NetNTLMv1 [https://www.youtube.com/watch?v=sIidzPntdCM]. In NetNTLMv1, the client receives the 8-byte challenge and calculates the response by encrypting it three times using DES with the different parts of the NTLM hash as the key. The key length for DES is effectively 56 bits, which is 7 bytes, while the NTLM hash is 16 bytes. NetNTLMv1 first encrypts the challenge using the first 7 bytes of the NTLM hash as the key, then encrypts the challenge using the next 7 bytes of the NTLM hash as the key, and finally encrypts the challenge using the last 2 bytes of the NTLM hash padded with null-bytes as the key. Effectively, this means that to retrieve the NTLM hash given a NetNTLMv1 challenge and response, an adversary must crack two 56-bit DES keys, which is exponentially easier than cracking a single 128-bit key. Moxie and Hulton developed custom hardware for this task and were able to brute-force the entire DES keyspace in less than 24 hours, which guarantees the successful retrieval of the NTLM hash within a reasonable time. Note that unlike dictionary or brute force attacks against the password, which may not be fruitful, this attack guarantees the successful retrieval of the NTLM hash.

Rainbow Tables

As demonstrated by ToorCon at https://crack.sh, it is feasible to create a complete rainbow table for all the possible NetNTLMv1 responses to a chosen challenge, such as 0x1122334455667788, which allows cracking the NTLM hash for a given response within minutes. The implication is that capturing a NetNTLMv1 response for the chosen challenge can be translated to the corresponding NTLM hash almost instantly, which is almost the equivalent to obtaining the password due to Pass the Hash.

NetNTLM Downgrade Attack

Mimikatz is commonly executed after the adversary has gained elevated access to the target host. At this point, the adversary can also change registry keys, such as LMCompatibilityLevel, which specifies whether the host should negotiate NetNTLMv1 or NetNTLMv2. The adversary can change the value to 0, 1 or 2, which enable NetNTLMv1 as a client, and then try to authenticate to a rogue SMB server that will capture the client’s response, as described in Optiv’s blog post [https://www.optiv.com/blog/post-exploitation-using-netntlm-downgrade-attacks].

Extended NetNTLM Downgrade Attack

Two more settings may stop the victim from negotiating a NetNTLMv1 response:

  1. NTLMMinClientSec - if configured to "Require NTLMv2 session security", the connection will fail if NTLMv2 protocol is not negotiated.
  2. RestrictSendingNTLMTraffic - if configured to "Deny all," the client computer cannot authenticate to a remote server with NetNTLM of any version. Similarly to the NetNTLM Downgrade attack, these settings can be changed if necessary. Note that unlike LMCompatibilityLevel, these settings are not configured by default to block NetNTLMv1 authentication.

Internal Monologue Attack

In secure environments, where Mimikatz should not be executed, an adversary can perform an Internal Monologue Attack, in which they invoke a local procedure call to the NTLM authentication package (MSV1_0) from a user-mode application through SSPI to calculate a NetNTLM response in the context of the logged on user, after performing an extended NetNTLM downgrade.

The Internal Monologue Attack flow is described below:

  1. Disable NetNTLMv1 preventive controls by changing LMCompatibilityLevel, NTLMMinClientSec and RestrictSendingNTLMTraffic to appropriate values, as described above.
  2. Retrieve all non-network logon tokens from currently running processes and impersonate the associated users.
  3. For each impersonated user, interact with NTLM SSP locally to elicit a NetNTLMv1 response to the chosen challenge in the security context of the impersonated user.
  4. Restore the original values of LMCompatibilityLevel, NTLMMinClientSec and RestrictSendingNTLMTraffic.
  5. Crack the NTLM hash of the captured responses using rainbow tables.
  6. Pass the Hash.

Update: Credential Guard Compatibility

I have recently retested Internal Monologue in environments with Credential Guard enabled and got negative results. I am not sure whether Credential Guard was not working properly in my test environment during the initial tests, or perhaps something changed since then. I updated the implementation to acquire a server token from AcceptSecurityContext dynamically and tamper with it to avoid the local authentication trap, so that if NetNTLMv1 without Extended Session Security fails, at least a NetNTLMv2 challenge-response can be captured.

Audit Trail

The Internal Monologue Attack is arguably stealthier than running Mimikatz because there is no need to inject code or dump memory to/from a protected process. Because the NetNTLMv1 response is elicited by interacting with NTLM SSP locally, no network traffic is generated, and the chosen challenge is not easily visible. No successful NTLM authentication event is recorded in the logs. The registry changes for the NetNTLM downgrade and stealing tokens/impersonating other users may trip indicators.

Proof of Concept

This tool is a proof of concept that implements the Internal Monologue Attack in C#. Porting the code to PowerShell may substitute certain event logs in the audit trail with others. The PoC code is far from perfect. Positive contributions and improvements are welcome.

Author

Elad Shamir from The Missing Link Security

Acknowledgements

  • Matthew Bush (3xocyte) from The Missing Link Security and Shaun Williamson (AusJock) from Beyond Binary for helping bounce off ideas and put this together
  • Moxie Marlinspike and David Hulton for their talk “Defeating PPTP VPNs and WPA2 Enterprise with MS-CHAPv2” at Defcon 20
  • Optiv for the NetNTLM Downgrade Attack
  • Bialek Joseph (clymb3r) for Invoke-TokenManupilation
  • MWR Labs for Incognito
  • Anton Sapozhnikov (snowytoxa) for Selfhash
  • Tim Malcom Vetter (malcomvetter) for multiple improvements
  • Marcello Salvati (byt3bl33d3r) for the DLL library addition