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 2018 SecureAuth Corporation. All rights reserved. 

2# 

3# This software is provided under under a slightly modified version 

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

5# for more information. 

6# 

7# Author: Alberto Solino (@agsolino) 

8# 

9# Description: 

10# [MS-TSCH] SASec Interface implementation 

11# 

12# Best way to learn how to use these calls is to grab the protocol standard 

13# so you understand what the call does, and then read the test case located 

14# at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC 

15# 

16# Some calls have helper functions, which makes it even easier to use. 

17# They are located at the end of this file.  

18# Helper functions start with "h"<name of the call>. 

19# There are test cases for them too.  

20# 

21from impacket.dcerpc.v5.ndr import NDRCALL, NDRUniConformantArray 

22from impacket.dcerpc.v5.dtypes import DWORD, LPWSTR, ULONG, WSTR, NULL 

23from impacket import hresult_errors 

24from impacket.uuid import uuidtup_to_bin 

25from impacket.dcerpc.v5.rpcrt import DCERPCException 

26 

27MSRPC_UUID_SASEC = uuidtup_to_bin(('378E52B0-C0A9-11CF-822D-00AA0051E40F','1.0')) 

28 

29class DCERPCSessionError(DCERPCException): 

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

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

32 

33 def __str__( self ): 

34 key = self.error_code 

35 if key in hresult_errors.ERROR_MESSAGES: 

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

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

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

39 else: 

40 return 'TSCH SessionError: unknown error code: 0x%x' % self.error_code 

41 

42################################################################################ 

43# CONSTANTS 

44################################################################################ 

45SASEC_HANDLE = WSTR 

46PSASEC_HANDLE = LPWSTR 

47 

48MAX_BUFFER_SIZE = 273 

49 

50# 3.2.5.3.4 SASetAccountInformation (Opnum 0) 

51TASK_FLAG_RUN_ONLY_IF_LOGGED_ON = 0x40000 

52 

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

54# STRUCTURES 

55################################################################################ 

56class WORD_ARRAY(NDRUniConformantArray): 

57 item = '<H' 

58 

59################################################################################ 

60# RPC CALLS 

61################################################################################ 

62# 3.2.5.3.4 SASetAccountInformation (Opnum 0) 

63class SASetAccountInformation(NDRCALL): 

64 opnum = 0 

65 structure = ( 

66 ('Handle', PSASEC_HANDLE), 

67 ('pwszJobName', WSTR), 

68 ('pwszAccount', WSTR), 

69 ('pwszPassword', LPWSTR), 

70 ('dwJobFlags', DWORD), 

71 ) 

72 

73class SASetAccountInformationResponse(NDRCALL): 

74 structure = ( 

75 ('ErrorCode',ULONG), 

76 ) 

77 

78# 3.2.5.3.5 SASetNSAccountInformation (Opnum 1) 

79class SASetNSAccountInformation(NDRCALL): 

80 opnum = 1 

81 structure = ( 

82 ('Handle', PSASEC_HANDLE), 

83 ('pwszAccount', LPWSTR), 

84 ('pwszPassword', LPWSTR), 

85 ) 

86 

87class SASetNSAccountInformationResponse(NDRCALL): 

88 structure = ( 

89 ('ErrorCode',ULONG), 

90 ) 

91 

92# 3.2.5.3.6 SAGetNSAccountInformation (Opnum 2) 

93class SAGetNSAccountInformation(NDRCALL): 

94 opnum = 2 

95 structure = ( 

96 ('Handle', PSASEC_HANDLE), 

97 ('ccBufferSize', DWORD), 

98 ('wszBuffer', WORD_ARRAY), 

99 ) 

100 

101class SAGetNSAccountInformationResponse(NDRCALL): 

102 structure = ( 

103 ('wszBuffer',WORD_ARRAY), 

104 ('ErrorCode',ULONG), 

105 ) 

106 

107# 3.2.5.3.7 SAGetAccountInformation (Opnum 3) 

108class SAGetAccountInformation(NDRCALL): 

109 opnum = 3 

110 structure = ( 

111 ('Handle', PSASEC_HANDLE), 

112 ('pwszJobName', WSTR), 

113 ('ccBufferSize', DWORD), 

114 ('wszBuffer', WORD_ARRAY), 

115 ) 

116 

117class SAGetAccountInformationResponse(NDRCALL): 

118 structure = ( 

119 ('wszBuffer',WORD_ARRAY), 

120 ('ErrorCode',ULONG), 

121 ) 

122################################################################################ 

123# OPNUMs and their corresponding structures 

124################################################################################ 

125OPNUMS = { 

126 0 : (SASetAccountInformation, SASetAccountInformationResponse), 

127 1 : (SASetNSAccountInformation, SASetNSAccountInformationResponse), 

128 2 : (SAGetNSAccountInformation, SAGetNSAccountInformationResponse), 

129 3 : (SAGetAccountInformation, SAGetAccountInformationResponse), 

130} 

131 

132################################################################################ 

133# HELPER FUNCTIONS 

134################################################################################ 

135def checkNullString(string): 

136 if string == NULL: 136 ↛ 137line 136 didn't jump to line 137, because the condition on line 136 was never true

137 return string 

138 

139 if string[-1:] != '\x00': 139 ↛ 142line 139 didn't jump to line 142, because the condition on line 139 was never false

140 return string + '\x00' 

141 else: 

142 return string 

143 

144def hSASetAccountInformation(dce, handle, pwszJobName, pwszAccount, pwszPassword, dwJobFlags=0): 

145 request = SASetAccountInformation() 

146 request['Handle'] = handle 

147 request['pwszJobName'] = checkNullString(pwszJobName) 

148 request['pwszAccount'] = checkNullString(pwszAccount) 

149 request['pwszPassword'] = checkNullString(pwszPassword) 

150 request['dwJobFlags'] = dwJobFlags 

151 return dce.request(request) 

152 

153def hSASetNSAccountInformation(dce, handle, pwszAccount, pwszPassword): 

154 request = SASetNSAccountInformation() 

155 request['Handle'] = handle 

156 request['pwszAccount'] = checkNullString(pwszAccount) 

157 request['pwszPassword'] = checkNullString(pwszPassword) 

158 return dce.request(request) 

159 

160def hSAGetNSAccountInformation(dce, handle, ccBufferSize = MAX_BUFFER_SIZE): 

161 request = SAGetNSAccountInformation() 

162 request['Handle'] = handle 

163 request['ccBufferSize'] = ccBufferSize 

164 for _ in range(ccBufferSize): 

165 request['wszBuffer'].append(0) 

166 return dce.request(request) 

167 

168def hSAGetAccountInformation(dce, handle, pwszJobName, ccBufferSize = MAX_BUFFER_SIZE): 

169 request = SAGetAccountInformation() 

170 request['Handle'] = handle 

171 request['pwszJobName'] = checkNullString(pwszJobName) 

172 request['ccBufferSize'] = ccBufferSize 

173 for _ in range(ccBufferSize): 

174 request['wszBuffer'].append(0) 

175 return dce.request(request)