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

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#
24from __future__ import division
25from __future__ import print_function
26import binascii
27import random
29from impacket import nt_errors
30from impacket.dcerpc.v5.dtypes import DWORD, ULONG
31from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray
32from impacket.dcerpc.v5.rpcrt import DCERPCException
33from impacket.uuid import uuidtup_to_bin
34from impacket.structure import Structure
36MSRPC_UUID_MIMIKATZ = uuidtup_to_bin(('17FC11E9-C258-4B8D-8D07-2F4125156244', '1.0'))
38class DCERPCSessionError(DCERPCException):
39 def __init__(self, error_string=None, error_code=None, packet=None):
40 DCERPCException.__init__(self, error_string, error_code, packet)
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
51################################################################################
52# CONSTANTS
53################################################################################
54CALG_DH_EPHEM = 0x0000aa02
55TPUBLICKEYBLOB = 0x6
56CUR_BLOB_VERSION = 0x2
57ALG_ID = DWORD
58CALG_RC4 = 0x6801
60################################################################################
61# STRUCTURES
62################################################################################
63class 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
76class 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
86class 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()
98class 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
108class BYTE_ARRAY(NDRUniConformantArray):
109 item = 'c'
111class PBYTE_ARRAY(NDRPOINTER):
112 referent = (
113 ('Data',BYTE_ARRAY),
114 )
116class MIMI_PUBLICKEY(NDRSTRUCT):
117 structure = (
118 ('sessionType',ALG_ID),
119 ('cbPublicKey',DWORD),
120 ('pbPublicKey',PBYTE_ARRAY),
121 )
123class PMIMI_PUBLICKEY(NDRPOINTER):
124 referent = (
125 ('Data',MIMI_PUBLICKEY),
126 )
128################################################################################
129# RPC CALLS
130################################################################################
131class MimiBind(NDRCALL):
132 opnum = 0
133 structure = (
134 ('clientPublicKey',MIMI_PUBLICKEY),
135 )
137class MimiBindResponse(NDRCALL):
138 structure = (
139 ('serverPublicKey',MIMI_PUBLICKEY),
140 ('phMimi',MIMI_HANDLE),
141 ('ErrorCode',ULONG),
142 )
144class MimiUnbind(NDRCALL):
145 opnum = 1
146 structure = (
147 ('phMimi',MIMI_HANDLE),
148 )
150class MimiUnbindResponse(NDRCALL):
151 structure = (
152 ('phMimi',MIMI_HANDLE),
153 ('ErrorCode',ULONG),
154 )
156class MimiCommand(NDRCALL):
157 opnum = 2
158 structure = (
159 ('phMimi',MIMI_HANDLE),
160 ('szEncCommand',DWORD),
161 ('encCommand',PBYTE_ARRAY),
162 )
164class MimiCommandResponse(NDRCALL):
165 structure = (
166 ('szEncResult',DWORD),
167 ('encResult',PBYTE_ARRAY),
168 ('ErrorCode',ULONG),
169 )
172################################################################################
173# OPNUMs and their corresponding structures
174################################################################################
175OPNUMS = {
176 0 : (MimiBind, MimiBindResponse),
177 1 : (MimiUnbind, MimiUnbindResponse),
178 2 : (MimiCommand, MimiCommandResponse),
179}
181################################################################################
182# HELPER FUNCTIONS
183################################################################################
185class 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)
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)
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)
208def hMimiBind(dce, clientPublicKey):
209 request = MimiBind()
210 request['clientPublicKey'] = clientPublicKey
211 return dce.request(request)
213def 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)
220if __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
227 bob = MimiDiffeH()
228 bob.G = 5
229 bob.P = 23
230 bob.privateKey = 15
232 print('Alice pubKey')
233 hexdump(alice.genPublicKey())
234 print('Bob pubKey')
235 hexdump(bob.genPublicKey())
237 print('Secret')
238 hexdump(alice.getSharedSecret(bob.genPublicKey()))
239 hexdump(bob.getSharedSecret(alice.genPublicKey()))