extractors/lobshot/lobshot_config_extractor.py (59 lines of code) (raw):

import argparse import pathlib import lief import typing from nightmare.malware.lobshot import configuration from nightmare import utils def get_rdata_section_content(file_path: pathlib.Path) -> None | bytes: pe = lief.parse(str(file_path)) if not pe: return None for section in pe.sections: if section.name.lower() == ".rdata": return bytes(section.content) else: return None def extract_configuration( path: pathlib.Path, ) -> typing.Optional[tuple[bytes, int | None]]: rdata = get_rdata_section_content(path) if not rdata: print(".rdata section not found: {}\n".format(path)) return None return configuration.parse(rdata) def parse_arguments() -> argparse.Namespace: parser = argparse.ArgumentParser("LOBSHOT config file extractor") group = parser.add_mutually_exclusive_group(required=True) group.add_argument("-f", "--file", type=pathlib.Path, help="LOBSHOT file path") group.add_argument("-d", "--directory", type=pathlib.Path, help="LOBSHOT directory") return parser.parse_args() def display_results( path: pathlib.Path, configuration: tuple[bytes, typing.Optional[int]] ) -> None: print("File: {}".format(path)) print("IP: {}".format(configuration[0].decode("utf-8"))) print("Port: {}\n".format(configuration[1])) def print_banner() -> None: print( r""" _ ____ ____ _____ _ _ ____ _______ ____ | | / __ \ | _ \ / ____|| | | | / __ \|__ __| /xxxx\ | | | | | || |_) || (___ | |__| || | | | | | |xxxxxx| | | | | | || _ < \___ \ | __ || | | | | | |xxxxxx| | |____| |__| || |_) | ____) || | | || |__| | | | \xxxxxx/ |______|\____/ |____/ |_____/ |_| |_| \____/ |_| \xxxx/ \--/ _____ __ _ ______ _ || _ / ____| / _|(_) | ____| | | || | | | | ___ _ __ | |_ _ __ _ | |__ __ __| |_ _ __ __ _ ___ | |_ ___ _ __ | | / _ \ | '_ \ | _|| | / _` | | __| \ \/ /| __|| '__|/ _` | / __|| __|/ _ \ | '__| | |____| (_) || | | || | | || (_| | | |____ > < | |_ | | | (_| || (__ | |_| (_) || | \_____|\___/ |_| |_||_| |_| \__, | |______|/_/\_\ \__||_| \__,_| \___| \__|\___/ |_| __/ | || ,odOO"bo, || ,dOOOP'dOOOb, || ,O3OP'dOO3OO33, || P",ad33O333O3Ob [] ?833O338333P",d `88383838P,d38' `Y8888P,d88P' `"?8,8P"' """ ) def main() -> None: lief.logging.disable() print_banner() args = parse_arguments() if args.file: configuration = extract_configuration(args.file) if not configuration: print("Failed to extract configuration from {}".format(args.file)) return display_results(args.file, configuration) if args.directory: for path, configuration in utils.map_files_directory( args.directory, extract_configuration ): if not configuration: print("Failed to extract configuration from {}".format(path)) continue display_results(path, configuration) if __name__ == "__main__": main()