Windows Services passwords stored in the LSA

Table des matières :


The Service Control Manager is a remote procedure call (RPC) server allowing to control services deployed on a Windows machine.

The Service Control Manager (SCM) is a crucial component of the Windows operating system. It is responsible for starting, stopping, and interacting with system services. These services include core system features such as networking, security, and user interface components. The SCM provides a standardized interface for other components of the system to interact with these services, and it also maintains status information about them. This includes information about which services are running, which are stopped, and any errors that may have occurred.

In order to start processes as a specific user, the SCM can be configured with the user’s credentials. These credentials are then stored in the Local Security Authority (LSA), a protected subsystem responsible for managing local security policy and user authentication. The LSA stores these credentials securely and provides them to the SCM when needed to start a service. This allows services to run under the security context of the configured user, even if that user is not currently logged in.

Storage and format

This secret is stored in the Local Security Authority (LSA) and is named in the format SCM:{<SID>}, with:

  • SCM - Meaning Service Control Manager (SCM)
  • SID - The object’s security identifier

The format of this secret is a character string encoded in UTF-16-LE containing the password in plain text:


Implementation in pentest tools

Secretsdump of the Impacket suite

In the file impacket/examples/ I added these few lines of python to automatically parse and format the services passwords in the output of the secretsdump tool:

elif re.match('^SCM:{([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})}', upperName) is not None:
    # Decode stored service password
    sid ='^SCM:{([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})}', upperName).group(1)
        password = secretItem.decode('utf-16le').rstrip('\x00')
        secret = 'Password of service %s: %s' % (sid, password)

The output of the secretsdump tool now becomes:

[*] NL$KM
 0000   2E 5F 46 93 4D 20 EB 46  5F 74 5F 61 83 A7 81 80   ................
 0010   B9 98 AB 93 78 24 5D 3D  34 E2 1A 63 F6 4D DE CF   ................
 0020   3C 20 8A 3C 63 EB 33 D4  FC 3E FB 99 42 E3 9E 30   ................
 0030   44 74 A8 C0 32 E7 48 43  3B 2D DC B0 6B CF 42 E5   ................
[*] SCM:{B092549F-61DB-41B0-96FD-02EB41E19783}
SCM Password of service B092549F-61DB-41B0-96FD-02EB41E19783: P@ssW0rD0fS3rv1c3!!!
[*] Cleaning up...
[*] Stopping service RemoteRegistry

I created a pull request to add this feature directly in impacket.