Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def fire_context(self, **kwargs): #pylint:disable=arguments-differ
if self.target.run_command(["chmod","777",os.path.dirname(self.target.target_path)], user="root").wait() != 0:
raise ArchrError("failed to chmod CWD. core will *not* drop")
r = CoreResults()
r.target_core_path = os.path.join(os.path.dirname(self.target.target_path), "core")
r.local_core_path = tempfile.mktemp(prefix="arch_core_")
try:
with self.target.flight_context(result=r, **kwargs) as flight:
yield flight
finally:
with open(r.local_core_path, 'wb') as c:
c.write(self.target.retrieve_contents(r.target_core_path))
def fire(self, aslr=False, **kwargs): #pylint:disable=arguments-differ
if self.target.target_os == 'cgc':
return [], [], b'', {}
exit_code = 42
if not self.argv:
with self.target.shellcode_context(asm_code=self.sendfile_shellcode("/proc/self/cmdline") +
self.exit_shellcode(exit_code=exit_code),
aslr=aslr, **kwargs) as p:
arg_str, stderr = p.communicate()
if p.returncode != exit_code:
raise ArchrError("DataScout failed to get argv from the target process.\n"
"stdout: %s\nstderr: %s" % (arg_str, stderr))
self.argv = arg_str.split(b'\0')[:-1]
if not self.env:
with self.target.shellcode_context(asm_code=self.sendfile_shellcode("/proc/self/environ") +
self.exit_shellcode(exit_code=exit_code),
aslr=aslr, **kwargs) as p:
env_str, stderr = p.communicate()
if p.returncode != exit_code:
raise ArchrError("DataScout failed to get env from the target process.\n"
"stdout: %s\nstderr: %s" % (env_str, stderr))
self.env = env_str.split(b'\0')[:-1]
if not self.auxv:
with self.target.shellcode_context(asm_code=self.sendfile_shellcode("/proc/self/auxv") +
# did a crash occur?
if r.returncode in [ 139, -11 ]:
r.crashed = True
r.signal = signal.SIGSEGV
elif r.returncode == [ 132, -9 ]:
r.crashed = True
r.signal = signal.SIGILL
if local_core_filename:
target_cores = self.target.resolve_glob(os.path.join(tmpdir, "qemu_*.core"))
if len(target_cores) == 0:
raise ArchrError("the target didn't crash inside qemu! Make sure you launch it correctly!\n"+
"command: %s" % ' '.join(target_cmd))
elif len(target_cores) > 1:
raise ArchrError("expected 1 core file but found %d" % len(target_cores))
with self._local_mk_tmpdir() as local_tmpdir:
self.target.retrieve_into(target_cores[0], local_tmpdir)
cores = glob.glob(os.path.join(local_tmpdir, "qemu_*.core"))
shutil.move(cores[0], local_core_filename)
r.core_path = local_core_filename
if target_trace_filename:
trace = self.target.retrieve_contents(target_trace_filename)
trace_iter = iter(trace.splitlines())
# Find where qemu loaded the binary. Primarily for PIE
r.base_address = int(next(t.split()[1] for t in trace_iter if t.startswith(b"start_code")), 16) #pylint:disable=stop-iteration-return
# record the trace
_trace_re = _trace_old_re if self.target.target_os == 'cgc' else _trace_new_re
r.trace = [
def inject_tarball(self, target_path, tarball_path=None, tarball_contents=None):
if tarball_contents is None:
with open(tarball_path, "rb") as t:
tarball_contents = t.read()
p = self.run_command(["mkdir", "-p", target_path])
if p.wait() != 0:
raise ArchrError("Unexpected error when making target_path in container: " + p.stdout.read() + " " + p.stderr.read())
self.container.put_archive(target_path, tarball_contents)
if self.user != 'root':
# TODO: this is probably important, but as implemented (path resolves to /), it is way to slow. If someone wants this, implement it correctly.
p = self.run_command(["chown", "-R", f"{self.user}:{self.user}", '/tmp'], user="root", stderr=subprocess.DEVNULL)
p.wait()
pass
if lastline.startswith(b"Trace") or lastline.find(b"Segmentation") == -1:
l.warning("Trace return code was less than zero, but the last line of the trace does not"
"contain the uncaught exception error from qemu."
"If using an older version of shellphish_qemu try using 'ulimit -Sc 0' or "
"updating to a newer version of shellphish_qemu.")
r.crash_address = int(lastline.split(b'[')[1].split(b']')[0], 16)
l.debug("Trace consists of %d basic blocks", len(r.trace))
# remove the trace file on the target
self.target.remove_path(target_trace_filename)
if target_magic_filename:
r.magic_contents = self.target.retrieve_contents(target_magic_filename)
if len(r.magic_contents) != 0x1000:
raise ArchrError("Magic content read from QEMU improper size, should be a page in length")
# remove the magic file on the target
self.target.remove_path(target_magic_filename)
def _run_command(
self, args, env,
user=None, aslr=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
): #pylint:disable=arguments-differ
if self.container is None:
raise ArchrError("target.start() must be called before target.run_command()")
if not aslr:
args = ['setarch', 'x86_64', '-R'] + args
docker_args = [ "docker", "exec", "-i" ]
for e in env:
docker_args += [ "-e", e ]
if user:
docker_args += [ "-u", user ]
docker_args.append(self.container.id)
l.debug("running command: {}".format(docker_args + args))
return subprocess.Popen(
docker_args + args,
stdin=stdin, stdout=stdout, stderr=stderr, bufsize=0
#
# hardcode an argv[0]
#cmd_args += [ "-0", program_args[0] ]
# record trace
if trace_filename:
cmd_args += ["-d", "nochain,exec,page", "-D", trace_filename] if 'cgc' not in qemu_variant else ["-d", "exec", "-D", trace_filename]
else:
if 'cgc' in qemu_variant:
cmd_args += ["-enable_double_empty_exiting"]
# save CGC magic page
if magic_filename:
if 'cgc' not in qemu_variant:
raise ArchrError("Specified magic page dump on non-cgc architecture")
cmd_args += ["-magicdump", magic_filename]
if self.seed is not None:
cmd_args.append("-seed")
cmd_args.append(str(self.seed))
if report_bad_args:
cmd_args += ["-report_bad_args"]
# Memory limit option is only available in shellphish-qemu-cgc-*
if 'cgc' in qemu_variant:
cmd_args += ["-m", "8G"]
if 'cgc' not in qemu_variant and "LD_BIND_NOW=1" not in self.target.target_env:
l.warning("setting LD_BIND_NOW=1. This will have an effect on the environment.")
cmd_args += ['-E', 'LD_BIND_NOW=1']
def fire_context(self, save_core=False, record_magic=False, report_bad_args=False, rr_args=None, sleep_time=0.1):
if save_core or record_magic or report_bad_args:
raise ArchrError("I can't do any of these things!")
fix_perf()
if self.local_trace_dir:
if os.path.exists(self.local_trace_dir):
shutil.rmtree(self.local_trace_dir)
os.mkdir(self.local_trace_dir)
else:
self.local_trace_dir = tempfile.mkdtemp(prefix="/tmp/rr_tracer_")
with self._target_mk_tmpdir() as remote_tmpdir:
fire_path = os.path.join(self.target.tmpwd, "rr", "fire")
record_command = [fire_path, 'record', '-n']
if trraces:
record_command += trraces.rr_unsupported_cpuid_features.rr_cpuid_filter_cmd_line_args()
if rr_args: