DJR

decrypt_huawei.py

DJR
Oct 30th, 2016
1,110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.15 KB | None | 0 0
  1. import sys
  2. import os
  3. from binascii import hexlify, unhexlify
  4. # pip install pycrypto
  5. from Crypto.Cipher import AES
  6. from Crypto.Hash import SHA256
  7. from Crypto.Util import number
  8.  
  9. # HG352
  10. modem_keys = {
  11.     "HG352": {
  12.         "RSA_D":
  13.             "1B18D0048611500CA489C51D7389B19A"
  14.             "F977E6F5BB8DD5E61A62E339499E6237"
  15.             "C234740129EBD25EF226AB7E498A0830"
  16.             "DF0A5D45F19F5055B906EBC5E71C16C5"
  17.             "A99E36D4F369701FAE2403E445BA3CAE"
  18.             "4B0C9526A82EDD90FECD78B7EDD5EA5E"
  19.             "6C98A0C4CABF3148E99E78DA0D5EB972"
  20.             "6F1533A6738F47C790037D532F403C0D",
  21.  
  22.         "RSA_N":
  23.             "A93591A1BFCB7615555C12CFE3AF0B68"
  24.             "5A6B94E8604A9441ABF7A5F268D4CBF9"
  25.             "6022E2F0694D679D2C8E4C2D4C3C0C44"
  26.             "60C5646E852A51EF7EBC2F0C88F08E80"
  27.             "6D991446348EB7AF280E607DDA363F4F"
  28.             "322E9B5005503F31F60353219F86443A"
  29.             "04E573FFEF541D21ADD1043E478D81B1"
  30.             "E79A5B434C5F64B3D5B141D7BEB59D71",
  31.         "AES128CBC_KEY": "3E4F5612EF64305955D543B0AE350880",
  32.         "AES128CBC_IV": "8049E91025A6B54876C3B4868090D3FC",
  33.     },
  34.     "HG658": {
  35.         "RSA_D":
  36.             "2345ADB2C06E54D7373E2A233A50150A"
  37.             "4044E417FBF76FB1AC8A444E72A345AA"
  38.             "14B7C349A4824C96DF9ECF7D8CC50425"
  39.             "32930DBD40D86FDCD892398702E3EA51"
  40.             "41C90F10494BB91440E89B104626CCCB"
  41.             "E45A5133362359732954BD63FCA58929"
  42.             "E3D890014FDF83847E6B19F0D9E1117E"
  43.             "9706984EAA57E114934B273366C4DBD1",
  44.  
  45.         "RSA_N": "C206CF93A9E6EE1CE17984DD54422AC4"
  46.                  "561A4EEB969D1BA81432626D6409FA03"
  47.                  "3B3738F8BBA046ACEF3BAC35094B70AF"
  48.                  "231D9DC43C1D68EDBEBE983E267B72FD"
  49.                  "3C2A7614D60FA7457B92B6A45C49F307"
  50.                  "EA23DE51E7E0C36D6440FC4F62C44CCB"
  51.                  "4169914E43DBFDAE536F002B2D670CE0"
  52.                  "A2A11FD1AF4C484C1A6FED9C228199A3",
  53.  
  54.         "AES128CBC_KEY": "48EE9D8621739F26C215C49071e2438A",
  55.         "AES128CBC_IV": "A68FBBCA44BB1F5364A530608BCDEAAB",
  56.     }
  57. }
  58.  
  59. RSA_D = None  # not required
  60. RSA_N = None
  61. AES128CBC_IV = None
  62. AES128CBC_KEY = None
  63.  
  64. XML_VERSION_STRING = b'<?xml version="1.0" ?>'
  65.  
  66.  
  67. def print_usage():
  68.     print("Usage : python " + sys.argv[0] + " config_file_path modem_model")
  69.     print("modem_model only HG352 and HG658.")
  70.     sys.exit(1)
  71.  
  72.  
  73. def load_config(config_file):
  74.     if os.path.isfile(config_file):
  75.         cf = open(config_file, "rb")
  76.         config = cf.read()
  77.         cf.close()
  78.     else:
  79.         print("Config file not found..exiting")
  80.         sys.exit(1)
  81.     return config
  82.  
  83.  
  84. def save_to_file(dest_file, data):
  85.     with open(dest_file, "wb") as write_file:
  86.         write_file.write(data)
  87.  
  88.  
  89. def get_sha256_hash_from_sig(sig):
  90.     sig_int = int(hexlify(sig), 16)
  91.     rsa_n = int(RSA_N, 16)
  92.     dec_sig_as_int = pow(sig_int, 0x10001, rsa_n)
  93.     decrypted_sig = number.long_to_bytes(dec_sig_as_int, 128)
  94.     target_sha256 = hexlify(decrypted_sig)[-64:]
  95.     return target_sha256
  96.  
  97.  
  98. def calc_actual_sha256_hash(enc_config_body):
  99.     sha256 = SHA256.new()
  100.     sha256.update(enc_config_body)
  101.     actual_sha256_sig = sha256.hexdigest()
  102.     actual_sha256_sig = str.encode(actual_sha256_sig)
  103.     return actual_sha256_sig
  104.  
  105.  
  106. def decrypt_body(enc_config_body):
  107.     iv = unhexlify(AES128CBC_IV)
  108.     key = unhexlify(AES128CBC_KEY)
  109.     cipher = AES.new(key, AES.MODE_CBC, iv)
  110.     decrypted_data = cipher.decrypt(enc_config_body)
  111.     # Strip block padding
  112.     decrypted_data = decrypted_data.rstrip(b'\0')
  113.     return decrypted_data
  114.  
  115.  
  116. def decrypt_config(input_file, output_file):
  117.     enc_config = load_config(input_file)
  118.     sig = enc_config[:0x80]
  119.     enc_config_body = enc_config[0x80:]
  120.  
  121.     print("verifying signature...")
  122.     target_sha256_hash = get_sha256_hash_from_sig(sig)
  123.     actual_sha256_hash = calc_actual_sha256_hash(enc_config_body)
  124.  
  125.     if actual_sha256_hash == target_sha256_hash:
  126.         print("Signature ok...")
  127.     else:
  128.         print("Signature not ok...exiting")
  129.         sys.exit(1)
  130.  
  131.     print("Decrypting...")
  132.     decrypted_data = decrypt_body(enc_config_body)
  133.  
  134.     check_config(decrypted_data)
  135.  
  136.     print("Saving decrypted config to " + output_file + "...")
  137.     save_to_file(output_file, decrypted_data)
  138.  
  139.  
  140. def check_config(new_config_file):
  141.     head = new_config_file[0:len(XML_VERSION_STRING)]
  142.     if head != XML_VERSION_STRING:
  143.         print("Not a valid config file...exiting")
  144.         sys.exit(1)
  145.  
  146.  
  147. def main():
  148.     if len(sys.argv) < 3:
  149.         print_usage()
  150.  
  151.     input_file = sys.argv[1]
  152.     global modem_keys, RSA_D, RSA_N, AES128CBC_IV, AES128CBC_KEY
  153.     sys.argv[2] = sys.argv[2].upper()  # required to be upper case.
  154.     if sys.argv[2] not in modem_keys.keys():
  155.         print("the only version available are : " + modem_keys.keys())
  156.         sys.exit(1)
  157.  
  158.     keys = modem_keys[sys.argv[2]]
  159.     RSA_D = keys["RSA_D"]
  160.     RSA_N = keys["RSA_N"]
  161.     AES128CBC_IV = keys["AES128CBC_IV"]
  162.     AES128CBC_KEY = keys["AES128CBC_KEY"]
  163.  
  164.     output_file = "config.xml"
  165.  
  166.     decrypt_config(input_file, output_file)
  167.  
  168.  
  169. if __name__ == "__main__":
  170.     main()
Advertisement
Add Comment
Please, Sign In to add comment