• 获取MobaXterm 保存的账号密码


    MobaXterm 是非常优秀的shell 工具,使用过程中发现个人版无法查看历史保存的密码,故百度了以下 并将可行的方案整理如下:

    reg query HKEY_CURRENT_USER\Software\Mobatek\MobaXterm\C   # Credentials
    reg query HKEY_CURRENT_USER\Software\Mobatek\MobaXterm\P   # Passwords
    

    可以看到密码被编码成了新的字符串。在运行解码代码之前,我们还需要更新下Python环境。

    pip uninstall pycrypto
    pip install pycryptodome
    

    这里我们借助脚本,避免重复造轮子

    点击查看代码 ShowMobaXterm.py
    #!/usr/bin/env python3
    import sys, os, platform, random, base64, itertools, winreg
    from Crypto.Hash import SHA512
    from Crypto.Cipher import AES
    
    if platform.system().lower() != 'windows':
        print('Please run this script in Windows.')
        exit(-1)
    
    class MobaXtermCrypto:
    
        def __init__(self, SysHostname: bytes, SysUsername: bytes, SessionP: bytes = None):
            self._SysHostname = SysHostname
            self._SysUsername = SysUsername
            self._SessionP = SessionP
    
        def _KeyCrafter(self, **kargs) -> bytes:
            if kargs.get('ConnHostname') != None and kargs.get('ConnUsername') != None:
                s1 = self._SysUsername + self._SysHostname
                while len(s1) < 20:
                    s1 = s1 + s1
    
                s2 = kargs.get('ConnUsername') + kargs.get('ConnHostname')
                while len(s2) < 20:
                    s2 = s2 + s2
    
                key_space = [
                    s1.upper(),
                    s2.upper(),
                    s1.lower(),
                    s2.lower()
                ]
            else:
                s = self._SessionP
                while len(s) < 20:
                    s = s + s
    
                key_space = [
                    s.upper(),
                    s.upper(),
                    s.lower(),
                    s.lower()
                ]
    
            key = bytearray(b'0d5e9n1348/U2+67')
            for i in range(0, len(key)):
                b = key_space[(i + 1) % len(key_space)][i]
                if (b not in key) and (b in b'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/'):
                    key[i] = b
    
            return bytes(key)
    
        def EncryptPassword(self, Plaintext: bytes, ConnHostname: bytes, ConnUsername: bytes) -> str:
            key = self._KeyCrafter(ConnHostname = ConnHostname, ConnUsername = ConnUsername)
    
            ct = bytearray()
            for char in Plaintext:
                l = char & 0x0f
                ct.append(key[l])
                key = key[-1:] + key[0:-1]
    
                h = char >> 4
                ct.append(key[h])
                key = key[-1:] + key[0:-1]
    
            Ciphertext = bytearray()
            obfuscate_chars = bytes(filter(lambda char: char not in key, b'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/'))
            for char in ct:
                while random.choice([ True, False, False ]) == False:
                    Ciphertext.append(random.choice(obfuscate_chars))
                Ciphertext.append(char)
            while random.choice([ True, False, False ]) == False:
                Ciphertext.append(random.choice(obfuscate_chars))
    
            return Ciphertext.decode()
    
        def EncryptCredential(self, Plaintext: bytes) -> str:
            key = self._KeyCrafter()
    
            ct = bytearray()
            for char in Plaintext:
                l = char & 0x0f
                ct.append(key[l])
                key = key[-1:] + key[0:-1]
    
                h = char >> 4
                ct.append(key[h])
                key = key[-1:] + key[0:-1]
    
            Ciphertext = bytearray()
            obfuscate_chars = bytes(filter(lambda char: char not in key, b'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/'))
            for char in ct:
                while random.choice([ True, False, False ]) == False:
                    Ciphertext.append(random.choice(obfuscate_chars))
                Ciphertext.append(char)
            while random.choice([ True, False, False ]) == False:
                Ciphertext.append(random.choice(obfuscate_chars))
    
            return Ciphertext.decode()
    
        def DecryptPassword(self, Ciphertext: str, ConnHostname: bytes, ConnUsername: bytes) -> bytes:
            key = self._KeyCrafter(ConnHostname = ConnHostname, ConnUsername = ConnUsername)
    
            ct = bytearray()
            for char in Ciphertext.encode('ascii'):
                if char in key:
                    ct.append(char)
    
            if len(ct) % 2 == 0:
                pt = bytearray()
                for i in range(0, len(ct), 2):
                    l = key.find(ct[i])
                    key = key[-1:] + key[0:-1]
                    h = key.find(ct[i + 1])
                    key = key[-1:] + key[0:-1]
                    assert(l != -1 and h != -1)
                    pt.append(16 * h + l)
                return bytes(pt)
            else:
                raise ValueError('Invalid ciphertext.')
        
        def DecryptCredential(self, Ciphertext: str) -> bytes:
            key = self._KeyCrafter()
    
            ct = bytearray()
            for char in Ciphertext.encode('ascii'):
                if char in key:
                    ct.append(char)
    
            if len(ct) % 2 == 0:
                pt = bytearray()
                for i in range(0, len(ct), 2):
                    l = key.find(ct[i])
                    key = key[-1:] + key[0:-1]
                    h = key.find(ct[i + 1])
                    key = key[-1:] + key[0:-1]
                    assert (l != -1 and h != -1)
                    pt.append(16 * h + l)
                return bytes(pt)
            else:
                raise ValueError('Invalid ciphertext.')
    
    class MobaXtermCryptoSafe:
    
        def __init__(self, MasterPassword: bytes):
            self._Key = SHA512.new(MasterPassword).digest()[0:32]
    
        def EncryptPassword(self, Plaintext: bytes) -> str:
            iv = AES.new(key = self._Key, mode = AES.MODE_ECB).encrypt(b'\x00' * AES.block_size)
            cipher = AES.new(key = self._Key, iv = iv, mode = AES.MODE_CFB, segment_size = 8)
            return base64.b64encode(cipher.encrypt(Plaintext))
    
        def EncryptCredential(self, Plaintext: bytes) -> str:
            return self.EncryptPassword(Plaintext)
    
        def DecryptPassword(self, Ciphertext: str) -> bytes:
            iv = AES.new(key = self._Key, mode = AES.MODE_ECB).encrypt(b'\x00' * AES.block_size)
            cipher = AES.new(key = self._Key, iv = iv, mode = AES.MODE_CFB, segment_size = 8)
            return cipher.decrypt(base64.b64decode(Ciphertext))
        
        def DecryptCredential(self, Ciphertext: str) -> bytes:
            return self.DecryptPassword(Ciphertext)
    
    def WinRegistryReadValue(Root, SubKey: str, ValueName: str, ExpectValueType: int = None):
        Key = winreg.OpenKey(Root, SubKey)
        Value, ValueType = winreg.QueryValueEx(Key, ValueName)
        if type(ExpectValueType) == int and ValueType != ExpectValueType:
            raise TypeError('Expect %d, but %d is given.' % (ExpectValueType, ValueType))
        return Value
    
    if len(sys.argv) == 2:
        cipher = MobaXtermCryptoSafe(
            sys.argv[1].encode('ansi')
        )
    else:
        Value, ValueType = winreg.QueryValueEx(
            winreg.OpenKey(
                winreg.HKEY_CURRENT_USER, 
                'Software\\Mobatek\\MobaXterm'
            ), 
            'SessionP'
        ); assert(ValueType == winreg.REG_SZ)
    
        cipher = MobaXtermCrypto(
            platform.node().encode('ansi'), 
            os.getlogin().encode('ansi'), 
            Value.encode('ansi')
        )
    
    try:
        Key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\Mobatek\\MobaXterm\\C')
    
        print('Credentials'.center(48, '-'))
    
        for i in itertools.count(0):
            try:
                ValueName, Value, ValueType = winreg.EnumValue(Key, i)
                assert(ValueType == winreg.REG_SZ)
    
                CredentialUsername, CredentialPassword = Value.split(':')
    
                CredentialPassword = cipher.DecryptCredential(
                    CredentialPassword
                ).decode('ansi')
    
                print('[*] Name:     %s' % ValueName)
                print('[*] Username: %s' % CredentialUsername)
                print('[*] Password: %s' % CredentialPassword)
                print('')
            except OSError:
                break
    except FileNotFoundError:
        pass
    
    try:
        Key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\Mobatek\\MobaXterm\\P')
    
        print('Passwords'.center(48, '-'))
    
        for i in itertools.count(0):
            try:
                ValueName, Value, ValueType = winreg.EnumValue(Key, i)
                assert(ValueType == winreg.REG_SZ)
    
                ConnUsername, ConnHostname = ValueName.split('@')
                if ':' in ConnUsername:
                    ConnUsername = ConnUsername.split(':')[-1]
                
                ConnPassword = cipher.DecryptPassword(
                    Value, 
                    #ConnHostname.encode('ansi'), 
                    #ConnUsername.encode('ansi')
                ).decode('ansi')
    
                print('[*] Name:     %s' % ValueName)
                print('[*] Password: %s' % ConnPassword)
                print('')
            except OSError:
                break
    except FileNotFoundError:
        pass
    

    单条密码
    下面,我们就可以运行对应的文件进行密码解码了。我们随机挑选一个session,以第一个为例,取最后一列中的字符串W8jczTkOZRzGXWnc(编码后的密码),使用如下命令,即可解码出原始的密码!
    python MobaXtermCipher.py dec -p Master密码 W8jczTkOZRzGXWnc
    (PS:这里需要区分是否有本地的Master密码,要使用不同的参数,上述为配置了Master密码的情况,具体的可以查看github项目中的Readme)
    全部密码
    如果我们想看到全部Session的密码,还可以使用项目中的另外一个文件ShowMobaXterm.py。
    在作者的尝试过程中,发现也需要修改代码,可能也是和版本相关,大家在使用时可以根据环境情况决定是否要修改。具体的修改内容为注释掉代码中的230、231两行。
    ConnPassword = cipher.DecryptPassword(
    Value,
    # ConnHostname.encode('ansi'),
    # ConnUsername.encode('ansi')
    ).decode('ansi')
    然后,执行该文件即可得到全部Session的密码,这里同样用到了Master密码(MobaXterm 启动时提示你输入的密码)。
    python ShowMobaXterm.py Master密码
    输出如下

  • 相关阅读:
    网络层-数据平面:路由器工作原理
    文件系统和目录:目录
    文件系统与目录:文件系统
    运输层-可靠数据传输原理:选择重传 Selective Repeat Protocol
    运输层-可靠数据传输原理:回退N步 Go-Back_N Protocol
    JAVA学习笔记之多态
    约瑟夫环的递归解法C
    题目:汉诺塔问题
    题目:在同一坐标中输出sinx和cosx两条曲线
    n!的溢出问题及处理
  • 原文地址:https://www.cnblogs.com/vmsky/p/16266594.html
Copyright © 2020-2023  润新知