import argparse import getpass from impacket import ntlm from impacket.dcerpc.v5 import transport, samr, epm from impacket.dcerpc.v5.ndr import NULL def parse_target(target): # source: Impacket's smbpasswd.py try: userpass, hostname_or_ip = target.rsplit('@', 1) except ValueError: print('Wrong target string format. For more information run with --help option.') sys.exit(1) try: username, currpass = userpass.split(':', 1) except ValueError: username = userpass currpass = getpass.getpass('Password: ') return (username, currpass, hostname_or_ip) def validatePassword(v_username, v_password, domain, target): conn_username, conn_password, hostname = parse_target(target) # "RPC clients for this protocol MUST use RPC over TCP/IP for the SamrValidatePassword method" stringBinding = epm.hept_map(hostname, samr.MSRPC_UUID_SAMR, protocol = 'ncacn_ip_tcp') rpctransport = transport.DCERPCTransportFactory(stringBinding) rpctransport.set_credentials(conn_username, conn_password, domain, '', '') dce = rpctransport.get_dce_rpc() dce.connect() dce.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY) dce.bind(samr.MSRPC_UUID_SAMR) inputArg = samr.SAM_VALIDATE_INPUT_ARG() inputArg['tag'] = samr.PASSWORD_POLICY_VALIDATION_TYPE.SamValidatePasswordChange inputArg['ValidatePasswordChangeInput']['InputPersistedFields']['PasswordHistory'] = NULL inputArg['ValidatePasswordChangeInput']['UserAccountName'] = v_username inputArg['ValidatePasswordChangeInput']['ClearPassword'] = v_password inputArg['ValidatePasswordChangeInput']['PasswordMatch'] = True resp = samr.hSamrValidatePassword(dce, inputArg) validationStatus = resp['OutputArg']['ValidatePasswordChangeOutput']['ValidationStatus'] print("Status: " + samr.SAM_VALIDATE_VALIDATION_STATUS.enumItems(validationStatus).name) parser = argparse.ArgumentParser() parser.add_argument('-u', default='Administrator', help='Username (for ValidatePassword call)') parser.add_argument('-p', default='', help='Password (for ValidatePassword call)') parser.add_argument('-d', default='', help='Domain') parser.add_argument('target', help='@') args = parser.parse_args() validatePassword(args.u, args.p, args.d, args.target)