Created
April 8, 2023 11:01
-
-
Save andyboeh/d295c80a57d62379b926640762f3d5dd to your computer and use it in GitHub Desktop.
Enable SSHD on the Aclatel HH40V (modify backup file)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
import sys | |
import subprocess | |
import tempfile | |
import struct | |
import shutil | |
import hashlib | |
class SSHEnabler(object): | |
def __init__(self, filepath, directory): | |
self.openssl = None | |
self.filepath = filepath | |
self.directory = directory | |
self.check_openssl() | |
def decrypt_file(self): | |
if not os.path.exists(self.filepath): | |
print(f"Input file does not exist: {self.filepath}") | |
return False | |
ret = subprocess.run([self.openssl, "aes-128-cbc", "-d", "-k", "oacgnahsnauyilil", "-base64", "-in", self.filepath, "-out", self.directory + os.path.sep + "decrypted.tar.gz", "-md", "md5"]) | |
if ret.returncode != 0: | |
print("Error decrypting file") | |
return False | |
ret = subprocess.run(["tar", "zxf", self.directory + os.path.sep + "decrypted.tar.gz", "-C", self.directory]) | |
if ret.returncode != 0: | |
print("Error extracting file") | |
return False | |
if not os.path.exists(self.directory + os.path.sep + "configure.bin"): | |
print("Extracted file configure.bin does not exist") | |
return False | |
os.remove(self.directory + os.path.sep + "decrypted.tar.gz") | |
with open(self.directory + os.path.sep + "configure.bin", "rb") as f: | |
head = f.read(45) # The first 45 bytes contain ALCATEL BACKUP HEAD, the filename of the extracted file and the lenght of it | |
if head[0:24] != b"ALCATEL BACKUP FILE HEAD": | |
print("Head does not start with ALCATEL BACKUP FILE HEAD") | |
return False | |
length, = struct.unpack(">h", head[43:45]) | |
ret = subprocess.call(["dd", "if="+self.directory + os.path.sep + "configure.bin", "of="+self.directory + os.path.sep + "backup.tar.gz", "bs=1", "skip=45", "count=" + str(length)]) | |
ret = subprocess.call(["dd", "if="+self.directory + os.path.sep + "configure.bin", "of="+self.directory + os.path.sep + "configure.bin.head", "bs=1", "count=43"]) | |
ret = subprocess.call(["dd", "if="+self.directory + os.path.sep + "configure.bin", "of="+self.directory + os.path.sep + "configure.bin.tail", "bs=1", "skip=" + str(45 + length)]) | |
os.remove(self.directory + os.path.sep + "configure.bin") | |
os.remove(self.directory + os.path.sep + "configure.md5") | |
ret = subprocess.run(["tar", "zxf", self.directory + os.path.sep + "backup.tar.gz", "-C", self.directory]) | |
if ret.returncode != 0: | |
print("Error extracting backup.tar.gz") | |
return False | |
if not os.path.exists(self.directory + os.path.sep + "backup_dir" + os.path.sep + "sysconfig.tar.gz"): | |
print("sysconfig.tar.gz in backup file not found") | |
return False | |
os.remove(self.directory + os.path.sep + "backup.tar.gz") | |
ret = subprocess.run(["tar", "zxf", self.directory + os.path.sep + "backup_dir" + os.path.sep + "sysconfig.tar.gz", "-C", self.directory + os.path.sep + "backup_dir"]) | |
if ret.returncode != 0: | |
print("Error extracting sysconfig.tar.gz") | |
return False | |
if not os.path.exists(self.directory + os.path.sep + "backup_dir" + os.path.sep + "etc" + os.path.sep + "rc.local"): | |
print("rc.local not found") | |
return False | |
os.remove(self.directory + os.path.sep + "backup_dir" + os.path.sep + "etc" + os.path.sep + "rc.local") | |
with open(self.directory + os.path.sep + "backup_dir" + os.path.sep + "etc" + os.path.sep + "rc.local", "w") as f: | |
f.write("# Put your custom commands here that should be executed once\n") | |
f.write("# the system init finished. By default this file does nothing.\n") | |
f.write("\n") | |
f.write("/etc/init.d/dropbear start\n") | |
f.write("\n") | |
f.write("exit 0\n") | |
os.remove(self.directory + os.path.sep + "backup_dir" + os.path.sep + "sysconfig.tar.gz") | |
ret = subprocess.run(["tar", "zcf", self.directory + os.path.sep + "backup_dir" + os.path.sep + "sysconfig.tar.gz", "-C", self.directory + os.path.sep + "backup_dir", "etc"]) | |
if ret.returncode != 0: | |
print("Error creating sysconfig.tar.gz") | |
return False | |
shutil.rmtree(self.directory + os.path.sep + "backup_dir" + os.path.sep + "etc") | |
ret = subprocess.run(["tar", "zcf", self.directory + os.path.sep + "backup.tar.gz", "-C", self.directory, "backup_dir"]) | |
if ret.returncode != 0: | |
print("Error creating backup.tar.gz") | |
return False | |
shutil.rmtree(self.directory + os.path.sep + "backup_dir") | |
size = os.path.getsize(self.directory + os.path.sep + "backup.tar.gz") | |
with open(self.directory + os.path.sep + "configure.bin.head", "ab") as f: | |
f.write(struct.pack(">h", size)) | |
with open(self.directory + os.path.sep + "configure.bin", "wb") as f: | |
with open(self.directory + os.path.sep + "configure.bin.head", "rb") as g: | |
f.write(g.read()) | |
with open(self.directory + os.path.sep + "backup.tar.gz", "rb") as g: | |
f.write(g.read()) | |
with open(self.directory + os.path.sep + "configure.bin.tail", "rb") as g: | |
f.write(g.read()) | |
os.remove(self.directory + os.path.sep + "configure.bin.head") | |
os.remove(self.directory + os.path.sep + "configure.bin.tail") | |
os.remove(self.directory + os.path.sep + "backup.tar.gz") | |
md5 = hashlib.md5(open(self.directory + os.path.sep + "configure.bin", "rb").read()).hexdigest() | |
with open(self.directory + os.path.sep + "configure.md5", "w") as f: | |
f.write(md5 + "\n") | |
ret = subprocess.run(["tar", "zcf", self.directory + os.path.sep + "decrypted.tar.gz", "-C", self.directory, "configure.bin", "configure.md5"]) | |
if ret.returncode != 0: | |
print("Error creating final .tar.gz file") | |
return False | |
ret = subprocess.run([self.openssl, "aes-128-cbc", "-e", "-k", "oacgnahsnauyilil", "-base64", "-in", self.directory + os.path.sep + "decrypted.tar.gz", "-out", self.filepath + "_mod.bin", "-md", "md5"]) | |
def which(self, program): | |
def is_exe(fpath): | |
return os.path.isfile(fpath) and os.access(fpath, os.X_OK) | |
fpath, fname = os.path.split(program) | |
if fpath: | |
if is_exe(program): | |
return program | |
else: | |
for path in os.environ["PATH"].split(os.pathsep): | |
path = path.strip('"') | |
exe_file = os.path.join(path, program) | |
if is_exe(exe_file): | |
return exe_file | |
return None | |
def check_openssl(self): | |
self.openssl = self.which("openssl") | |
if self.openssl: | |
ret = subprocess.run([self.openssl, "version"], stdout = subprocess.PIPE, | |
universal_newlines = True) | |
if ret.returncode == 0: | |
version = ret.stdout.replace('\n', '') | |
return version | |
return False | |
if len(sys.argv) < 2: | |
print("Usage: enable_sshd.py configure.bin") | |
sys.exit(1) | |
with tempfile.TemporaryDirectory() as tempdir: | |
enabler = SSHEnabler(sys.argv[1], tempdir) | |
enabler.decrypt_file() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment