Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/mimilib.py: 48%

# Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/mimilib.py : 48%

## 120 statements

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# Mimikatz Interface implementation, based on @gentilkiwi IDL

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#

24 from __future__ import division

25 from __future__ import print_function

26 import binascii

27 import random

28

29 from impacket import nt_errors

30 from impacket.dcerpc.v5.dtypes import DWORD, ULONG

31 from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray

32 from impacket.dcerpc.v5.rpcrt import DCERPCException

33 from impacket.uuid import uuidtup_to_bin

34 from impacket.structure import Structure

35

36 MSRPC_UUID_MIMIKATZ = uuidtup_to_bin(('17FC11E9-C258-4B8D-8D07-2F4125156244', '1.0'))

37

38 class DCERPCSessionError(DCERPCException):

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

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

41

42 def __str__( self ):

43 key = self.error_code

44 if key in nt_errors.ERROR_MESSAGES:

45 error_msg_short = nt_errors.ERROR_MESSAGES[key][0]

46 error_msg_verbose = nt_errors.ERROR_MESSAGES[key][1]

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

48 else:

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

50

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

52# CONSTANTS

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

54 CALG_DH_EPHEM = 0x0000aa02

55 TPUBLICKEYBLOB = 0x6

56 CUR_BLOB_VERSION = 0x2

57 ALG_ID = DWORD

58 CALG_RC4 = 0x6801

59

60################################################################################

61# STRUCTURES

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

63 class PUBLICKEYSTRUC(Structure):

64 structure = (

65 ('bType','B=0'),

66 ('bVersion','B=0'),

67 ('reserved','<H=0'),

68 ('aiKeyAlg','<L=0'),

69 )

70 def __init__(self, data = None, alignment = 0):

71 Structure.__init__(self,data,alignment)

72 self['bType'] = TPUBLICKEYBLOB

73 self['bVersion'] = CUR_BLOB_VERSION

74 self['aiKeyAlg'] = CALG_DH_EPHEM

75

76 class DHPUBKEY(Structure):

77 structure = (

78 ('magic','<L=0'),

79 ('bitlen','<L=0'),

80 )

81 def __init__(self, data = None, alignment = 0):

82 Structure.__init__(self,data,alignment)

83 self['magic'] = 0x31484400

84 self['bitlen'] = 1024

85

86 class PUBLICKEYBLOB(Structure):

87 structure = (

88 ('publickeystruc',':', PUBLICKEYSTRUC),

89 ('dhpubkey',':', DHPUBKEY),

90 ('yLen', '_-y','128'),

91 ('y',':'),

92 )

93 def __init__(self, data = None, alignment = 0):

94 Structure.__init__(self,data,alignment)

95 self['publickeystruc'] = PUBLICKEYSTRUC().getData()

96 self['dhpubkey'] = DHPUBKEY().getData()

97

98 class MIMI_HANDLE(NDRSTRUCT):

99 structure = (

100 ('Data','20s=""'),

101 )

102 def getAlignment(self):

103 if self._isNDR64 is True:

104 return 8

105 else:

106 return 4

107

108 class BYTE_ARRAY(NDRUniConformantArray):

109 item = 'c'

110

111 class PBYTE_ARRAY(NDRPOINTER):

112 referent = (

113 ('Data',BYTE_ARRAY),

114 )

115

116 class MIMI_PUBLICKEY(NDRSTRUCT):

117 structure = (

118 ('sessionType',ALG_ID),

119 ('cbPublicKey',DWORD),

120 ('pbPublicKey',PBYTE_ARRAY),

121 )

122

123 class PMIMI_PUBLICKEY(NDRPOINTER):

124 referent = (

125 ('Data',MIMI_PUBLICKEY),

126 )

127

128################################################################################

129# RPC CALLS

130################################################################################

131 class MimiBind(NDRCALL):

132 opnum = 0

133 structure = (

134 ('clientPublicKey',MIMI_PUBLICKEY),

135 )

136

137 class MimiBindResponse(NDRCALL):

138 structure = (

139 ('serverPublicKey',MIMI_PUBLICKEY),

140 ('phMimi',MIMI_HANDLE),

141 ('ErrorCode',ULONG),

142 )

143

144 class MimiUnbind(NDRCALL):

145 opnum = 1

146 structure = (

147 ('phMimi',MIMI_HANDLE),

148 )

149

150 class MimiUnbindResponse(NDRCALL):

151 structure = (

152 ('phMimi',MIMI_HANDLE),

153 ('ErrorCode',ULONG),

154 )

155

156 class MimiCommand(NDRCALL):

157 opnum = 2

158 structure = (

159 ('phMimi',MIMI_HANDLE),

160 ('szEncCommand',DWORD),

161 ('encCommand',PBYTE_ARRAY),

162 )

163

164 class MimiCommandResponse(NDRCALL):

165 structure = (

166 ('szEncResult',DWORD),

167 ('encResult',PBYTE_ARRAY),

168 ('ErrorCode',ULONG),

169 )

170

171

172################################################################################

173# OPNUMs and their corresponding structures

174################################################################################

175 OPNUMS = {

176 0 : (MimiBind, MimiBindResponse),

177 1 : (MimiUnbind, MimiUnbindResponse),

178 2 : (MimiCommand, MimiCommandResponse),

179}

180

181################################################################################

182# HELPER FUNCTIONS

183################################################################################

184

185 class MimiDiffeH:

186 def __init__(self):

187 self.G = 2

188 self.P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF

189 self.privateKey = random.getrandbits(1024)

190 #self.privateKey = int('A'*128, base=16)

191

192 def genPublicKey(self):

193 self.publicKey = pow(self.G, self.privateKey, self.P)

194 tmp = hex(self.publicKey)[2:].rstrip('L')

195 if len(tmp) & 1:

196 tmp = '0' + tmp

197 return binascii.unhexlify(tmp)

198

199 def getSharedSecret(self, serverPublicKey):

200 pubKey = int(binascii.hexlify(serverPublicKey), base=16)

201 self.sharedSecret = pow(pubKey, self.privateKey, self.P)

202 tmp = hex(self.sharedSecret)[2:].rstrip('L')

203 if len(tmp) & 1:

204 tmp = '0' + tmp

205 return binascii.unhexlify(tmp)

206

207

208 def hMimiBind(dce, clientPublicKey):

209 request = MimiBind()

210 request['clientPublicKey'] = clientPublicKey

211 return dce.request(request)

212

213 def hMimiCommand(dce, phMimi, encCommand):

214 request = MimiCommand()

215 request['phMimi'] = phMimi

216 request['szEncCommand'] = len(encCommand)

217 request['encCommand'] = list(encCommand)

218 return dce.request(request)

219

220 if __name__ == '__main__': 220 ↛ 221line 220 didn't jump to line 221, because the condition on line 220 was never true

221 from impacket.winregistry import hexdump

222 alice = MimiDiffeH()

223 alice.G = 5

224 alice.P = 23

225 alice.privateKey = 6

226

227 bob = MimiDiffeH()

228 bob.G = 5

229 bob.P = 23

230 bob.privateKey = 15

231

232 print('Alice pubKey')

233 hexdump(alice.genPublicKey())

234 print('Bob pubKey')

235 hexdump(bob.genPublicKey())

236

237 print('Secret')

238 hexdump(alice.getSharedSecret(bob.genPublicKey()))

239 hexdump(bob.getSharedSecret(alice.genPublicKey()))