def handleconstraint(self, args, path, vmlinux): print("parsing file %s" % path) if vmlinux is None: print("Require vmlinux") return kernel = Kernel(vmlinux) with open(path) as f: start = False dist = dict() for line in f: if "constraints for symbolic memory index" in line: start = True if "constraints for loops" in line: break if start: m = re.search('(0x[0-9a-f]+): (0x[0-9a-f])', line) if m: pc = int(m.group(1), 16) num = int(m.group(2), 16) dist[pc] = num dist_func = dict() for pc, num in dist.items(): sym = kernel.find_symbol(pc) if sym: if sym.name in dist_func: dist_func[sym.name] += num else: dist_func[sym.name] = num total = 0 sorted_list = sorted(dist_func.items(), key=lambda x: x[1]) for name, num in sorted_list: total += num print("%s: %d" % (name, num)) print("total: %d" % total)
def Instrumentor(self, args): if args.source is None: raise ValueError("no source project provided") kernel = Kernel(args.image) source_cfg = self.loads( os.path.join(self.project_path(args.source), "project.json")) cfg = dict() cfg['workdir'] = self.getConfig("workdir") # cfg['sourcedir'] = self.project_path(args.source) cfg['logLevel'] = "debug" cfg['check_kasan'] = True vuln = self.loads(self.workdir_file("vuln.json")) if vuln['Symbolic']: cfg['vul_size'] = 0 else: cfg['vul_size'] = Pahole.getSize(vuln['Size']) cfg['allocSite'] = vuln['Callsite'] cfg['kasan'], cfg['kasan_ret'] = kernel.getKasanReport() cfg['repro'] = False cfg['ranges'] = [] content = "add_plugin(\"Instrumentor\")\n" content += "pluginsConfig.Instrumentor = %s" % lua.encode(cfg) return content
def handlereport(self, path, vmlinux=None): print("parsing file %s" % path) kernel = None if vmlinux: kernel = Kernel(vmlinux) with open(path) as f: for line in f: if "[KASAN]" in line: item = KernelObject("[KASAN]", line) print(str(item)) if kernel is None: continue if "ip" in item: for addr in item.ip: print(kernel.resolve_addr(addr))
def find_sites(self, project, vmlinux, workdir, timeout, threaded=False): if not os.path.isfile(os.path.join(workdir, "vuln.json")): logger.error("no vuln.json found, please run with --findVuln first") return False logger.debug("Phase 2: locate all the vulnerability sites...") extra_process = [] count = runCommand.MAXIMUM_TIMES if threaded else 1 while count > 0: cmds = ["python", "main.py", "genconf", "-p", project, "-i", vmlinux, "-e", "-m", "2"] if len(extra_process) > 0: cmds += ["--pids", ",".join(extra_process)] logger.debug("Patch the config: %s" % " ".join(cmds)) run(cmds, check=True) tmpfile = os.path.join(workdir, "tmp") # continue to execute even if timeout is raised ret = self.launch_s2e(tmpfile, timeout=timeout) if ret != 0 and ret != RET_TIMEOUT: return False pid = self.findProcess(tmpfile) if pid is not None: if pid not in extra_process: extra_process.append(pid) continue kernel = Kernel(vmlinux) reports = find_vulnerablility_sites(tmpfile, kernel, os.path.join(workdir, "reports.json")) if len(reports) == 0: logger.error("failed to find any sites") count -= 1 continue logger.debug("find vulnerability sites: %s" % str(reports)) return True return False
def exploit(self, args): content = self.loadconfig("s2e-config.lua") to_be_removed = [ "ExecutionTracer", "ModuleTracer", "TranslationBlockCoverage", "StaticFunctionModels", "LuaCoreEvents", "MultiSearcher", "CUPASearcher", "TestCaseGenerator" ] content = self.remove_plugins(content, to_be_removed) content = self.patch_plugins(content) kernel = Kernel(args.image) content += '\n\n' content += self.OptionPlugin(args) content += self.Disassembler() content += self.ProgramMonitor() content += self.PcMonitor(args, kernel) content += self.KernelAddressSanitizer(kernel) if args.mode == 4: # TODO: copy cap file path = self.workdir_file("layout.json") if not os.path.exists(path): layout = findLayoutSyscall( self.last_execution_file('debug.txt'), self.work_file("layout.json")) if args.mode != 1 and not args.nosymalloc: # try to parse the log file and extract information of the vul object vuln_path = self.workdir_file("vuln.json") if os.path.exists(vuln_path): content += self.AllocManager(args, kernel, KernelObject.load(vuln_path)) else: path = self.last_execution_file('debug.txt') item = find_vulnerable_object(path, vuln_path) content += self.AllocManager(args, kernel, item) else: content += self.AllocManager(args, kernel) content += self.KernelFunctionModels(args, kernel) if args.exploit: content += self.KernelInstructionTracer(kernel, args) else: content += self.ObjectAnalyzer(kernel) content += self.addfunction(args) content += ('dofile(\'candidates.lua\')\n') if args.verbose: print(content) exit(1) self.patch_candidate() self.saveconfig(content, "s2e-config.lua") self.patch_bootstrap(args)
def run(self, args): num = 0 if not args.skip else args.skip kernel = Kernel(args.image) if args.sweep: print(args.line, type(args.line)) self.sweeptrace(kernel, args.file, depth=args.depth, start=args.entry, end=args.exit, num=args.line, skip=num) else: self.trace(kernel, args.file, depth=args.depth, start=args.entry, skip=num)
def run(self, args): kernel = Kernel(args.image) self.shrink(kernel, args.file, args.entry)