Skip to content

Instantly share code, notes, and snippets.

@milankragujevic
Forked from andyboeh/enable_sshd.py
Created April 25, 2023 10:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save milankragujevic/7158d3f7a09d77c99065431722499bfe to your computer and use it in GitHub Desktop.
Save milankragujevic/7158d3f7a09d77c99065431722499bfe to your computer and use it in GitHub Desktop.
Enable SSHD on the Aclatel HH40V (modify backup file)
#!/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