fork download
  1. import struct
  2. from Crypto.Cipher import AES
  3.  
  4. PASSWORD_DELIMITER = "%$%$"
  5. AES_KEY = [0xB8, 0x36, 0x3C, 0x9B, 0x77, 0xDA, 0xED, 0x4B,
  6. 0x9A, 0xBB, 0x9F, 0x2F, 0x6D, 0xF5, 0xF1, 0xD5,
  7. 0xCB, 0x64, 0x97, 0x5D, 0x5D, 0x3B, 0xCE, 0xE8,
  8. 0x82, 0x7F, 0x2F, 0x42, 0x23, 0x5F, 0x92, 0x29]
  9. AES_IV = [0x17, 0x81, 0x6F, 0x96, 0x5B, 0x07, 0x1E, 0xD4,
  10. 0xEC, 0x52, 0x84, 0xFF, 0x94, 0xFF, 0x71, 0x76]
  11. AES_MANGLE = [11, 17, 23, 29]
  12. BLOCK_SIZE = 24
  13.  
  14. def AscUnvisible(s):
  15. r = ""
  16. for c in s:
  17. if c == "~":
  18. c = "?"
  19. c = chr(ord(c) - 0x21)
  20. r += c
  21. return r
  22.  
  23. def DesEnhSysToLong(d):
  24. assert len(d) >= 4
  25.  
  26. x = 1
  27. r = 0
  28.  
  29. for i in range(0, 5):
  30. v0 = ((x << 1) + x) & 0xffffffff
  31. v1 = (v0 << 5) & 0xffffffff
  32. r += ord(d[i]) * x
  33. x = (v1 - v0) & 0xffffffff
  34.  
  35. return r
  36.  
  37. def PlainToBin_AES(s):
  38. out = []
  39. for i in range(0, 16, 4):
  40. r = DesEnhSysToLong(s[(i/4)*5:])
  41.  
  42. out.append(r)
  43.  
  44. r = ""
  45. for x in out:
  46. r += struct.pack(">I", x)
  47.  
  48. return r
  49.  
  50. def GenRandPwdKey_AES(key, salt):
  51. assert len(key) == 32 and len(salt) == 4
  52.  
  53. r = list(key[:])
  54.  
  55. for i in range(len(AES_MANGLE)):
  56. r[AES_MANGLE[i]] = ord(salt[i])
  57.  
  58. return "".join([chr(x) for x in r])
  59.  
  60. def decrypt_password(s):
  61. assert s.startswith(PASSWORD_DELIMITER) and s.endswith(PASSWORD_DELIMITER), \
  62. "[!] Not a Huawei AES256 password :-("
  63. t = s[len(PASSWORD_DELIMITER):-len(PASSWORD_DELIMITER)]
  64.  
  65. t = AscUnvisible(t)
  66.  
  67. plaintext = ""
  68. for block_offset in range(0, len(t), BLOCK_SIZE):
  69. block = t[block_offset:block_offset + BLOCK_SIZE]
  70.  
  71. # Last 4 chars are the salt
  72. salt = block[20:]
  73.  
  74. r = GenRandPwdKey_AES(AES_KEY, salt)
  75. block = PlainToBin_AES(block)
  76.  
  77. iv = "".join([chr(x) for x in AES_IV])
  78. cipher = AES.new(r, AES.MODE_CBC, iv)
  79. msg = cipher.decrypt(block)
  80.  
  81. plaintext += msg
  82.  
  83. plaintext = plaintext.rstrip("\x00")
  84. return plaintext
  85.  
  86. print (decrypt_password("%$%$P@=yCB4*qVAPCxA=#&+,,kbY`j{A;2|K<4DaC4;0Fxz+$qhc%$%$"))
Success #stdin #stdout 0.01s 7280KB
stdin
Standard input is empty
stdout
��h�Ѕ��߄�s9+7%��"�=�T�L�h