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# 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# 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 from __future__ import division

22 from __future__ import print_function

23 import binascii

24 import random

25

26 from impacket import nt_errors

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

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

29 from impacket.dcerpc.v5.rpcrt import DCERPCException

30 from impacket.uuid import uuidtup_to_bin

31 from impacket.structure import Structure

32

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

34

35 class DCERPCSessionError(DCERPCException):

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

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

38

39 def __str__( self ):

40 key = self.error_code

41 if key in nt_errors.ERROR_MESSAGES:

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

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

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

45 else:

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

47

48################################################################################

49# CONSTANTS

50################################################################################

51 CALG_DH_EPHEM = 0x0000aa02

52 TPUBLICKEYBLOB = 0x6

53 CUR_BLOB_VERSION = 0x2

54 ALG_ID = DWORD

55 CALG_RC4 = 0x6801

56

57################################################################################

58# STRUCTURES

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

60 class PUBLICKEYSTRUC(Structure):

61 structure = (

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

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

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

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

66 )

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

68 Structure.__init__(self,data,alignment)

69 self['bType'] = TPUBLICKEYBLOB

70 self['bVersion'] = CUR_BLOB_VERSION

71 self['aiKeyAlg'] = CALG_DH_EPHEM

72

73 class DHPUBKEY(Structure):

74 structure = (

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

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

77 )

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

79 Structure.__init__(self,data,alignment)

80 self['magic'] = 0x31484400

81 self['bitlen'] = 1024

82

83 class PUBLICKEYBLOB(Structure):

84 structure = (

85 ('publickeystruc',':', PUBLICKEYSTRUC),

86 ('dhpubkey',':', DHPUBKEY),

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

88 ('y',':'),

89 )

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

91 Structure.__init__(self,data,alignment)

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

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

94

95 class MIMI_HANDLE(NDRSTRUCT):

96 structure = (

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

98 )

99 def getAlignment(self):

100 if self._isNDR64 is True:

101 return 8

102 else:

103 return 4

104

105 class BYTE_ARRAY(NDRUniConformantArray):

106 item = 'c'

107

108 class PBYTE_ARRAY(NDRPOINTER):

109 referent = (

110 ('Data',BYTE_ARRAY),

111 )

112

113 class MIMI_PUBLICKEY(NDRSTRUCT):

114 structure = (

115 ('sessionType',ALG_ID),

116 ('cbPublicKey',DWORD),

117 ('pbPublicKey',PBYTE_ARRAY),

118 )

119

120 class PMIMI_PUBLICKEY(NDRPOINTER):

121 referent = (

122 ('Data',MIMI_PUBLICKEY),

123 )

124

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

126# RPC CALLS

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

128 class MimiBind(NDRCALL):

129 opnum = 0

130 structure = (

131 ('clientPublicKey',MIMI_PUBLICKEY),

132 )

133

134 class MimiBindResponse(NDRCALL):

135 structure = (

136 ('serverPublicKey',MIMI_PUBLICKEY),

137 ('phMimi',MIMI_HANDLE),

138 ('ErrorCode',ULONG),

139 )

140

141 class MimiUnbind(NDRCALL):

142 opnum = 1

143 structure = (

144 ('phMimi',MIMI_HANDLE),

145 )

146

147 class MimiUnbindResponse(NDRCALL):

148 structure = (

149 ('phMimi',MIMI_HANDLE),

150 ('ErrorCode',ULONG),

151 )

152

153 class MimiCommand(NDRCALL):

154 opnum = 2

155 structure = (

156 ('phMimi',MIMI_HANDLE),

157 ('szEncCommand',DWORD),

158 ('encCommand',PBYTE_ARRAY),

159 )

160

161 class MimiCommandResponse(NDRCALL):

162 structure = (

163 ('szEncResult',DWORD),

164 ('encResult',PBYTE_ARRAY),

165 ('ErrorCode',ULONG),

166 )

167

168

169################################################################################

170# OPNUMs and their corresponding structures

171################################################################################

172 OPNUMS = {

173 0 : (MimiBind, MimiBindResponse),

174 1 : (MimiUnbind, MimiUnbindResponse),

175 2 : (MimiCommand, MimiCommandResponse),

176}

177

178################################################################################

179# HELPER FUNCTIONS

180################################################################################

181

182 class MimiDiffeH:

183 def __init__(self):

184 self.G = 2

185 self.P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF

186 self.privateKey = random.getrandbits(1024)

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

188

189 def genPublicKey(self):

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

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

192 if len(tmp) & 1:

193 tmp = '0' + tmp

194 return binascii.unhexlify(tmp)

195

196 def getSharedSecret(self, serverPublicKey):

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

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

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

200 if len(tmp) & 1:

201 tmp = '0' + tmp

202 return binascii.unhexlify(tmp)

203

204

205 def hMimiBind(dce, clientPublicKey):

206 request = MimiBind()

207 request['clientPublicKey'] = clientPublicKey

208 return dce.request(request)

209

210 def hMimiCommand(dce, phMimi, encCommand):

211 request = MimiCommand()

212 request['phMimi'] = phMimi

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

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

215 return dce.request(request)

216

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

218 from impacket.winregistry import hexdump

219 alice = MimiDiffeH()

220 alice.G = 5

221 alice.P = 23

222 alice.privateKey = 6

223

224 bob = MimiDiffeH()

225 bob.G = 5

226 bob.P = 23

227 bob.privateKey = 15

228

229 print('Alice pubKey')

230 hexdump(alice.genPublicKey())

231 print('Bob pubKey')

232 hexdump(bob.genPublicKey())

233

234 print('Secret')

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

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