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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 

# 

# This software is provided under under a slightly modified version 

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

# for more information. 

# 

# Author: Alberto Solino (@agsolino) 

# 

# Description: 

# [MS-TSCH] SASec Interface implementation 

# 

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

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

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

# 

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

# They are located at the end of this file.  

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

# There are test cases for them too.  

# 

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

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

from impacket import hresult_errors 

from impacket.uuid import uuidtup_to_bin 

from impacket.dcerpc.v5.rpcrt import DCERPCException 

 

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

 

class DCERPCSessionError(DCERPCException): 

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

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

 

def __str__( self ): 

key = self.error_code 

if key in hresult_errors.ERROR_MESSAGES: 

error_msg_short = hresult_errors.ERROR_MESSAGES[key][0] 

error_msg_verbose = hresult_errors.ERROR_MESSAGES[key][1] 

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

else: 

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

 

################################################################################ 

# CONSTANTS 

################################################################################ 

SASEC_HANDLE = WSTR 

PSASEC_HANDLE = LPWSTR 

 

MAX_BUFFER_SIZE = 273 

 

# 3.2.5.3.4 SASetAccountInformation (Opnum 0) 

TASK_FLAG_RUN_ONLY_IF_LOGGED_ON = 0x40000 

 

################################################################################ 

# STRUCTURES 

################################################################################ 

class WORD_ARRAY(NDRUniConformantArray): 

item = '<H' 

 

################################################################################ 

# RPC CALLS 

################################################################################ 

# 3.2.5.3.4 SASetAccountInformation (Opnum 0) 

class SASetAccountInformation(NDRCALL): 

opnum = 0 

structure = ( 

('Handle', PSASEC_HANDLE), 

('pwszJobName', WSTR), 

('pwszAccount', WSTR), 

('pwszPassword', LPWSTR), 

('dwJobFlags', DWORD), 

) 

 

class SASetAccountInformationResponse(NDRCALL): 

structure = ( 

('ErrorCode',ULONG), 

) 

 

# 3.2.5.3.5 SASetNSAccountInformation (Opnum 1) 

class SASetNSAccountInformation(NDRCALL): 

opnum = 1 

structure = ( 

('Handle', PSASEC_HANDLE), 

('pwszAccount', LPWSTR), 

('pwszPassword', LPWSTR), 

) 

 

class SASetNSAccountInformationResponse(NDRCALL): 

structure = ( 

('ErrorCode',ULONG), 

) 

 

# 3.2.5.3.6 SAGetNSAccountInformation (Opnum 2) 

class SAGetNSAccountInformation(NDRCALL): 

opnum = 2 

structure = ( 

('Handle', PSASEC_HANDLE), 

('ccBufferSize', DWORD), 

('wszBuffer', WORD_ARRAY), 

) 

 

class SAGetNSAccountInformationResponse(NDRCALL): 

structure = ( 

('wszBuffer',WORD_ARRAY), 

('ErrorCode',ULONG), 

) 

 

# 3.2.5.3.7 SAGetAccountInformation (Opnum 3) 

class SAGetAccountInformation(NDRCALL): 

opnum = 3 

structure = ( 

('Handle', PSASEC_HANDLE), 

('pwszJobName', WSTR), 

('ccBufferSize', DWORD), 

('wszBuffer', WORD_ARRAY), 

) 

 

class SAGetAccountInformationResponse(NDRCALL): 

structure = ( 

('wszBuffer',WORD_ARRAY), 

('ErrorCode',ULONG), 

) 

################################################################################ 

# OPNUMs and their corresponding structures 

################################################################################ 

OPNUMS = { 

0 : (SASetAccountInformation, SASetAccountInformationResponse), 

1 : (SASetNSAccountInformation, SASetNSAccountInformationResponse), 

2 : (SAGetNSAccountInformation, SAGetNSAccountInformationResponse), 

3 : (SAGetAccountInformation, SAGetAccountInformationResponse), 

} 

 

################################################################################ 

# HELPER FUNCTIONS 

################################################################################ 

def checkNullString(string): 

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

return string 

 

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

return string + '\x00' 

else: 

return string 

 

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

request = SASetAccountInformation() 

request['Handle'] = handle 

request['pwszJobName'] = checkNullString(pwszJobName) 

request['pwszAccount'] = checkNullString(pwszAccount) 

request['pwszPassword'] = checkNullString(pwszPassword) 

request['dwJobFlags'] = dwJobFlags 

return dce.request(request) 

 

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

request = SASetNSAccountInformation() 

request['Handle'] = handle 

request['pwszAccount'] = checkNullString(pwszAccount) 

request['pwszPassword'] = checkNullString(pwszPassword) 

return dce.request(request) 

 

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

request = SAGetNSAccountInformation() 

request['Handle'] = handle 

request['ccBufferSize'] = ccBufferSize 

for _ in range(ccBufferSize): 

request['wszBuffer'].append(0) 

return dce.request(request) 

 

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

request = SAGetAccountInformation() 

request['Handle'] = handle 

request['pwszJobName'] = checkNullString(pwszJobName) 

request['ccBufferSize'] = ccBufferSize 

for _ in range(ccBufferSize): 

request['wszBuffer'].append(0) 

return dce.request(request)