mirror of
https://github.com/lgandx/Responder.git
synced 2024-10-18 05:00:39 -07:00
132 lines
4.3 KiB
Python
132 lines
4.3 KiB
Python
# SECUREAUTH LABS. Copyright 2020 SecureAuth Corporation. All rights reserved.
|
|
#
|
|
# This software is provided under a slightly modified version
|
|
# of the Apache Software License. See the accompanying LICENSE file
|
|
# for more information.
|
|
#
|
|
# Description:
|
|
# [MS-OXABREF]: Address Book Name Service Provider Interface (NSPI) Referral Protocol
|
|
#
|
|
# Authors:
|
|
# Arseniy Sharoglazov <mohemiv@gmail.com> / Positive Technologies (https://www.ptsecurity.com/)
|
|
#
|
|
|
|
from impacket import hresult_errors, mapi_constants
|
|
from impacket.dcerpc.v5.dtypes import NULL, STR, ULONG
|
|
from impacket.dcerpc.v5.ndr import NDRCALL, NDRPOINTER
|
|
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
|
from impacket.uuid import uuidtup_to_bin
|
|
|
|
MSRPC_UUID_OXABREF = uuidtup_to_bin(('1544F5E0-613C-11D1-93DF-00C04FD7BD09','1.0'))
|
|
|
|
class DCERPCSessionError(DCERPCException):
|
|
def __init__(self, error_string=None, error_code=None, packet=None):
|
|
DCERPCException.__init__(self, error_string, error_code, packet)
|
|
|
|
def __str__( self ):
|
|
key = self.error_code
|
|
if key in mapi_constants.ERROR_MESSAGES:
|
|
error_msg_short = mapi_constants.ERROR_MESSAGES[key]
|
|
return 'OXABREF SessionError: code: 0x%x - %s' % (self.error_code, error_msg_short)
|
|
elif key in hresult_errors.ERROR_MESSAGES:
|
|
error_msg_short = hresult_errors.ERROR_MESSAGES[key][0]
|
|
error_msg_verbose = hresult_errors.ERROR_MESSAGES[key][1]
|
|
return 'OXABREF SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
|
|
else:
|
|
return 'OXABREF SessionError: unknown error code: 0x%x' % self.error_code
|
|
|
|
################################################################################
|
|
# STRUCTURES
|
|
################################################################################
|
|
class PUCHAR_ARRAY(NDRPOINTER):
|
|
referent = (
|
|
('Data', STR),
|
|
)
|
|
|
|
class PPUCHAR_ARRAY(NDRPOINTER):
|
|
referent = (
|
|
('Data', PUCHAR_ARRAY),
|
|
)
|
|
|
|
################################################################################
|
|
# RPC CALLS
|
|
################################################################################
|
|
|
|
# 3.1.4.1 RfrGetNewDSA (opnum 0)
|
|
class RfrGetNewDSA(NDRCALL):
|
|
opnum = 0
|
|
structure = (
|
|
('ulFlags', ULONG),
|
|
('pUserDN', STR),
|
|
('ppszUnused', PPUCHAR_ARRAY),
|
|
('ppszServer', PPUCHAR_ARRAY),
|
|
)
|
|
|
|
class RfrGetNewDSAResponse(NDRCALL):
|
|
structure = (
|
|
('ppszUnused', PPUCHAR_ARRAY),
|
|
('ppszServer', PPUCHAR_ARRAY),
|
|
)
|
|
|
|
# 3.1.4.2 RfrGetFQDNFromServerDN (opnum 1)
|
|
class RfrGetFQDNFromServerDN(NDRCALL):
|
|
opnum = 1
|
|
structure = (
|
|
('ulFlags', ULONG),
|
|
('cbMailboxServerDN', ULONG),
|
|
('szMailboxServerDN', STR),
|
|
)
|
|
|
|
class RfrGetFQDNFromServerDNResponse(NDRCALL):
|
|
structure = (
|
|
('ppszServerFQDN', PUCHAR_ARRAY),
|
|
('ErrorCode', ULONG),
|
|
)
|
|
|
|
################################################################################
|
|
# OPNUMs and their corresponding structures
|
|
################################################################################
|
|
OPNUMS = {
|
|
0 : (RfrGetNewDSA, RfrGetNewDSAResponse),
|
|
1 : (RfrGetFQDNFromServerDN, RfrGetFQDNFromServerDNResponse),
|
|
}
|
|
|
|
################################################################################
|
|
# HELPER FUNCTIONS
|
|
################################################################################
|
|
def checkNullString(string):
|
|
if string == NULL:
|
|
return string
|
|
|
|
if string[-1:] != '\x00':
|
|
return string + '\x00'
|
|
else:
|
|
return string
|
|
|
|
def hRfrGetNewDSA(dce, pUserDN=''):
|
|
request = RfrGetNewDSA()
|
|
request['ulFlags'] = 0
|
|
request['pUserDN'] = checkNullString(pUserDN)
|
|
request['ppszUnused'] = NULL
|
|
request['ppszServer'] = '\x00'
|
|
|
|
resp = dce.request(request)
|
|
resp['ppszServer'] = resp['ppszServer'][:-1]
|
|
|
|
if request['ppszUnused'] != NULL:
|
|
resp['ppszUnused'] = resp['ppszUnused'][:-1]
|
|
|
|
return resp
|
|
|
|
def hRfrGetFQDNFromServerDN(dce, szMailboxServerDN):
|
|
szMailboxServerDN = checkNullString(szMailboxServerDN)
|
|
request = RfrGetFQDNFromServerDN()
|
|
request['ulFlags'] = 0
|
|
request['szMailboxServerDN'] = szMailboxServerDN
|
|
request['cbMailboxServerDN'] = len(szMailboxServerDN)
|
|
|
|
resp = dce.request(request)
|
|
resp['ppszServerFQDN'] = resp['ppszServerFQDN'][:-1]
|
|
|
|
return resp
|