-->
当前位置:首页 > DayDayUp > 正文内容

纯python实现Finalshell密码解密

Luz1年前 (2023-12-08)DayDayUp2132

Finalshell的解密流程

Finalshell保存的服务器密码解密并不难,网络上也已经有很多的案例,比如:Finalshell密码批量解密(工具) - DayDayUp - HYLUZ

  1. static byte[] ranDomKey(byte[] head) {
  2.         long ks = 3680984568597093857L / (long)(new Random((long)head[5])).nextInt(127);
  3.         Random random = new Random(ks);
  4.         int t = head[0];
  5.         for(int i = 0; i < t; ++i) {
  6.             random.nextLong();
  7.         }
  8.         long n = random.nextLong();
  9.         Random r2 = new Random(n);
  10.         long[] ld = new long[]{(long)head[4], r2.nextLong(), (long)head[7], (long)head[3], r2.nextLong(), (long)head[1], random.nextLong(), (long)head[2]};
  11.         ByteArrayOutputStream bos = new ByteArrayOutputStream();
  12.         DataOutputStream dos = new DataOutputStream(bos);
  13.         long[] var15 = ld;
  14.         int var14 = ld.length;
  15.         for(int var13 = 0; var13 < var14; ++var13) {
  16.             long l = var15[var13];
  17.             try {
  18.                 dos.writeLong(l);
  19.             } catch (IOException var18) {
  20.                 var18.printStackTrace();
  21.             }
  22.         }
  23.         try {
  24.             dos.close();
  25.         } catch (IOException var17) {
  26.             var17.printStackTrace();
  27.         }
  28.         byte[] keyData = bos.toByteArray();
  29.         keyData = md5(keyData);
  30.         return keyData;
  31.     }

关键的密钥计算部分涉及了大量的java随机数运算,因此这些解密脚本往往都是使用java编写运行的。

python对java.util.Random随机数生成算法的实现

但是查阅文档可以知道,java.util.Random中的随机数是使用LCG算法实现的,LCG算法本身是可以使用python去复现的。

python实现 LCG算法 生成与java.util.Random相同的随机数序列 - DayDayUp - HYLUZ

基于python的Finalshell解密实现

整合了一下python中LCG算法的实现方式,与Finalshell中的解密逻辑,制作了基于python不依赖任何java环境的Finalshell密码解密程序。

  1. import base64
  2. import hashlib
  3. import struct
  4. from Crypto.Cipher import DES
  5. import re
  6. def remove_non_printable_chars(input_string):
  7.     cleaned_string = re.sub(r'[\x00-\x1F\x7F-\x9F]', '', input_string)
  8.     return cleaned_string
  9. class Random:
  10.     def __init__(self, seed=None):
  11.         if seed is None:
  12.             seed = (int((id(self) + id(seed)) * 997) & ((1 << 48) - 1))
  13.         self.seed = (seed ^ 0x5DEECE66D) & ((1 << 48) - 1)
  14.     
  15.     def next(self, bits):
  16.         self.seed = (self.seed * 0x5DEECE66D + 0xB) & ((1 << 48) - 1)
  17.         value = self.seed >> (48 - bits)
  18.         return value if value < (1 << (bits - 1)) else value - (1 << bits)
  19.     def next_int(self):
  20.         return self.next(32)
  21.     def next_long(self):
  22.         return (self.next(32) << 32) + self.next(32)
  23.     def next_float(self):
  24.         return self.next(24) / (1 << 24)
  25.     def next_double(self):
  26.         return ((self.next(26) << 27) + self.next(27)) * (1.0 / (1 << 53))
  27.         
  28. def des_decode(data, key):
  29.     cipher = DES.new(key, DES.MODE_ECB)
  30.     return cipher.decrypt(data)
  31. def random_key(head):
  32.     ilist=[24,54,89,120,19,49,85,115,14,44,80,110,9,40,75,106,43,73,109,12,38,68,104,7,33,64,99,3,28,59,94,125,112,16,51,82,107,11,46,77,103,6,41,72,98,1,37,67,4,35,70,101,0,30,65,96,122,25,61,91,117,20,56,86,74,104,13,43,69,99,8,38,64,95,3,34,59,90,125,29,93,123,32,62,88,119,27,58,83,114,22,53,79,109,17,48,35,66,101,5,31,61,96,0,26,56,92,122,21,51,87,117,55,85,120,24,50,80,116,19,45,75,111,14,40,71,106,10,50,81,116,20,45,76,111,15,41,71,106,10,36,66,102,5,69,100,8,39,65,95,3,34,60,90,126,29,55,85,121,24,12,42,78,108,7,37,73,103,2,33,68,99,124,28,63,94,31,61,97,0,26,57,92,123,21,52,87,118,17,47,82,113,100,4,39,70,96,126,34,65,91,121,30,60,86,116,25,55,120,23,58,89,115,18,54,84,110,13,49,79,105,9,44,75,62,92,1,31,57,88,123,27,52,83,118,22,48,78,113,17,81,112,20,51,76,107,15,46,72,102,10,41,67,97,6,36]
  33.     i=ilist[head[5]]
  34.     ks = 3680984568597093857 // i
  35.     random = Random(ks)
  36.     t = head[0]
  37.     for _ in range(t):
  38.         random.next_long()
  39.     n = random.next_long()
  40.     r2 = Random(n)
  41.     ld = [head[4], r2.next_long(), head[7], head[3], r2.next_long(), head[1], random.next_long(), head[2]]
  42.     byte_stream = bytearray()
  43.     for l in ld:
  44.         byte_stream.extend(struct.pack('!Q', l& ((1 << 64) - 1)))
  45.     #print(' '.join(format(byte, '02X') for byte in byte_stream))
  46.     key_data = md5(byte_stream)[:8]
  47.     return key_data
  48. def md5(data):
  49.     return hashlib.md5(data).digest()
  50. def decode_pass(data):
  51.     if data is None:
  52.         return None
  53.     rs = ""
  54.     buf = base64.b64decode(data)
  55.     head = buf[:8]
  56.     d = buf[8:]
  57.     key = random_key(head)
  58.     bt = des_decode(d, key)
  59.     rs = bt.decode('utf-8')
  60.     return remove_non_printable_chars(rs)
  61. while(1):
  62.     try:
  63.         a=input("Input Password:")
  64.         if('exit' in a):
  65.             break
  66.         print("Decode Result:",decode_pass(a))
  67.     except:
  68.         print('error')

运行截图

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。