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# Impacket - Collection of Python classes for working with network protocols. 

2# 

3# SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 

4# 

5# This software is provided under a slightly modified version 

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

7# for more information. 

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# 

21# Author: 

22# Alberto Solino (@agsolino) 

23# 

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

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

26from impacket import hresult_errors 

27from impacket.uuid import uuidtup_to_bin 

28from impacket.dcerpc.v5.rpcrt import DCERPCException 

29 

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

31 

32class DCERPCSessionError(DCERPCException): 

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

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

35 

36 def __str__( self ): 

37 key = self.error_code 

38 if key in hresult_errors.ERROR_MESSAGES: 

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

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

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

42 else: 

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

44 

45################################################################################ 

46# CONSTANTS 

47################################################################################ 

48SASEC_HANDLE = WSTR 

49PSASEC_HANDLE = LPWSTR 

50 

51MAX_BUFFER_SIZE = 273 

52 

53# 3.2.5.3.4 SASetAccountInformation (Opnum 0) 

54TASK_FLAG_RUN_ONLY_IF_LOGGED_ON = 0x40000 

55 

56################################################################################ 

57# STRUCTURES 

58################################################################################ 

59class WORD_ARRAY(NDRUniConformantArray): 

60 item = '<H' 

61 

62################################################################################ 

63# RPC CALLS 

64################################################################################ 

65# 3.2.5.3.4 SASetAccountInformation (Opnum 0) 

66class SASetAccountInformation(NDRCALL): 

67 opnum = 0 

68 structure = ( 

69 ('Handle', PSASEC_HANDLE), 

70 ('pwszJobName', WSTR), 

71 ('pwszAccount', WSTR), 

72 ('pwszPassword', LPWSTR), 

73 ('dwJobFlags', DWORD), 

74 ) 

75 

76class SASetAccountInformationResponse(NDRCALL): 

77 structure = ( 

78 ('ErrorCode',ULONG), 

79 ) 

80 

81# 3.2.5.3.5 SASetNSAccountInformation (Opnum 1) 

82class SASetNSAccountInformation(NDRCALL): 

83 opnum = 1 

84 structure = ( 

85 ('Handle', PSASEC_HANDLE), 

86 ('pwszAccount', LPWSTR), 

87 ('pwszPassword', LPWSTR), 

88 ) 

89 

90class SASetNSAccountInformationResponse(NDRCALL): 

91 structure = ( 

92 ('ErrorCode',ULONG), 

93 ) 

94 

95# 3.2.5.3.6 SAGetNSAccountInformation (Opnum 2) 

96class SAGetNSAccountInformation(NDRCALL): 

97 opnum = 2 

98 structure = ( 

99 ('Handle', PSASEC_HANDLE), 

100 ('ccBufferSize', DWORD), 

101 ('wszBuffer', WORD_ARRAY), 

102 ) 

103 

104class SAGetNSAccountInformationResponse(NDRCALL): 

105 structure = ( 

106 ('wszBuffer',WORD_ARRAY), 

107 ('ErrorCode',ULONG), 

108 ) 

109 

110# 3.2.5.3.7 SAGetAccountInformation (Opnum 3) 

111class SAGetAccountInformation(NDRCALL): 

112 opnum = 3 

113 structure = ( 

114 ('Handle', PSASEC_HANDLE), 

115 ('pwszJobName', WSTR), 

116 ('ccBufferSize', DWORD), 

117 ('wszBuffer', WORD_ARRAY), 

118 ) 

119 

120class SAGetAccountInformationResponse(NDRCALL): 

121 structure = ( 

122 ('wszBuffer',WORD_ARRAY), 

123 ('ErrorCode',ULONG), 

124 ) 

125################################################################################ 

126# OPNUMs and their corresponding structures 

127################################################################################ 

128OPNUMS = { 

129 0 : (SASetAccountInformation, SASetAccountInformationResponse), 

130 1 : (SASetNSAccountInformation, SASetNSAccountInformationResponse), 

131 2 : (SAGetNSAccountInformation, SAGetNSAccountInformationResponse), 

132 3 : (SAGetAccountInformation, SAGetAccountInformationResponse), 

133} 

134 

135################################################################################ 

136# HELPER FUNCTIONS 

137################################################################################ 

138def checkNullString(string): 

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

140 return string 

141 

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

143 return string + '\x00' 

144 else: 

145 return string 

146 

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

148 request = SASetAccountInformation() 

149 request['Handle'] = handle 

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

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

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

153 request['dwJobFlags'] = dwJobFlags 

154 return dce.request(request) 

155 

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

157 request = SASetNSAccountInformation() 

158 request['Handle'] = handle 

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

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

161 return dce.request(request) 

162 

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

164 request = SAGetNSAccountInformation() 

165 request['Handle'] = handle 

166 request['ccBufferSize'] = ccBufferSize 

167 for _ in range(ccBufferSize): 

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

169 return dce.request(request) 

170 

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

172 request = SAGetAccountInformation() 

173 request['Handle'] = handle 

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

175 request['ccBufferSize'] = ccBufferSize 

176 for _ in range(ccBufferSize): 

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

178 return dce.request(request)