├── .gitignore ├── .vscode └── settings.json ├── README.md ├── core ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-310.pyc │ ├── banner.cpython-310.pyc │ └── builder.cpython-310.pyc ├── banner.py └── builder.py ├── demo.py ├── main.py ├── output └── module.dwarf └── src ├── repository-list.json └── tool.zip.tar /.gitignore: -------------------------------------------------------------------------------- 1 | env/ 2 | *.pyc 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.analysis.typeCheckingMode": "off" 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # profile-builder 2 | 3 | 借鉴以下项目 4 | 5 | - [kevthehermit/volatility_symbols: Volatility Symbol Generator for Linux Kernels](https://github.com/kevthehermit/volatility_symbols) 6 | 7 | ## 目前仅为雏形,尚不能保证完美工作 8 | 9 | 现已支持以下发行版家族: 10 | 11 | - Ubuntu 12 | - Debian 13 | -------------------------------------------------------------------------------- /core/__init__.py: -------------------------------------------------------------------------------- 1 | from core.banner import banner_analyzer, deb_searcher 2 | from core.builder import Core_Builder 3 | -------------------------------------------------------------------------------- /core/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CTF-Archives/profile-builder/1c6ffedff78c40cb76d97bf934087599d5564c63/core/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /core/__pycache__/banner.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CTF-Archives/profile-builder/1c6ffedff78c40cb76d97bf934087599d5564c63/core/__pycache__/banner.cpython-310.pyc -------------------------------------------------------------------------------- /core/__pycache__/builder.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CTF-Archives/profile-builder/1c6ffedff78c40cb76d97bf934087599d5564c63/core/__pycache__/builder.cpython-310.pyc -------------------------------------------------------------------------------- /core/banner.py: -------------------------------------------------------------------------------- 1 | import json 2 | import requests 3 | import string 4 | 5 | key_release = ["ubuntu", "debian"] 6 | with open("./src/repository-list.json", "r") as f: 7 | key_repository = json.loads(f.read()) 8 | 9 | 10 | def banner_analyzer(banner: str): 11 | banner_release = [i for i in key_release if i in banner][0] 12 | banner_kernel = [i for i in banner.replace("(", " ").replace(")", " ").split(" ") if i != ""][2] 13 | 14 | return banner_release, banner_kernel 15 | 16 | 17 | def deb_searcher(banner_release: str, banner_kernel: str): 18 | repository_url = key_repository[banner_release] 19 | repository_debs = requests.get(repository_url).text 20 | repository_debs = [i.split('"')[1] for i in [i for i in repository_debs.split("\n")[4:-3] if i != ""]] 21 | repository_debs_need = [ 22 | i 23 | for i in repository_debs 24 | if ("linux-modules-" + banner_kernel in i) 25 | or ("linux-image" in i and banner_kernel in i) 26 | or ("linux-headers-" + banner_kernel[::-1].split("-", 1)[1][::-1] in i) 27 | ] 28 | return repository_debs_need 29 | 30 | 31 | if __name__ == "__main__": 32 | ins = "Linux version 6.2.0-35-generic (buildd@bos03-amd64-016) (x86_64-linux-gnu-gcc-11 (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC (Ubuntu 6.2.0-35.35~22.04.1-generic 6.2.16)" 33 | banner_release, banner_kernel = banner_analyzer(ins) 34 | deb_url = deb_searcher(banner_release, banner_kernel) 35 | deb_url.sort() 36 | print(deb_url[::-1]) 37 | -------------------------------------------------------------------------------- /core/builder.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import docker 4 | import logging 5 | import tarfile 6 | import zipfile 7 | import io 8 | from core.banner import deb_searcher 9 | 10 | with open("./src/repository-list.json", "r") as f: 11 | key_repository = json.loads(f.read()) 12 | 13 | 14 | class Core_Builder: 15 | def __init__(self, banner_release: str, banner_kernel: str) -> None: 16 | # 默认使用本地docker服务 17 | self.client = docker.DockerClient(base_url="unix:///var/run/docker.sock") 18 | self.banner_release = banner_release 19 | self.banner_kernel = banner_kernel 20 | self.output_folder = os.path.join(os.getcwd(), "output") 21 | if not os.path.exists(self.output_folder): 22 | os.makedirs(self.output_folder) 23 | 24 | def container_start(self): 25 | container_params = { 26 | "image": "ubuntu:latest", # 替换为你想要启动的Docker镜像的名称和标签 27 | "command": "sleep infinity", # 替换为要在容器内运行的命令 28 | "detach": True, # 设置为True以在后台运行容器 29 | "name": "profile-builder-{release}-{kernel}".format(release=self.banner_release, kernel=self.banner_kernel), 30 | } 31 | self.container_name = container_params["name"] 32 | 33 | # 启动容器 34 | self.container = self.client.containers.run(**container_params) 35 | 36 | def container_change_repository(self): 37 | if self.banner_release == "ubuntu": 38 | logging.info("[+] {}".format("sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list")) 39 | self.container.exec_run("sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list") 40 | logging.info("[+] {}".format("sed -i 's@//.*security.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list")) 41 | self.container.exec_run("sed -i 's@//.*security.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list") 42 | exec_result = self.container.exec_run("apt-get update") 43 | logging.debug(exec_result.output.decode("utf-8").strip()) 44 | 45 | def container_install_dependency(self): 46 | dependency_ubuntu = ["wget", "unzip", "dwarfdump", "build-essential", "kmod", "linux-base", "gcc-10", "gcc-11", "gcc-12"] 47 | if self.banner_release == "ubuntu": 48 | logging.info("[+] {}".format("apt-get install -y " + " ".join(dependency_ubuntu))) 49 | exec_result = self.container.exec_run("apt-get install -y " + " ".join(dependency_ubuntu)) 50 | logging.debug(exec_result.output.decode("utf-8").strip()) 51 | 52 | def container_install_debs(self): 53 | repository_url = key_repository[self.banner_release] 54 | self.container.exec_run("mkdir /src") 55 | debs = deb_searcher(self.banner_release, self.banner_kernel) 56 | debs.sort() 57 | for deb in debs: 58 | logging.info("[+] {}".format("wget " + repository_url + deb)) 59 | exec_result = self.container.exec_run("wget " + repository_url + deb + " -P /src/") 60 | logging.debug(exec_result.output.decode("utf-8").strip()) 61 | 62 | for i in [_ for _ in debs if _.startswith("linux-modules")]: 63 | logging.info("dpkg -i /src/{}".format(i)) 64 | exec_result = self.container.exec_run("dpkg -i /src/{}".format(i)) 65 | logging.debug(exec_result.output.decode("utf-8").strip()) 66 | 67 | for i in [_ for _ in debs if _.startswith("linux-headers")][::-1]: 68 | logging.info("dpkg -i /src/{}".format(i)) 69 | exec_result = self.container.exec_run("dpkg -i /src/{}".format(i)) 70 | logging.debug(exec_result.output.decode("utf-8").strip()) 71 | 72 | for i in [_ for _ in debs if _.startswith("linux-image")]: 73 | logging.info("dpkg -i /src/{}".format(i)) 74 | exec_result = self.container.exec_run("dpkg -i /src/{}".format(i)) 75 | logging.debug(exec_result.output.decode("utf-8").strip()) 76 | 77 | def container_build_dwarf(self): 78 | self.container.exec_run("mkdir /src") 79 | path_tool = "tool.zip.tar" 80 | path_dest = "/src/tool.zip" 81 | path_current = os.getcwd() 82 | with open(path_current + "/src/" + path_tool, "rb") as f: 83 | self.container.put_archive(os.path.dirname(path_dest), f.read()) 84 | 85 | exec_result = self.container.exec_run('bash -c "cd /src;unzip tool.zip"') 86 | logging.debug(exec_result.output.decode("utf-8").strip()) 87 | self.container.exec_run("sed -i 's/$(shell uname -r)/{}/g' /src/linux/Makefile".format(self.banner_kernel)) 88 | self.container.exec_run('bash -c "echo TU9EVUxFX0xJQ0VOU0UoIkdQTCIpOw== | base64 -d >> /src/linux/module.c"') 89 | exec_result = self.container.exec_run('bash -c "cd /src/linux;make"') 90 | logging.debug(exec_result.output.decode("utf-8").strip()) 91 | 92 | 93 | def extract_and_write_file(self, source_path, target_path): 94 | bits, _ = self.container.get_archive(source_path) 95 | 96 | file_like_object = io.BytesIO() 97 | for chunk in bits: 98 | file_like_object.write(chunk) 99 | file_like_object.seek(0) 100 | 101 | with tarfile.open(fileobj=file_like_object, mode='r:*') as tar: 102 | member = tar.next() 103 | 104 | if member is not None: 105 | file_data = tar.extractfile(member).read() 106 | with open(target_path, 'wb') as f: 107 | f.write(file_data) 108 | 109 | 110 | def extract_dwarf(self): 111 | self.extract_and_write_file(source_path="/src/linux/module.dwarf", 112 | target_path=self.output_folder + "/module.dwarf") 113 | 114 | def extract_System_map(self): 115 | system_map_path = f"/boot/System.map-{self.banner_kernel}" 116 | system_map_filename = os.path.basename(system_map_path) 117 | 118 | self.extract_and_write_file(system_map_path, os.path.join(self.output_folder, system_map_filename)) 119 | 120 | 121 | def Zip_profile(self): 122 | dwarf_path = os.path.join(self.output_folder, "module.dwarf") 123 | system_map_path = os.path.join(self.output_folder, f"System.map-{self.banner_kernel}") 124 | zip_filename = os.path.join(self.output_folder, f"{self.banner_release}_{self.banner_kernel}.zip") 125 | 126 | with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf: 127 | zipf.write(dwarf_path, arcname='module.dwarf') 128 | zipf.write(system_map_path, arcname=f"System.map-{self.banner_kernel}") 129 | 130 | def container_clean(self): 131 | self.container.stop() 132 | self.container.remove() 133 | 134 | def run(self): 135 | logging.info("### Container starting") 136 | self.container_start() 137 | logging.info("### Change to mirror repository") 138 | self.container_change_repository() 139 | logging.info("### Install dependency") 140 | self.container_install_dependency() 141 | logging.info("### Download needful debs") 142 | self.container_install_debs() 143 | logging.info("### Build dwarf") 144 | self.container_build_dwarf() 145 | logging.info("### Extract dwarf file") 146 | self.extract_dwarf() 147 | logging.info("### Extract System.map file") 148 | self.extract_System_map() 149 | logging.info("### Zip profile") 150 | self.Zip_profile() 151 | logging.info("### Clean Container") 152 | self.container_clean() 153 | -------------------------------------------------------------------------------- /demo.py: -------------------------------------------------------------------------------- 1 | import docker 2 | import os 3 | import tarfile 4 | 5 | # 创建 Docker 客户端 6 | client = docker.from_env() 7 | 8 | container_params = { 9 | "image": "ubuntu:latest", # 替换为你想要启动的Docker镜像的名称和标签 10 | "command": "sleep infinity", # 替换为要在容器内运行的命令 11 | "detach": True, # 设置为True以在后台运行容器 12 | } 13 | 14 | # 创建容器并启动 15 | container = client.containers.run(**container_params) 16 | container.exec_run("mkdir /src") 17 | 18 | container_dir = "/src/data.txt" 19 | src="./data.txt" 20 | print(os.getcwd()) 21 | os.chdir(os.path.dirname(src)) 22 | srcname = os.path.basename(src) 23 | print(src + '.tar') 24 | tar = tarfile.open(src + '.tar', mode='w') 25 | try: 26 | tar.add(srcname) 27 | finally: 28 | tar.close() 29 | 30 | data = open(src + '.tar', 'rb').read() 31 | container.put_archive(os.path.dirname(container_dir), data) 32 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from core import * 2 | import logging 3 | 4 | logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") 5 | 6 | if __name__ == "__main__": 7 | banner_release, banner_kernel = banner_analyzer(input("input:")) 8 | print("banner_release: {}\nbanner_kernel: {}".format(banner_release, banner_kernel)) 9 | builder = Core_Builder(banner_release, banner_kernel) 10 | builder.run() 11 | -------------------------------------------------------------------------------- /src/repository-list.json: -------------------------------------------------------------------------------- 1 | { 2 | "ubuntu": "https://mirrors.ustc.edu.cn/ubuntu/pool/main/l/linux/", 3 | "debian": "https://mirrors.ustc.edu.cn/debian/pool/main/l/linux/" 4 | } -------------------------------------------------------------------------------- /src/tool.zip.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CTF-Archives/profile-builder/1c6ffedff78c40cb76d97bf934087599d5564c63/src/tool.zip.tar --------------------------------------------------------------------------------