You've already forked greyhack
205 lines
6.1 KiB
Python
205 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
|
from pathlib import Path
|
|
import re
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
SOURCE_DIR = ROOT / "source"
|
|
OUTPUT = ROOT / "provision.src"
|
|
DOWNLOADED_BINARIES = [
|
|
"nmap",
|
|
"smtp-user-list",
|
|
"ssh-server",
|
|
"http-server",
|
|
"ftp-server",
|
|
"chat-server",
|
|
"repository-server",
|
|
"wallet",
|
|
"decipher",
|
|
"rshell-interface",
|
|
"rshell-server",
|
|
"scanlib",
|
|
"scanrouter",
|
|
"sniffer",
|
|
]
|
|
DOWNLOADED_EXECUTABLES = ["Stocks.exe", "ExploitReport.exe", "AdminMonitor.exe"]
|
|
|
|
|
|
def variable_name(path: Path) -> str:
|
|
stem = re.sub(r"\W+", "_", path.stem.lower()).strip("_")
|
|
if not stem:
|
|
raise ValueError(f"cannot derive variable name from {path.name!r}")
|
|
if stem[0].isdigit():
|
|
stem = f"_{stem}"
|
|
return stem
|
|
|
|
|
|
def greyscript_string(value: str) -> str:
|
|
return '"' + value.replace('"', '""') + '"'
|
|
|
|
|
|
def content_lines(var: str, content: str) -> list[str]:
|
|
lines = [f'{var}_content = ""']
|
|
for line in content.splitlines():
|
|
lines.append(
|
|
f"{var}_content = {var}_content + {greyscript_string(line)} + NL"
|
|
)
|
|
return lines
|
|
|
|
|
|
def source_files() -> list[Path]:
|
|
files = sorted(SOURCE_DIR.glob("*.src"), key=lambda p: p.name)
|
|
bbuild = SOURCE_DIR / "bbuild.src"
|
|
if bbuild not in files:
|
|
raise RuntimeError(f"required bootstrap source missing: {bbuild}")
|
|
if bbuild in files:
|
|
files.remove(bbuild)
|
|
files.insert(0, bbuild)
|
|
return files
|
|
|
|
|
|
def chmod_lines(target: str, spec: str, indent: str = "") -> list[str]:
|
|
# Grey Hack File.chmod accepts one class per call, e.g. "u+rwx", not "u+rwx,g+rx".
|
|
return [f'{indent}{target}.chmod("{part}")' for part in spec.split(",")]
|
|
|
|
|
|
def install_binary_lines(var: str, bin_name: str) -> list[str]:
|
|
return install_file_lines(var, f"/bin/{bin_name}", bin_name)
|
|
|
|
|
|
def install_file_lines(var: str, path: str, name: str) -> list[str]:
|
|
return [
|
|
f'{var}_bin = cp.File("{path}")',
|
|
f'if not {var}_bin then exit("Failed to install {name}")',
|
|
f'{var}_bin.set_group("root")',
|
|
f'{var}_bin.set_owner("root")',
|
|
*chmod_lines(f"{var}_bin", "u+rwx,g+rx,o+rx"),
|
|
"",
|
|
]
|
|
|
|
|
|
def downloaded_program_lines(name: str, destination: str) -> list[str]:
|
|
var = variable_name(Path(name))
|
|
return [
|
|
f'{var}_bin = cp.File(home + "/{name}")',
|
|
f'if not {var}_bin then',
|
|
f'\tprint("Missing downloaded program: {name}")',
|
|
f'else',
|
|
f'\t{var}_bin.move("{destination}", "{name}")',
|
|
f'\t{var}_bin = cp.File("{destination}/{name}")',
|
|
f'\tif not {var}_bin then',
|
|
f'\t\tprint("Failed to install {name}")',
|
|
f'\telse',
|
|
f'\t\t{var}_bin.set_group("root")',
|
|
f'\t\t{var}_bin.set_owner("root")',
|
|
*chmod_lines(f"{var}_bin", "u+rwx,g+rx,o+rx", indent="\t\t"),
|
|
f'\tend if',
|
|
f'end if',
|
|
"",
|
|
]
|
|
|
|
|
|
def metaxploit_lines() -> list[str]:
|
|
return [
|
|
'metaxploit_lib = cp.File(home + "/metaxploit.so")',
|
|
"if not metaxploit_lib then",
|
|
'\tprint("Missing metaxploit.so")',
|
|
"else",
|
|
'\tmetaxploit_lib.copy(home + "/guest", "metaxploit.so")',
|
|
'\tmetaxploit_guest = cp.File(home + "/guest/metaxploit.so")',
|
|
"\tif not metaxploit_guest then",
|
|
'\t\tprint("Failed to copy metaxploit.so to guest")',
|
|
"\telse",
|
|
*chmod_lines("metaxploit_guest", "u+rwx,g+rx,o+rx", indent="\t\t"),
|
|
'\t\tmetaxploit_guest.set_group("guest")',
|
|
'\t\tmetaxploit_guest.set_owner("guest")',
|
|
"\tend if",
|
|
'\tmetaxploit_lib.move("/lib", "metaxploit.so")',
|
|
'\tmetaxploit_lib = cp.File("/lib/metaxploit.so")',
|
|
"\tif not metaxploit_lib then",
|
|
'\t\tprint("Failed to install metaxploit.so")',
|
|
"\telse",
|
|
'\t\tmetaxploit_lib.set_group("root")',
|
|
'\t\tmetaxploit_lib.set_owner("root")',
|
|
*chmod_lines("metaxploit_lib", "u+rw,g+rw,o+rw", indent="\t\t"),
|
|
"\tend if",
|
|
"end if",
|
|
"",
|
|
]
|
|
|
|
|
|
def build_provision() -> str:
|
|
sources = source_files()
|
|
if not sources:
|
|
raise RuntimeError(f"no .src files found in {SOURCE_DIR}")
|
|
|
|
output: list[str] = [
|
|
"cp = get_shell.host_computer",
|
|
'home = "/home/" + active_user',
|
|
"NL = char(10)",
|
|
'cp.create_folder(home, "source")',
|
|
'cp.create_folder(home, "guest")',
|
|
"",
|
|
]
|
|
|
|
for src in sources:
|
|
var = variable_name(src)
|
|
output.extend(
|
|
[
|
|
f'cp.touch(home + "/source/", "{src.name}")',
|
|
f'{var}_source = cp.File(home + "/source/{src.name}")',
|
|
*content_lines(var, src.read_text()),
|
|
f"{var}_source.set_content({var}_content)",
|
|
"",
|
|
]
|
|
)
|
|
|
|
for name in DOWNLOADED_BINARIES:
|
|
output.extend(downloaded_program_lines(name, "/bin"))
|
|
|
|
for name in DOWNLOADED_EXECUTABLES:
|
|
output.extend(downloaded_program_lines(name, "/usr/bin"))
|
|
|
|
output.extend(metaxploit_lines())
|
|
|
|
bbuild = sources[0]
|
|
bbuild_var = variable_name(bbuild)
|
|
output.extend(
|
|
[
|
|
f"build_result = get_shell.build({bbuild_var}_source.path, current_path)",
|
|
'if build_result != "" then exit(build_result)',
|
|
f'{bbuild_var}_bin = cp.File(current_path + "/bbuild")',
|
|
f'if not {bbuild_var}_bin then exit("Failed to build bbuild")',
|
|
f'{bbuild_var}_bin.move("/bin", "bbuild")',
|
|
*install_binary_lines(bbuild_var, "bbuild"),
|
|
]
|
|
)
|
|
|
|
for src in sources[1:]:
|
|
var = variable_name(src)
|
|
bin_name = src.stem
|
|
output.extend(
|
|
[
|
|
f'get_shell.launch("/bin/bbuild", {var}_source.path)',
|
|
*install_binary_lines(var, bin_name),
|
|
]
|
|
)
|
|
|
|
output.extend(
|
|
[
|
|
'provision_source = cp.File(home + "/provision.src")',
|
|
"if provision_source then provision_source.delete",
|
|
'provision_bin = cp.File(home + "/provision")',
|
|
"if provision_bin then provision_bin.delete",
|
|
]
|
|
)
|
|
return "\n".join(output) + "\n"
|
|
|
|
|
|
def main() -> None:
|
|
OUTPUT.write_text(build_provision())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|