output a bit more intuitive, fixed bug in smb_lookupsid

pull/4/merge
lanjelot 11 years ago
parent 251f33cd08
commit 5da0649d2e

@ -49,6 +49,7 @@ Currently it supports the following modules:
- mssql_login : Brute-force MSSQL - mssql_login : Brute-force MSSQL
- oracle_login : Brute-force Oracle - oracle_login : Brute-force Oracle
- mysql_login : Brute-force MySQL - mysql_login : Brute-force MySQL
- mysql_queries : Brute-force MySQL queries
- pgsql_login : Brute-force PostgreSQL - pgsql_login : Brute-force PostgreSQL
- vnc_login : Brute-force VNC - vnc_login : Brute-force VNC
@ -236,7 +237,7 @@ and as a result the exception is caught upstream by the controller.
Such exceptions, or failures, are not immediately reported to the user, the Such exceptions, or failures, are not immediately reported to the user, the
controller will retry 4 more times (see --max-retries) before reporting the controller will retry 4 more times (see --max-retries) before reporting the
failed payload with logging level ERROR. failed payload with logging level "FAIL".
* Read carefully the following examples to get a good understanding of how patator works. * Read carefully the following examples to get a good understanding of how patator works.
@ -579,6 +580,7 @@ TODO
# logging {{{ # logging {{{
import logging import logging
logging._levelNames[logging.ERROR] = 'FAIL'
class MyLoggingFormatter(logging.Formatter): class MyLoggingFormatter(logging.Formatter):
dft_fmt = '%(asctime)s %(name)-7s %(levelname)7s - %(message)s' dft_fmt = '%(asctime)s %(name)-7s %(levelname)7s - %(message)s'
@ -711,7 +713,7 @@ class Controller:
builtin_actions = ( builtin_actions = (
('ignore', 'do not report'), ('ignore', 'do not report'),
('retry', 'try payload again'), ('retry', 'try payload again'),
('free', 'dismiss future types of payloads'), ('free', 'dismiss future similar payloads'),
('quit', 'terminate execution now'), ('quit', 'terminate execution now'),
) )
@ -1168,8 +1170,8 @@ Please read the README inside for more examples and usage information.
self.total_size -= sum(self.resume) self.total_size -= sum(self.resume)
logger.info('') logger.info('')
logger.info('%-15s | %-25s \t | %5s | %s' % ('code & size', 'candidate', 'num', 'mesg')) logger.info(self.module.Response.logformat % self.module.Response.logheader)
logger.info('-' * 63) logger.info('-' * 70)
self.start_time = time() self.start_time = time()
count = 0 count = 0
@ -1347,7 +1349,7 @@ Please read the README inside for more examples and usage information.
p.current = current p.current = current
p.seconds[p.done_count % len(p.seconds)] = seconds p.seconds[p.done_count % len(p.seconds)] = seconds
msg = '%-15s | %-25s \t | %5d | %s' % (resp.compact(), current, offset, resp) msg = self.module.Response.logformat % (resp.compact()+(current, offset, resp))
if 'fail' in actions: if 'fail' in actions:
logger.error(msg) logger.error(msg)
@ -1365,7 +1367,7 @@ Please read the README inside for more examples and usage information.
p.hits_count += 1 p.hits_count += 1
if self.log_dir: if self.log_dir:
filename = '%d_%s' % (offset, resp.compact().replace(' ', '_')) filename = '%d_%s' % (offset, ':'.join(map(str, resp.compact())))
with open('%s/%s.txt' % (self.log_dir, filename), 'w') as f: with open('%s/%s.txt' % (self.log_dir, filename), 'w') as f:
f.write(resp.dump()) f.write(resp.dump())
@ -1479,6 +1481,9 @@ class Response_Base:
('egrep', 'search for regex'), ('egrep', 'search for regex'),
) )
logformat = '%-5s %-4s | %-34s | %5s | %s'
logheader = ('code', 'size', 'candidate', 'num', 'mesg')
def __init__(self, code, mesg, trace=None): def __init__(self, code, mesg, trace=None):
self.code = code self.code = code
self.mesg = mesg self.mesg = mesg
@ -1486,7 +1491,7 @@ class Response_Base:
self.size = len(self.mesg) self.size = len(self.mesg)
def compact(self): def compact(self):
return '%s %d' % (self.code, self.size) return self.code, self.size
def __str__(self): def __str__(self):
return self.mesg return self.mesg
@ -1987,7 +1992,7 @@ class LDAP_login:
def execute(self, host, port='389', binddn='', bindpw='', basedn='', ssl='0'): def execute(self, host, port='389', binddn='', bindpw='', basedn='', ssl='0'):
uri = 'ldap%s://%s:%s' % ('s' if ssl != '0' else '', host, port) uri = 'ldap%s://%s:%s' % ('s' if ssl != '0' else '', host, port)
cmd = ['ldapsearch', '-H', uri, '-e', 'ppolicy', '-D', binddn, '-w', bindpw, '-b', basedn] cmd = ['ldapsearch', '-H', uri, '-e', 'ppolicy', '-D', binddn, '-w', bindpw, '-b', basedn, '-s', 'one']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={'LDAPTLS_REQCERT': 'never'}) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={'LDAPTLS_REQCERT': 'never'})
out = p.stdout.read() out = p.stdout.read()
err = p.stderr.read() err = p.stderr.read()
@ -2017,7 +2022,7 @@ class SMB_login(TCP_Cache):
usage_hints = ( usage_hints = (
"""%prog host=10.0.0.1 user=FILE0 password=FILE1 0=logins.txt 1=passwords.txt""" """%prog host=10.0.0.1 user=FILE0 password=FILE1 0=logins.txt 1=passwords.txt"""
""" -x ignore:fgrep=STATUS_LOGON_FAILURE""", """ -x ignore:fgrep='unknown user name or bad password'""",
) )
available_options = ( available_options = (
@ -2030,26 +2035,32 @@ class SMB_login(TCP_Cache):
) )
available_options += TCP_Cache.available_options available_options += TCP_Cache.available_options
Response = Response_Base class Response(Response_Base):
logformat = '%-8s %-4s | %-34s | %5s | %s'
# ripped from medusa smbnt.c # ripped from medusa smbnt.c
error_map = { error_map = {
0xFF: 'UNKNOWN_ERROR_CODE', 0xffff: 'UNKNOWN_ERROR_CODE',
0x00: 'STATUS_SUCCESS', 0x0000: 'STATUS_SUCCESS',
0x0D: 'STATUS_INVALID_PARAMETER', 0x000d: 'STATUS_INVALID_PARAMETER',
0x5E: 'STATUS_NO_LOGON_SERVERS', 0x005e: 'STATUS_NO_LOGON_SERVERS',
0x6D: 'STATUS_LOGON_FAILURE', 0x006d: 'STATUS_LOGON_FAILURE',
0x6E: 'STATUS_ACCOUNT_RESTRICTION', 0x006e: 'STATUS_ACCOUNT_RESTRICTION',
0x6F: 'STATUS_INVALID_LOGON_HOURS', 0x006f: 'STATUS_INVALID_LOGON_HOURS',
0x70: 'STATUS_INVALID_WORKSTATION', 0x0002: 'STATUS_INVALID_LOGON_HOURS (LM Authentication)',
0x71: 'STATUS_PASSWORD_EXPIRED', 0x0070: 'STATUS_INVALID_WORKSTATION',
0x72: 'STATUS_ACCOUNT_DISABLED', 0x0002: 'STATUS_INVALID_WORKSTATION (LM Authentication)',
0x5B: 'STATUS_LOGON_TYPE_NOT_GRANTED', 0x0071: 'STATUS_PASSWORD_EXPIRED',
0x8D: 'STATUS_TRUSTED_RELATIONSHIP_FAILURE', 0x0072: 'STATUS_ACCOUNT_DISABLED',
0x93: 'STATUS_ACCOUNT_EXPIRED', 0x015b: 'STATUS_LOGON_TYPE_NOT_GRANTED',
0x24: 'STATUS_PASSWORD_MUST_CHANGE', 0x018d: 'STATUS_TRUSTED_RELATIONSHIP_FAILURE',
0x34: 'STATUS_ACCOUNT_LOCKED_OUT', 0x0193: 'STATUS_ACCOUNT_EXPIRED',
0x01: 'AS400_STATUS_LOGON_FAILURE', 0x0002: 'STATUS_ACCOUNT_EXPIRED_OR_DISABLED (LM Authentication)',
0x0224: 'STATUS_PASSWORD_MUST_CHANGE',
0x0002: 'STATUS_PASSWORD_MUST_CHANGE (LM Authentication)',
0x0234: 'STATUS_ACCOUNT_LOCKED_OUT (No LM Authentication Code)',
0x0001: 'AS400_STATUS_LOGON_FAILURE',
0x0064: 'The machine you are logging onto is protected by an authentication firewall.',
} }
def connect(self, host, port): def connect(self, host, port):
@ -2077,30 +2088,31 @@ class SMB_login(TCP_Cache):
self.reset() self.reset()
except impacket_smb.SessionError as e: except impacket_smb.SessionError as e:
code = '%x-%x' % (e.error_class, e.error_code) code = '%04x%04x' % (e.error_class, e.error_code)
mesg = self.error_map.get(e.error_code, '')
error_class = e.error_classes.get(e.error_class, None) # (ERRNT, {}) error_class = e.error_classes.get(e.error_class, None) # -> ("ERRNT", nt_msgs)
if error_class: if error_class:
class_str = error_class[0] # 'ERRNT' class_str = error_class[0] # "ERRNT"
error_tuple = error_class[1].get(e.error_code, None) # ('ERRnoaccess', 'Access denied.') or None error_tuple = error_class[1].get(e.error_code, None) # -> ("STATUS_LOGON_FAILURE","Logon failure: unknown user name or bad password.") or None
if error_tuple: if error_tuple:
mesg += ' - %s %s' % error_tuple mesg = '%s %s' % error_tuple
else: else:
mesg += ' - %s' % class_str mesg = '%s' % class_str
else:
mesg = self.error_map.get(e.error_code & 0x0000fffff, '')
if persistent == '0': if persistent == '0':
self.reset() self.reset()
return self.Response(code, mesg) return self.Response(code, mesg)
class DCE_Connection(TCP_Connection): class DCE_Connection(TCP_Connection):
def __init__(self, fp, smbt): def __init__(self, fp, smbt):
self.fp = fp
self.smbt = smbt self.smbt = smbt
TCP_Connection.__init__(self, fp)
def close(self): def close(self):
self.smbt.get_socket().close() self.smbt.get_socket().close()
@ -2117,6 +2129,8 @@ class SMB_lookupsid(TCP_Cache):
('port', 'ports to target [139]'), ('port', 'ports to target [139]'),
('sid', 'SID to test'), ('sid', 'SID to test'),
('rid', 'RID to test'), ('rid', 'RID to test'),
('user', 'username to use if auth required'),
('password', 'password to use if auth required'),
) )
available_options += TCP_Cache.available_options available_options += TCP_Cache.available_options
@ -2601,7 +2615,8 @@ class Oracle_login:
) )
available_actions = () available_actions = ()
Response = Response_Base class Response(Response_Base):
logformat = '%-9s %-4s | %-34s | %5s | %s'
def execute(self, host, port='1521', user='', password='', sid=''): def execute(self, host, port='1521', user='', password='', sid=''):
dsn = cx_Oracle.makedsn(host, port, sid) dsn = cx_Oracle.makedsn(host, port, sid)
@ -2681,12 +2696,15 @@ class Controller_HTTP(Controller):
class Response_HTTP(Response_Base): class Response_HTTP(Response_Base):
logformat = '%-4s %-13s | %-32s | %5s | %s'
logheader = ('code', 'size:clen', 'candidate', 'num', 'mesg')
def __init__(self, code, response, trace=None, content_length=-1): def __init__(self, code, response, trace=None, content_length=-1):
self.content_length = content_length self.content_length = content_length
Response_Base.__init__(self, code, response, trace) Response_Base.__init__(self, code, response, trace)
def compact(self): def compact(self):
return '%s %s' % (self.code, '%d:%d' % (self.size, self.content_length)) return self.code, '%d:%d' % (self.size, self.content_length)
def __str__(self): def __str__(self):
i = self.mesg.rfind('HTTP/', 0, 5000) i = self.mesg.rfind('HTTP/', 0, 5000)

Loading…
Cancel
Save