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# 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#
21from __future__ import division
22from __future__ import print_function
23import binascii
24import random
26from impacket import nt_errors
27from impacket.dcerpc.v5.dtypes import DWORD, ULONG
28from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray
29from impacket.dcerpc.v5.rpcrt import DCERPCException
30from impacket.uuid import uuidtup_to_bin
31from impacket.structure import Structure
33MSRPC_UUID_MIMIKATZ = uuidtup_to_bin(('17FC11E9-C258-4B8D-8D07-2F4125156244', '1.0'))
35class DCERPCSessionError(DCERPCException):
36 def __init__(self, error_string=None, error_code=None, packet=None):
37 DCERPCException.__init__(self, error_string, error_code, packet)
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
48################################################################################
49# CONSTANTS
50################################################################################
51CALG_DH_EPHEM = 0x0000aa02
52TPUBLICKEYBLOB = 0x6
53CUR_BLOB_VERSION = 0x2
54ALG_ID = DWORD
55CALG_RC4 = 0x6801
57################################################################################
58# STRUCTURES
59################################################################################
60class 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
73class 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
83class 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()
95class 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
105class BYTE_ARRAY(NDRUniConformantArray):
106 item = 'c'
108class PBYTE_ARRAY(NDRPOINTER):
109 referent = (
110 ('Data',BYTE_ARRAY),
111 )
113class MIMI_PUBLICKEY(NDRSTRUCT):
114 structure = (
115 ('sessionType',ALG_ID),
116 ('cbPublicKey',DWORD),
117 ('pbPublicKey',PBYTE_ARRAY),
118 )
120class PMIMI_PUBLICKEY(NDRPOINTER):
121 referent = (
122 ('Data',MIMI_PUBLICKEY),
123 )
125################################################################################
126# RPC CALLS
127################################################################################
128class MimiBind(NDRCALL):
129 opnum = 0
130 structure = (
131 ('clientPublicKey',MIMI_PUBLICKEY),
132 )
134class MimiBindResponse(NDRCALL):
135 structure = (
136 ('serverPublicKey',MIMI_PUBLICKEY),
137 ('phMimi',MIMI_HANDLE),
138 ('ErrorCode',ULONG),
139 )
141class MimiUnbind(NDRCALL):
142 opnum = 1
143 structure = (
144 ('phMimi',MIMI_HANDLE),
145 )
147class MimiUnbindResponse(NDRCALL):
148 structure = (
149 ('phMimi',MIMI_HANDLE),
150 ('ErrorCode',ULONG),
151 )
153class MimiCommand(NDRCALL):
154 opnum = 2
155 structure = (
156 ('phMimi',MIMI_HANDLE),
157 ('szEncCommand',DWORD),
158 ('encCommand',PBYTE_ARRAY),
159 )
161class MimiCommandResponse(NDRCALL):
162 structure = (
163 ('szEncResult',DWORD),
164 ('encResult',PBYTE_ARRAY),
165 ('ErrorCode',ULONG),
166 )
169################################################################################
170# OPNUMs and their corresponding structures
171################################################################################
172OPNUMS = {
173 0 : (MimiBind, MimiBindResponse),
174 1 : (MimiUnbind, MimiUnbindResponse),
175 2 : (MimiCommand, MimiCommandResponse),
176}
178################################################################################
179# HELPER FUNCTIONS
180################################################################################
182class 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)
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)
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)
205def hMimiBind(dce, clientPublicKey):
206 request = MimiBind()
207 request['clientPublicKey'] = clientPublicKey
208 return dce.request(request)
210def 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)
217if __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
224 bob = MimiDiffeH()
225 bob.G = 5
226 bob.P = 23
227 bob.privateKey = 15
229 print('Alice pubKey')
230 hexdump(alice.genPublicKey())
231 print('Bob pubKey')
232 hexdump(bob.genPublicKey())
234 print('Secret')
235 hexdump(alice.getSharedSecret(bob.genPublicKey()))
236 hexdump(bob.getSharedSecret(alice.genPublicKey()))