Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# SECUREAUTH LABS. Copyright 2020 SecureAuth Corporation. All rights reserved. 

2# 

3# This software is provided under a slightly modified version 

4# of the Apache Software License. See the accompanying LICENSE file 

5# for more information. 

6# 

7# Description: 

8# [MS-OXABREF]: Address Book Name Service Provider Interface (NSPI) Referral Protocol 

9# 

10# Authors: 

11# Arseniy Sharoglazov <mohemiv@gmail.com> / Positive Technologies (https://www.ptsecurity.com/) 

12# 

13 

14from impacket import hresult_errors, mapi_constants 

15from impacket.dcerpc.v5.dtypes import NULL, STR, ULONG 

16from impacket.dcerpc.v5.ndr import NDRCALL, NDRPOINTER 

17from impacket.dcerpc.v5.rpcrt import DCERPCException 

18from impacket.uuid import uuidtup_to_bin 

19 

20MSRPC_UUID_OXABREF = uuidtup_to_bin(('1544F5E0-613C-11D1-93DF-00C04FD7BD09','1.0')) 

21 

22class DCERPCSessionError(DCERPCException): 

23 def __init__(self, error_string=None, error_code=None, packet=None): 

24 DCERPCException.__init__(self, error_string, error_code, packet) 

25 

26 def __str__( self ): 

27 key = self.error_code 

28 if key in mapi_constants.ERROR_MESSAGES: 

29 error_msg_short = mapi_constants.ERROR_MESSAGES[key] 

30 return 'OXABREF SessionError: code: 0x%x - %s' % (self.error_code, error_msg_short) 

31 elif key in hresult_errors.ERROR_MESSAGES: 

32 error_msg_short = hresult_errors.ERROR_MESSAGES[key][0] 

33 error_msg_verbose = hresult_errors.ERROR_MESSAGES[key][1] 

34 return 'OXABREF SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 

35 else: 

36 return 'OXABREF SessionError: unknown error code: 0x%x' % self.error_code 

37 

38################################################################################ 

39# STRUCTURES 

40################################################################################ 

41class PUCHAR_ARRAY(NDRPOINTER): 

42 referent = ( 

43 ('Data', STR), 

44 ) 

45 

46class PPUCHAR_ARRAY(NDRPOINTER): 

47 referent = ( 

48 ('Data', PUCHAR_ARRAY), 

49 ) 

50 

51################################################################################ 

52# RPC CALLS 

53################################################################################ 

54 

55# 3.1.4.1 RfrGetNewDSA (opnum 0) 

56class RfrGetNewDSA(NDRCALL): 

57 opnum = 0 

58 structure = ( 

59 ('ulFlags', ULONG), 

60 ('pUserDN', STR), 

61 ('ppszUnused', PPUCHAR_ARRAY), 

62 ('ppszServer', PPUCHAR_ARRAY), 

63 ) 

64 

65class RfrGetNewDSAResponse(NDRCALL): 

66 structure = ( 

67 ('ppszUnused', PPUCHAR_ARRAY), 

68 ('ppszServer', PPUCHAR_ARRAY), 

69 ) 

70 

71# 3.1.4.2 RfrGetFQDNFromServerDN (opnum 1) 

72class RfrGetFQDNFromServerDN(NDRCALL): 

73 opnum = 1 

74 structure = ( 

75 ('ulFlags', ULONG), 

76 ('cbMailboxServerDN', ULONG), 

77 ('szMailboxServerDN', STR), 

78 ) 

79 

80class RfrGetFQDNFromServerDNResponse(NDRCALL): 

81 structure = ( 

82 ('ppszServerFQDN', PUCHAR_ARRAY), 

83 ('ErrorCode', ULONG), 

84 ) 

85 

86################################################################################ 

87# OPNUMs and their corresponding structures 

88################################################################################ 

89OPNUMS = { 

90 0 : (RfrGetNewDSA, RfrGetNewDSAResponse), 

91 1 : (RfrGetFQDNFromServerDN, RfrGetFQDNFromServerDNResponse), 

92} 

93 

94################################################################################ 

95# HELPER FUNCTIONS 

96################################################################################ 

97def checkNullString(string): 

98 if string == NULL: 

99 return string 

100 

101 if string[-1:] != '\x00': 

102 return string + '\x00' 

103 else: 

104 return string 

105 

106def hRfrGetNewDSA(dce, pUserDN=''): 

107 request = RfrGetNewDSA() 

108 request['ulFlags'] = 0 

109 request['pUserDN'] = checkNullString(pUserDN) 

110 request['ppszUnused'] = NULL 

111 request['ppszServer'] = '\x00' 

112 

113 resp = dce.request(request) 

114 resp['ppszServer'] = resp['ppszServer'][:-1] 

115 

116 if request['ppszUnused'] != NULL: 

117 resp['ppszUnused'] = resp['ppszUnused'][:-1] 

118 

119 return resp 

120 

121def hRfrGetFQDNFromServerDN(dce, szMailboxServerDN): 

122 szMailboxServerDN = checkNullString(szMailboxServerDN) 

123 request = RfrGetFQDNFromServerDN() 

124 request['ulFlags'] = 0 

125 request['szMailboxServerDN'] = szMailboxServerDN 

126 request['cbMailboxServerDN'] = len(szMailboxServerDN) 

127 

128 resp = dce.request(request) 

129 resp['ppszServerFQDN'] = resp['ppszServerFQDN'][:-1] 

130 

131 return resp