Here is the script that is used to interrupt autoboot (it includes the shell access and cim decoder)
python script.py --action stopboot --serial_port COM5
Start the script before powering on the device. At least on MSM422 this is the interrupt sequence that is used here. After the script exists you can connect to the serial port and just hit enter and the U-Boot console will pop up
import argparse
import hashlib
import re
import serial
import serial.tools.list_ports as port_list
import struct
#from Cryptodome.Cipher import AES
class Serial:
def __init__(self):
pass
def list_serial_ports(self):
ports = list(port_list.comports())
for p in ports:
print (p)
def stop_autoboot(self, serial_port):
import serial
import struct
import re
s = serial.Serial(serial_port, 115200, xonxoff=False, rtscts=False, dsrdtr=False)
s.flushInput()
s.flushOutput()
read_data = ''
found_autoboot = False
print('[*] Looking for Autoboot countdown string on "'+ serial_port +'"')
while True:
bytesToRead = s.inWaiting()
data_raw = s.read(bytesToRead)
if len(data_raw) > 0:
read_data += str(data_raw, 'utf-8', 'ignore')
if re.findall('Autoboot countdown', read_data):
if not found_autoboot:
print('[*] Found Autoboot countdown string')
found_autoboot = True
if found_autoboot:
print('[*] Sending interrupt string')
s.write(b'\x01\x0A')
if re.findall('INTERRUPT', read_data):
break
if re.findall('Unknown command', read_data):
break
print('[*] U-Boot command prompt available. Connect to serial port "' + serial_port + '" using 115200 baud rate')
class File:
def __init__(self):
pass
def read(self, path):
strg = b""
with open(path, "rb") as f:
header = f.read(8)
if header == b"CIM\xc1\x06\xad\xb0\x15":
print('[*] CIM Header version 6 (AES)')
print('[*] AES Encryption not supported ATM')
exit()
return decipher.decrypt(strg)
else:
print('[*] CIM Header version 5 (RC4)')
f.seek(0, 0)
while byte := f.read():
strg += byte
return strg
def write(self, path, data):
f = open(path, "wb")
f.write(data)
f.close()
class ShellAccess:
def __init__(self):
self.challenge_static = b'\xa7\x25\x57\xd1\x90\x0e\x3d\x6b'
self.sha = hashlib.sha1()
def generate(self, challenge):
self.sha.update(bytes(challenge[:3], 'utf-8'))
self.sha.update(self.challenge_static)
self.sha.update(bytes(challenge[3:], 'utf-8'))
digest = self.sha.digest()
return "%05u" % (digest[3] * digest[13])
class Firmware():
def __init__(self):
self.key = '379AeAB93l550g80'
def crypt_rc4(self, data):
return self.crypt_rc4_pp(data)
def crypt_rc4_pp(self, data):
S = list(range(256))
j = 0
key = self.key
for i in list(range(256)):
j = (j + S[i] + ord(key[i % len(key)])) % 256
S[i], S[j] = S[j], S[i]
j, y = (0, 0)
out = bytearray()
for char in data:
j = (j + 1) % 256
y = (y + S[j]) % 256
S[j], S[y] = S[y], S[j]
out.append(char ^ S[(S[j] + S[y]) % 256])
return out
parser = argparse.ArgumentParser(description='Colubris/HPE Helper')
parser.add_argument('--action', help='[cim|shell|stopboot]')
parser.add_argument('--infile', help='input file to decrypt/encrypt')
parser.add_argument('--outfile', help='output file to decrypt/encrypt')
parser.add_argument('--challenge', help='challenge issues by en->sh')
parser.add_argument('--serial_port', help='serial port that is used to stop autoboot')
args = parser.parse_args()
if not args.action:
print('[*] No action given.')
exit()
if args.action == 'cim':
if not args.infile or not args.outfile:
print('[*] Both infile and outfile are needed')
exit()
fl = File()
fw = Firmware()
data = fw.crypt_rc4(fl.read(args.infile))
fl.write(args.outfile, data)
elif args.action == 'shell':
sa = ShellAccess()
print( 'Response: %s' % sa.generate(args.challenge) )
elif args.action == 'stopboot':
s = Serial()
s.stop_autoboot(args.serial_port)