|
|
@ -589,7 +589,7 @@ logger.addHandler(handler)
|
|
|
|
|
|
|
|
|
|
|
|
import re
|
|
|
|
import re
|
|
|
|
import os
|
|
|
|
import os
|
|
|
|
from sys import stdin, exc_info, exit
|
|
|
|
from sys import stdin, exc_info, exit, version_info
|
|
|
|
from time import localtime, strftime, sleep, time
|
|
|
|
from time import localtime, strftime, sleep, time
|
|
|
|
from functools import reduce
|
|
|
|
from functools import reduce
|
|
|
|
from threading import Thread, active_count
|
|
|
|
from threading import Thread, active_count
|
|
|
@ -2403,74 +2403,72 @@ class VNC_Error(Exception): pass
|
|
|
|
class VNC:
|
|
|
|
class VNC:
|
|
|
|
def connect(self, host, port):
|
|
|
|
def connect(self, host, port):
|
|
|
|
self.fp = socket.create_connection((host, port))
|
|
|
|
self.fp = socket.create_connection((host, port))
|
|
|
|
resp = self.fp.recv(1024) # banner
|
|
|
|
resp = self.fp.recv(99) # banner
|
|
|
|
self.version = resp[:11]
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug('banner: %s' % repr(resp))
|
|
|
|
|
|
|
|
self.version = resp[:11].decode('ascii')
|
|
|
|
|
|
|
|
|
|
|
|
if len(resp) > 12:
|
|
|
|
if len(resp) > 12:
|
|
|
|
raise VNC_Error(self.version + ' ' + resp[20:])
|
|
|
|
raise VNC_Error('%s %s' % (self.version, resp[12:].decode('ascii', 'ignore')))
|
|
|
|
|
|
|
|
|
|
|
|
return self.version
|
|
|
|
return self.version
|
|
|
|
|
|
|
|
|
|
|
|
def login(self, password):
|
|
|
|
def login(self, password):
|
|
|
|
logger.debug("Remote version: %s" % self.version)
|
|
|
|
logger.debug('Remote version: %s' % self.version)
|
|
|
|
major, minor = self.version[6], self.version[10]
|
|
|
|
major, minor = self.version[6], self.version[10]
|
|
|
|
|
|
|
|
|
|
|
|
if major == '3' and minor == '8':
|
|
|
|
if (major, minor) in [('3', '8'), ('4', '1')]:
|
|
|
|
proto = 'RFB 003.008\n'
|
|
|
|
proto = b'RFB 003.008\n'
|
|
|
|
|
|
|
|
|
|
|
|
elif major == '3' and minor == '7':
|
|
|
|
elif (major, minor) == ('3', '7'):
|
|
|
|
proto = 'RFB 003.007\n'
|
|
|
|
proto = b'RFB 003.007\n'
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
proto = 'RFB 003.003\n'
|
|
|
|
proto = b'RFB 003.003\n'
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug('Client version: %s' % proto[:-1])
|
|
|
|
logger.debug('Client version: %s' % proto[:-1])
|
|
|
|
self.fp.sendall(proto)
|
|
|
|
self.fp.sendall(proto)
|
|
|
|
|
|
|
|
|
|
|
|
if minor in ('7', '8'):
|
|
|
|
sleep(0.5)
|
|
|
|
# send security type
|
|
|
|
|
|
|
|
resp = self.fp.recv(1024)
|
|
|
|
|
|
|
|
logger.debug("Security types supported: %s" % repr(resp))
|
|
|
|
|
|
|
|
self.fp.sendall('\x02') # always use classic VNC authentication
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# read server challenge
|
|
|
|
|
|
|
|
resp = self.fp.recv(1024)
|
|
|
|
|
|
|
|
logger.debug('Remote challenge: %s' % repr(resp))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if minor == '3':
|
|
|
|
resp = self.fp.recv(99)
|
|
|
|
if len(resp) < 4:
|
|
|
|
logger.debug('Security types supported: %s' % repr(resp))
|
|
|
|
raise VNC_Error('Unexpected response size (%d > 4): %s' % (len(resp), repr(resp)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
code = ord(resp[3])
|
|
|
|
if minor in ('7', '8'):
|
|
|
|
|
|
|
|
code = ord(resp[0:1])
|
|
|
|
if code == 0:
|
|
|
|
if code == 0:
|
|
|
|
raise VNC_Error('Session setup failed: %s' % repr(resp))
|
|
|
|
raise VNC_Error('Session setup failed: %s' % resp.decode('ascii', 'ignore'))
|
|
|
|
|
|
|
|
|
|
|
|
elif code == 1:
|
|
|
|
self.fp.sendall(b'\x02') # always use classic VNC authentication
|
|
|
|
raise VNC_Error('No authentication required: %s' % repr(resp))
|
|
|
|
resp = self.fp.recv(99)
|
|
|
|
|
|
|
|
|
|
|
|
elif code == 2:
|
|
|
|
else: # minor == '3':
|
|
|
|
if len(resp) != 20:
|
|
|
|
code = ord(resp[3:4])
|
|
|
|
raise VNC_Error('Unexpected challenge size (unsupported authentication type ?): %s' % repr(resp))
|
|
|
|
if code != 2:
|
|
|
|
|
|
|
|
raise VNC_Error('Session setup failed: %s' % resp.decode('ascii', 'ignore'))
|
|
|
|
|
|
|
|
|
|
|
|
resp = resp[4:20]
|
|
|
|
resp = resp[-16:]
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
if len(resp) != 16:
|
|
|
|
raise VNC_Error('Session setup unknown response')
|
|
|
|
raise VNC_Error('Unexpected challenge size (unsupported authentication type ?)')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug('challenge: %s' % repr(resp))
|
|
|
|
|
|
|
|
pw = password.ljust(8, '\x00')[:8] # make sure it is 8 chars long, zero padded
|
|
|
|
|
|
|
|
|
|
|
|
pw = (password + '\0' * 8)[:8] # make sure it is 8 chars long, zero padded
|
|
|
|
|
|
|
|
key = self.gen_key(pw)
|
|
|
|
key = self.gen_key(pw)
|
|
|
|
logger.debug('key: %s' % repr(key))
|
|
|
|
logger.debug('key: %s' % repr(key))
|
|
|
|
|
|
|
|
|
|
|
|
des = DES.new(key, DES.MODE_ECB)
|
|
|
|
des = DES.new(key, DES.MODE_ECB)
|
|
|
|
enc = des.encrypt(resp)
|
|
|
|
enc = des.encrypt(resp)
|
|
|
|
logger.debug('enc: %s' % repr(enc))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug('enc: %s' % repr(enc))
|
|
|
|
self.fp.sendall(enc)
|
|
|
|
self.fp.sendall(enc)
|
|
|
|
resp = self.fp.recv(1024)
|
|
|
|
|
|
|
|
|
|
|
|
resp = self.fp.recv(99)
|
|
|
|
logger.debug('resp: %s' % repr(resp))
|
|
|
|
logger.debug('resp: %s' % repr(resp))
|
|
|
|
|
|
|
|
|
|
|
|
code = ord(resp[3])
|
|
|
|
code = ord(resp[3:4])
|
|
|
|
mesg = resp[8:]
|
|
|
|
mesg = resp[8:].decode('ascii', 'ignore')
|
|
|
|
|
|
|
|
|
|
|
|
if code == 1:
|
|
|
|
if code == 1:
|
|
|
|
return code, mesg or 'Authentication failure'
|
|
|
|
return code, mesg or 'Authentication failure'
|
|
|
@ -2490,15 +2488,19 @@ class VNC:
|
|
|
|
for i in range(8):
|
|
|
|
for i in range(8):
|
|
|
|
if bsrc & (1 << i):
|
|
|
|
if bsrc & (1 << i):
|
|
|
|
btgt = btgt | (1 << 7-i)
|
|
|
|
btgt = btgt | (1 << 7-i)
|
|
|
|
newkey.append(chr(btgt))
|
|
|
|
newkey.append(btgt)
|
|
|
|
return ''.join(newkey)
|
|
|
|
|
|
|
|
|
|
|
|
if version_info[0] == 2:
|
|
|
|
|
|
|
|
return ''.join(chr(c) for c in newkey)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
return bytes(newkey)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VNC_login:
|
|
|
|
class VNC_login:
|
|
|
|
'''Brute-force VNC authentication'''
|
|
|
|
'''Brute-force VNC authentication'''
|
|
|
|
|
|
|
|
|
|
|
|
usage_hints = (
|
|
|
|
usage_hints = (
|
|
|
|
"""%prog host=10.0.0.1 password=FILE0 0=passwords.txt -x retry:fgrep!='Authentication failure' --max-retries -1 -x quit:code=0""",
|
|
|
|
"""%prog host=10.0.0.1 password=FILE0 0=passwords.txt -t 1 -x retry:fgrep!='Authentication failure' --max-retries -1 -x quit:code=0""",
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
available_options = (
|
|
|
|
available_options = (
|
|
|
@ -2514,13 +2516,13 @@ class VNC_login:
|
|
|
|
self.m = VNC()
|
|
|
|
self.m = VNC()
|
|
|
|
def execute(self, host, port=None, password=None):
|
|
|
|
def execute(self, host, port=None, password=None):
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
code, mesg = '0', self.m.connect(host, int(port or 5900))
|
|
|
|
code, mesg = 0, self.m.connect(host, int(port or 5900))
|
|
|
|
|
|
|
|
|
|
|
|
if password is not None:
|
|
|
|
if password is not None:
|
|
|
|
code, mesg = self.m.login(password)
|
|
|
|
code, mesg = self.m.login(password)
|
|
|
|
|
|
|
|
|
|
|
|
except VNC_Error as e:
|
|
|
|
except VNC_Error as e:
|
|
|
|
code, mesg = '2', str(e)
|
|
|
|
code, mesg = 2, str(e)
|
|
|
|
logger.debug('VNC_Error: %s' % mesg)
|
|
|
|
logger.debug('VNC_Error: %s' % mesg)
|
|
|
|
|
|
|
|
|
|
|
|
return self.Response(code, mesg)
|
|
|
|
return self.Response(code, mesg)
|
|
|
@ -3037,4 +3039,4 @@ Available modules:
|
|
|
|
|
|
|
|
|
|
|
|
# }}}
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
|
|
|
|
# vim: ts=2 sw=2 sts=2 et fdm=marker
|
|
|
|
# vim: ts=2 sw=2 sts=2 et fdm=marker bg=dark
|
|
|
|