Esempio n. 1
0
    def init(self, **kwargs):
        from pandare import Panda

        arch = self.avatar.arch.qemu_name
        args = self.assemble_cmd_line()[1:]

        self.avatar.save_config(file_name=self.qemu_config_file,
                                config=self.generate_qemu_config())

        self.pypanda = Panda(arch=arch, extra_args=args, **kwargs)

        # adjust panda's signal handler to avatar2-standard
        def SigHandler(SIG, a, b):
            if self.state == TargetStates.RUNNING:
                self.stop()
                self.wait()

            self.avatar.sigint_handler()

        self.pypanda._setup_internal_signal_handler(signal_handler=SigHandler)

        self._thread = Thread(target=self.pypanda.run, daemon=True)
        self._thread.start()

        self._connect_protocols()
Esempio n. 2
0
It then replays the recording and uses virt mem callbacks to find strings 
written into memory.

Run with: python3 extract_memstrings.py
'''


from sys import argv
from string import ascii_letters
from os import remove, path
from pandare import Panda

# Single arg of arch, defaults to i386
arch = "i386" if len(argv) <= 1 else argv[1]
panda = Panda(generic=arch)

# Make sure we're always saving a new recording
recording_name = "mem_test.recording"
for f in [recording_name+"-rr-nondet.log", recording_name+"-rr-snp"]:
    if path.isfile(f): remove(f)

@panda.queue_blocking
def my_record_cmd(): # Run a non-deterministic command at the root snapshot, then end .run()
    panda.record_cmd("wget google.com", recording_name=recording_name)
    panda.stop_run()

print("Take recording...")
panda.run()

print("Analyze replay...")
Esempio n. 3
0
#!/usr/bin/env python3

# Demonstartion of using PANDA to run shellcode. Example modified from Unicorn Engine
# https://github.com/unicorn-engine/unicorn/blob/master/bindings/python/sample_arm.py

import capstone
import os

from pandare import Panda

X86_CODE   = b"\x40\x01\xC3\x41" # inc eax; add ebx, eax; inc ecx;
ADDRESS = 0x1000
stop_addr = ADDRESS + len(X86_CODE)

# Create a machine of type 'configurable' but with just a CPU specified (no peripherals or memory maps)
panda = Panda("i386", extra_args=["-M", "configurable", "-nographic"])

@panda.cb_after_machine_init
def setup(cpu):
    '''
    After our CPU has been created, allocate memory and set starting state
    '''
    # map 2MB memory for this emulation
    panda.map_memory("mymem", 2 * 1024 * 1024, ADDRESS)

    # Write code into memory
    panda.physical_memory_write(ADDRESS, X86_CODE)

    # Set up registers
    panda.arch.set_reg(cpu, "EAX", 0x1)
    panda.arch.set_reg(cpu, "EBX", 0x2)
Esempio n. 4
0
#!/usr/bin/env python3
# Take a recording, then replay and analyze
from os import remove, path
from pandare import Panda, blocking

arch = "i386"
panda = Panda(generic=arch)

# Make sure we're always saving a new recording
recording_name = "test.recording"
for f in [recording_name + "-rr-nondet.log", recording_name + "-rr-snp"]:
    if path.isfile(f): remove(f)


@blocking
def record_nondet(
):  # Run a non-deterministic command at the root snapshot, then end .run()
    panda.record_cmd("date; cat /dev/urandom | head -n1 | md5sum",
                     recording_name=recording_name)
    panda.stop_run()


# Collect BBs during both recording and then replay validate that our replay is good
in_replay = False
orig_blocks = set()
replay_blocks = set()


@panda.cb_before_block_exec()
def before_block_exec(env, tb):
    # At each BB's execution in 'find', ensure translation is cached and add to executed_pcs
Esempio n. 5
0
                print("Saw PASSWD - switch modes")
                self.set_mode("mode2")

        @self.panda.ppp("syscalls2", "on_sys_open_enter")
        @self.mode_filter("mode2")
        def on_open2(cpu, pc, fname_ptr, flags, mode):
            assert self.mode == "mode2"

            try:
                fname = self.panda.read_str(cpu, fname_ptr)
            except ValueError:
                return

            if fname == "/proc/cpuinfo":
                print("SAW CPUINFO - switch modes")
                self.set_mode("end")

        # End PANDA-decorated functions in init

    def run_guest(self):
        '''
        Run guest
        '''
        self.panda.run()


if __name__ == "__main__":
    panda = Panda(generic="i386")
    test = Tester(panda)
    test.run_guest()
Esempio n. 6
0
#!/usr/bin/env python3
from pandare import Panda, blocking, ffi

panda = Panda(generic="x86_64")

panda.load_plugin("syscalls2")
panda.load_plugin("osi")

@panda.ppp("syscalls2", "on_sys_read_return")
def on_sys_read_return(cpu, pc, fd, buf, count):
    proc = panda.plugins['osi'].get_current_process(cpu)
    procname = ffi.string(proc.name) if proc != ffi.NULL else "error"
    fname_ptr = panda.plugins['osi_linux'].osi_linux_fd_to_filename(cpu, proc, fd)
    fname = ffi.string(fname_ptr) if fname_ptr != ffi.NULL else "error"
    rc = panda.plugins['syscalls2'].get_syscall_retval(cpu)
    print(f"[PANDA] {procname} read {rc} bytes from {fname}")

@panda.ppp("syscalls2", "on_sys_execve_enter")
def on_sys_execve_enter(cpu, pc, fname_ptr, argv_ptr, envp):
    # Log commands and arguments passed to execve unless in kernel
    if panda.in_kernel(cpu):
        return
    try:
        fname = panda.read_str(cpu, fname_ptr)
        argv_ptrlist = panda.virtual_memory_read(cpu, argv_ptr, 100, fmt='ptrlist')
    except ValueError: return
    argv = []
    for ptr in argv_ptrlist:
        if ptr == 0: break
        try:
            argv.append(panda.read_str(cpu, ptr))
Esempio n. 7
0
import capstone
import angr
import claripy
import struct
import logging

from pandare import Panda, blocking
from io import BytesIO
from ipdb import set_trace as d

logging.basicConfig(
    format='%(levelname)-7s | %(asctime)-23s | %(name)-8s | %(message)s')
logger = logging.getLogger('angrypanda')
logger.setLevel('DEBUG')

panda = Panda(generic="i386")

md = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_32)
buffer_addr = None  # Dynamically identified, address of buffer returned from malloc
found_input = None  # Dynamically computed during first run

# Settings - It would be better do do these using line numbers but good enough for this PoC
BUFFER_SET = 0x8048557  # After malloc (add esp, 0x10)
START_ANGR = 0x804859e  # After printf buffer contains (add esp, 0x10)
FIND_ADDR = 0x80485e5  # Before print success (push eax=>s_success)
AVOID = 0x80485f9  # Before print failure (push eax=>failure)
END_MAIN = 0x8048611  # Main's ret (ret)


def angr_insn_exec(state):
    """
Esempio n. 8
0
# particular pc (0xc101dfec) which we only knew about bc we ran qemu -d
# in_asm before.  At this pc we take a snapshot.  This callback actually
# contains a little state machine.  After we have taken the snapshot, we
# are in state 3, where we increment a counter with each call, i.e. for
# each new basic block we execute.  After 10 blocks, we revert to the
# snapshot at 0xc101dfec.
#
# Obviously there are more interesting uses for this kind of thing.  Two
# important things to notice.  First, we can take a snapshot that will
# in fact revert to a specific block's start pc.  Second, when we
# revert, we don't keep executing any code.  We snap back to exactly
# that bloc.

# Single arg of arch, defaults to i386
arch = "i386" if len(argv) <= 1 else argv[1]
panda = Panda(generic=arch)

state = 0 # before snapshot load

@blocking
def init():
    global state
    panda.delvm_sync("newroot")
    panda.revert_sync("root")
    state = 1

nt = 0
blocks = []

@panda.cb_before_block_exec()
def before_block_exec(env,tb):
Esempio n. 9
0
j .end
nop

.end:
addiu $t1, 1  # t1++
"""

ks = keystone.Ks(keystone.KS_ARCH_MIPS, keystone.KS_MODE_MIPS32)
#ks = keystone.Ks(keystone.KS_ARCH_MIPS, keystone.KS_MODE_MIPS32 + KS_MODE_BIG_ENDIAN)

ADDRESS = 0x1000
encoding, count = ks.asm(CODE, ADDRESS)
stop_addr = ADDRESS + len(encoding)

panda = Panda("mipsel",
              extra_args=["-M", "configurable", "-nographic"],
              raw_monitor=True)


@panda.cb_after_machine_init
def setup(cpu):
    '''
    After our CPU has been created, allocate memory and set starting state
    '''
    # map 2MB memory for this emulation
    panda.map_memory("mymem", 2 * 1024 * 1024, ADDRESS)

    # Write code into memory
    panda.physical_memory_write(ADDRESS, bytes(encoding))

    # Set up registers
Esempio n. 10
0
#!/usr/bin/env python3

from sys import argv
from pandare import Panda, blocking

# Record some programs running in the guest
# for some programs, register python callbacks

# Single arg of arch, defaults to i386
arch = "i386" if len(argv) <= 1 else argv[1]
panda = Panda(generic=arch)

# Python plugin- collect a set of unique basic blocks seen
seen_bbs = set()
@panda.cb_before_block_exec(enabled=False)
def bbe(env, tb):
    pc = panda.current_pc(env)
    global seen_bbs
    seen_bbs.add(pc)

# Run ls with c plugin loaded
@blocking
def record_ls():
    print("Recording run of `ls` with C callback")

    # Load c plugin
    panda.require("coverage")
    panda.record_cmd("ls /", recording_name="ls")
    panda.unload_plugin("coverage")
    panda.stop_run() # Return control flow
Esempio n. 11
0
#!/usr/bin/env python3

from sys import argv
from pandare import Panda

# Record some programs running in the guest
# for some programs, register python callbacks

# Single arg of arch, defaults to i386
arch = "x86_64" if len(argv) <= 1 else argv[1]
extra = "-nographic -chardev socket,id=monitor,path=./monitor.sock,server,nowait -monitor chardev:monitor -serial telnet:127.0.0.1:4444,server,nowait  -device e1000,netdev=net0 -netdev user,id=net0,hostfwd=tcp::5555-:22 -cdrom /home/luke/workspace/qcows/instance-1-cidata.iso"
qcow = "/home/luke/workspace/qcows/instance-1.qcow2"
panda = Panda(arch=arch,qcow=qcow,extra_args=extra,mem="1G")
panda.set_os_name("linux-64-ubuntu")

panda.require("syscalls2")
cb_name = "on_sys_read_return"
cb_args = "CPUState *, target_ulong, uint32_t, uint64_t, uint32_t"
ffi.cdef(f"void ppp_add_cb_{cb_name}(void (*)({cb_args}));")

@ffi.callback(f"void({cb_args})")
def on_sys_read_return(cpustate, pc, fd, buf, count):
	vmlinux = panda.get_volatility_symbols()
	import pdb
	pdb.set_trace()

panda.plugins["syscalls2"].__getattr__(f"ppp_add_cb_{cb_name}")(on_sys_read_return)

cb_name = "on_sys_read_enter"
cb_args = "CPUState *, target_ulong, uint32_t, uint64_t, uint32_t"
ffi.cdef(f"void ppp_add_cb_{cb_name}(void (*)({cb_args}));")
Esempio n. 12
0
#!/usr/bin/env python3
# Take a recording, then replay with analysis, then revert vm and run more commands
from sys import argv
from os import remove, path
from pandare import Panda, blocking

# Default arch is i386, but others can be used
arch = argv[1] if len(argv) > 1 else "i386"
panda = Panda(generic=arch)

# Make sure we're always saving a new recording
recording_name = "test.recording"
for f in [recording_name + "-rr-nondet.log", recording_name + "-rr-snp"]:
    if path.isfile(f): remove(f)

successes = [False, False]


####################### Recording ####################
@blocking
def record_nondet(
):  # Run a non-deterministic command at the root snapshot, then end .run()
    panda.record_cmd("date; cat /dev/urandom | head -n30 | md5sum",
                     recording_name=recording_name)
    global successes
    successes[0] = True
    panda.stop_run()


# Collect BBs during both recording and then replay validate that our replay is good
in_replay = False
Esempio n. 13
0
from pandare import Panda
from os import remove, path
from sys import argv

# Default arch is i386, but others can be used
arch = argv[1] if len(argv) > 1 else "i386"
panda = Panda(generic=arch)

# Make sure we're always saving a new recording
recording_name = f"filetaint-{arch}.recording"
for f in [recording_name+"-rr-nondet.log", recording_name+"-rr-snp"]:
    if path.isfile(f): remove(f)

success = False

@panda.queue_blocking
def driver():
    panda.record_cmd("cat /etc/passwd | wc -l", recording_name=recording_name)
    panda.end_analysis()

panda.run() # take recording

@panda.ppp("taint2", "on_taint_change")
def taint_change(*args):
    global success
    success = True
    panda.end_analysis()

panda.load_plugin("file_taint", {"filename": "/etc/passwd"})
panda.run_replay(recording_name)
Esempio n. 14
0
matches we taint the resulting data.

Lastly, we use syscalls2 to monitor sys_sendto for network traffic.
We must check each byte in the packet to check if it is tainted and
we alert if it is tainted.
'''

from sys import argv
from os import path
from pandare import Panda, blocking, ffi

arch = "x86_64" if len(argv) <= 1 else argv[1]
extra = "-nographic"
#qcow = "/home/luke/workspace/qcows/instance-1.qcow2"
#panda = Panda(arch=arch, qcow=qcow, extra_args=extra, mem="1G")
panda = Panda(generic=arch)

interesting_file_name = b"panda.panda2"

panda.set_os_name("linux-64-ubuntu")
panda.load_plugin("callstack_instr", args={"stack_type": "asid"})
panda.require("syscalls2")

cb_name = "on_sys_read_return"
cb_args = "CPUState *, target_ulong, uint32_t, uint64_t, uint32_t"
ffi.cdef(f"void ppp_add_cb_{cb_name}(void (*)({cb_args}));")

file_info = None


@ffi.callback(f"void({cb_args})")
Esempio n. 15
0
#!/usr/bin/env python3
# Take a recording, then replay with analysis, then revert vm and run more commands
from sys import argv
from os import remove, path
from pandare import Panda

# Default arch is i386, but others can be used
arch = argv[1] if len(argv) > 1 else "i386"
panda = Panda(generic=arch)

# Make sure we're always saving a new recording
recording_name = "test.recording"
for f in [recording_name+"-rr-nondet.log", recording_name+"-rr-snp"]:
    if path.isfile(f): remove(f)

successes = [False, False]

####################### Recording ####################
@panda.queue_blocking
def record_nondet(): # Run a non-deterministic command at the root snapshot, then end .run()
    panda.record_cmd("date; cat /dev/urandom | head -n30 | md5sum", recording_name=recording_name)
    global successes
    successes[0] = True
    panda.stop_run()

# Collect BBs during both recording and then replay validate that our replay is good
in_replay = False
orig_blocks = set()
replay_blocks = set()
@panda.cb_before_block_exec()
def before_block_exec(env, tb):
Esempio n. 16
0
#!/usr/bin/env python3

from sys import argv
from os import path, remove
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection
from pandare import Panda

# Single arg of arch, defaults to i386
arch = "i386_wheezy" if len(argv) <= 1 else argv[1]
panda = Panda(generic=arch)

bin_dir = "taint"
bin_name = "taint"

assert (path.isfile(path.join(bin_dir, bin_name))), "Missing file {}".format(
    path.join(bin_dir, bin_name))
# Take a recording of toy running in the guest if necessary
recording_name = bin_dir + "_" + bin_name

# Debug - delete recording each time
if path.isfile(recording_name + "-rr-snp"):
    remove(recording_name + "-rr-snp")
    remove(recording_name + "-rr-nondet.log")

if not path.isfile(recording_name + "-rr-snp"):

    @panda.queue_blocking
    def run_it():
        panda.record_cmd(f"./taint/taint",
                         copy_directory=bin_dir,
Esempio n. 17
0
        Retrieve ioctl that completed normally
        '''

        return self._get_returns(self._unmodified_returns, with_buf_only)


if __name__ == "__main__":
    '''
    Bash will issue ioctls on /dev/ttys0 - this is just a simple test to make sure they're being captured
    '''

    from pandare import blocking, Panda

    # No arguments, i386. Otherwise argument should be guest arch
    generic_type = sys.argv[1] if len(sys.argv) > 1 else "i386"
    panda = Panda(generic=generic_type)

    def print_list_elems(l):

        if not l:
            print("None")
        else:
            for e in l:
                print(e)

    @blocking
    def run_cmd():

        # Setup faker
        ioctl_faker = IoctlFaker(panda, use_osi_linux=True)
Esempio n. 18
0
'''
volatility pslist two ways.
By: Luke Craig
'''

from pandare import Panda, blocking
from sys import argv
from time import time
from volatility.framework.objects import utility

arch = "x86_64" if len(argv) <= 1 else argv[1]
extra = "-nographic -chardev socket,id=monitor,path=./monitor.sock,server,nowait -monitor chardev:monitor -serial telnet:127.0.0.1:4444,server,nowait"
qcow = "/home/luke/workspace/qcows/instance-1.qcow2"
panda = Panda(arch=arch, qcow=qcow, extra_args=extra, mem="1G")

timechange = 5
oldtime, oldtime2 = time(), time()
'''
In on_asid_change we use the fast method. It gives us back the volatility symbols
and we "become" the volatility plugin. The reason this is fast is because we clear
the cache between runs so we don't have to reconstruct the whole plugin again. This
way we only have to run the 10+ second startup once.
'''


@panda.cb_asid_changed()
def on_asid_change(env, old_asid, new_asid):
    global oldtime
    if time() - oldtime > timechange:
        vmlinux = panda.get_volatility_symbols(debug=True)
        init_task = vmlinux.object_from_symbol(symbol_name="init_task")
Esempio n. 19
0
#!/usr/bin/env python3

from pandare import Panda
panda = Panda(generic='x86_64')


@panda.queue_blocking
def driver():
    '''
    Asynchronous function that drives guest behavior after PANDA starts

    Load a snapshot where we're logged in, then copy the contents
    of ./copy into the guest, ensure ls is executable, then load the trace
    plugin and run ls. When ls completes, end the analysis
    '''
    panda.revert_sync("root")  # Revert to snapshot
    panda.copy_to_guest("copy")  # Copy directory into guest
    print(panda.run_serial_cmd("chmod +x ./copy/ls"))  # Ensure executable
    panda.load_plugin("trace", {
        'log': f'example_trace.txt',
        'target': 'ls'
    })  # Trace program named ls
    print(panda.run_serial_cmd("./copy/ls"))  # Run ls

    panda.end_analysis()  # We're finished here


@panda.ppp("proc_start_linux", "on_rec_auxv")
def proc_start(cpu, tb, auxv):
    procname = panda.ffi.string(auxv.argv[0]).decode(
        errors='ignore') if auxv.argv[0] != panda.ffi.NULL else "(error)"
Esempio n. 20
0
        # Close all open hfds
        if len(self.hooked_fds):
            self.ff_logger.debug("Cleaning up open hyper file descriptors")
            for (fd, asid) in list(self.hooked_fds.keys()):
                self.hooked_fds[(fd, asid)].close()
                del self.hooked_fds[(fd, asid)]

    def __del__(self):
        # XXX: This isn't being called for some reason on destruction
        self.close()


if __name__ == '__main__':
    from pandare import Panda

    panda = Panda(generic="x86_64")

    # Replace all syscalls that reference /foo with a custom string
    fake_str = "Hello world. This is data generated from python!"
    faker = FileFaker(panda)
    faker.replace_file("/foo", FakeFile(fake_str))

    @panda.queue_blocking
    def driver():
        new_str = "This is some new data"

        panda.revert_sync('root')
        data = panda.run_serial_cmd(
            "cat /foo"
        )  # note run_serial_cmd must end with a blank line and our fake file doesn't
        assert (fake_str in data), f"Failed to read fake file /foo: {data}"
Esempio n. 21
0
def runner(generic_name):
    '''
    Try to run a single generic image
    First run via CLI - load root snapshot, run a command and quit - check command output
    Then test via python to see if OSI works
    '''
    from pandare import Panda
    data = SUPPORTED_IMAGES[generic_name]
    qcow_path = Qcows.get_qcow(generic_name)

    # Check 1 - can we load with CLI
    assert(os.path.isfile(qcow_path)), f"Can't find qcow for {generic_name}"
    # Start panda with a 10s timeout and background it
    # then sleep 1s, connect to the serial port via telnet, run a command and capture output
    # then shutdown panda via monitor and check if output matches expected value
    cmd = f"timeout 10s    panda-system-{data.arch} -loadvm {data.snapshot} -m {data.default_mem}  {qcow_path} \
            {data.extra_args} -serial telnet:localhost:4321,server,nowait \
            -monitor unix:/tmp/panda.monitor,server,nowait & \
            sleep 2; RES=$(echo 'whoami' | nc localhost 4321) && (echo 'q' | nc -q1 -U /tmp/panda.monitor  || true) && echo \"RESULT: $RES\" | grep -q 'root'"
    print(cmd)
    p = subprocess.run(cmd, shell=True)
    if p.returncode != 0:
        raise RuntimeError("Failed to run CLI panda")
    print("\tCLI: PASS")

    # Check 2 - load with python and test OSI profile if arch in osi_supported
    panda = Panda(generic=generic_name)
    assert(os.path.isdir(panda.build_dir)), f"Missing build dir {panda.build_dir}"
    osi_supported = ['i386', 'x86_64', 'arm']

    if panda.arch in osi_supported:
        print(f"{panda.arch} supports OSI - loading")
        panda.load_plugin("osi")
        panda.load_plugin("osi_linux")

    seen = set()
    @panda.cb_asid_changed # Grab proc names at each asid change - AFTER we're at root (can't do OSI during boot, but asid will chage)
    def new_asid(cpu, oldasid, newasid):
        global reverted
        print("ASID", reverted, panda.arch)
        if reverted and panda.arch in osi_supported: # If osi unsupported, bail
            proc = panda.plugins['osi'].get_current_process(cpu) 
            name = panda.ffi.string(proc.name)
            if name not in seen:
                seen.add(name)
        return 0

    @panda.queue_blocking
    def start():
        panda.revert_sync("root")
        global reverted
        reverted = True

        r = panda.run_serial_cmd("grep --color=no root /etc/passwd")
        assert("root:x" in r), "Failed to run grep command"
        panda.end_analysis()

    panda.run()

    if panda.arch in osi_supported:
        assert(len(seen)), "Didn't observe any processes"
        assert(b'grep' in seen), "Didn't see grep process run"

    print("\tPython: PASS" + (" (no OSI)" if panda.arch not in osi_supported else ""))
Esempio n. 22
0
#!/usr/bin/env python3

# This test validates that run_serial_cmd works
# both in terms of getting the correct response
# but also for running multiple commands sequentially

from pandare import Panda
panda = Panda(generic="i386")

@panda.queue_blocking
def run_cmds():
    panda.revert_sync("root")
    
    for cur_size in range(1, 300):
        buf = '1234567890'*(cur_size//10) + '1234567890'[:cur_size % 10]
        assert(len(buf) == cur_size), "Test is broken"

        resp = panda.run_serial_cmd(f"echo {buf}")

        # Check length
        assert(len(resp) == len(buf)), f"Test {cur_size}: Echo'd {len(buf)} characters but got {len(resp)} back"

        # Check contents
        for j in range(len(buf)):
            if resp[j] != buf[j]:
                raise ValueError(f"Test {cur_size}: Response character {j} was {repr(resp[j])} instead of an {buf[j]}")

    panda.end_analysis()

panda.run()
Esempio n. 23
0
from pandare import Panda
panda = Panda(generic='x86_64')


@panda.queue_blocking
def driver():
    panda.revert_sync('root')
    print(panda.run_serial_cmd("grep root /etc/passwd"))
    panda.end_analysis()


panda.require("osi")
panda.require("osi_linux")


def fd_to_fname(cpu, fd):
    proc = panda.plugins['osi'].get_current_process(cpu)
    procname = panda.ffi.string(
        proc.name) if proc != panda.ffi.NULL else "error"
    fname_ptr = panda.plugins['osi_linux'].osi_linux_fd_to_filename(
        cpu, proc, fd)
    fname = panda.ffi.string(
        fname_ptr) if fname_ptr != panda.ffi.NULL else "error"
    return fname


@panda.ppp("syscalls2", "on_sys_read_return")
def read(cpu, tb, fd, buf, cnt):
    fname = fd_to_fname(cpu, fd)
    print(f"read {fname}")
Esempio n. 24
0
#!/usr/bin/env python3

from sys import argv
from pandare import Panda, blocking, ffi

# Record the address of every function we call using callstack_instr

generic_type = argv[1] if len(argv) > 1 else "mipsel"
panda = Panda(generic=generic_type)

if (generic_type == "i386") or (generic_type == "x86_64"):
    panda.load_plugin("callstack_instr")
else:
    panda.load_plugin("callstack_instr", args = {"stack_type":"heuristic"})

@blocking
def run_cmd():
    panda.revert_sync("root")
    print(panda.run_serial_cmd("uname -a"))
    panda.end_analysis()

@panda.ppp("callstack_instr", "on_call")
def on_call(cpu, func):
    print(f"Call to 0x{func:x}")

panda.queue_async(run_cmd)

panda.run()
Esempio n. 25
0
#!/usr/bin/env python3

import os
from enum import Enum
from sys import argv
from pandare import Panda, ffi, blocking

# Single arg of arch, defaults to i386
arch = "i386" if len(argv) <= 1 else argv[1]
panda = Panda(generic=arch)

monitor_lines = []
bb_count = 0

@blocking
def my_runcmd():
    panda.revert_sync('root')
    panda.run_serial_cmd("find . /proc/self")

@blocking
def info_reg():
    global monitor_lines
    result = panda.run_monitor_cmd("info registers")
    monitor_lines = result.split("\n")
    panda.end_analysis()

@panda.cb_before_block_exec
def before_block_exec(env,tb):
    global bb_count
    bb_count += 1
Esempio n. 26
0
#!/usr/bin/env python3

from pandare import Panda

panda = Panda(generic="i386")
panda.load_plugin("osi")
bb_ctr = 0


@panda.cb_after_block_exec
def bbe(cpu, tb, exit_code):

    global bb_ctr

    if (not panda.in_kernel(cpu)) and (exit_code <= 1):
        bb_ctr += 1

        if (bb_ctr % 1000) == 0:
            proc = panda.plugins['osi'].get_current_process(cpu)
            if proc == ffi.NULL:
                return

            proc_name = ffi.string(proc.name).decode("utf-8")
            pc = panda.current_pc(cpu)
            in_dll = panda.plugins['osi'].in_shared_object(cpu, proc)
            print(f"{proc_name}@{pc:016x}, in SO? {in_dll}")


@blocking
def start():
    panda.revert_sync("root")
Esempio n. 27
0
#!/usr/bin/python3

import os
from os import path
from os import remove
import sys
import shutil
from sys import argv
from pandare import blocking, Panda

thisdir = os.path.dirname(os.path.realpath(__file__))

if __name__ == "__main__":
    panda = Panda(arch="i386",
                  qcow="/home/panda/regdir/qcows/wheezy_panda2.qcow2",
                  extra_args="-nographic",
                  expect_prompt=rb"root@debian-i386:.*")

    panda.load_plugin("taint2")
    panda.run_replay("taint2_tests")
Esempio n. 28
0
#!/usr/bin/env python3
from sys import argv
from os import path
import capstone
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection
from pandare import Panda

# Single arg of arch, defaults to i386
arch = "i386" if len(argv) <= 1 else argv[1]
panda = Panda(generic=arch)
md = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_32)

bin_dir = "taint"
bin_name = "taint_asm"

assert (path.isfile(path.join(bin_dir, bin_name))), "Missing file {}".format(
    path.join(bin_dir, bin_name))

# Take a recording of toy running in the guest if necessary
recording_name = bin_dir + "_" + bin_name
if not path.isfile(recording_name + "-rr-snp"):

    @panda.queue_blocking
    def run_it():
        panda.record_cmd(path.join(bin_dir, bin_name),
                         copy_directory=bin_dir,
                         recording_name=recording_name)
        panda.stop_run()

    print("Generating " + recording_name + " replay")
Esempio n. 29
0
'''
proc_start.py

Makes use of the proc_start_linux plugin to get output.

Run with: python3 proc_start.py
'''

from pandare import Panda
from rich import print
from sys import argv

arch = argv[1] if len(argv) > 1 else "arm"
panda = Panda(generic=arch)


@panda.queue_blocking
def do_stuff():
    panda.revert_sync("root")
    for command in ["ls -la", "whoami", "sleep 1", "uname -r"]:
        print(panda.run_serial_cmd("LD_SHOW_AUXV=1 " + command))
    panda.end_analysis()


@panda.ppp("proc_start_linux", "on_rec_auxv")
def rec_auxv(cpu, tb, av):
    print("[bold magenta][START PyPANDA on_recv_auxv][/bold magenta]")
    print("[bold red]Arguments: [/bold red]", end="")
    for i in range(av.argc):
        print(f'[bold red]{panda.ffi.string(av.argv[i])},[/bold red]', end="")
    print()
Esempio n. 30
0
#!/usr/bin/env python3

from sys import argv
from pandare import Panda, blocking, ffi

panda = Panda(generic="x86_64" if len(argv) < 2 else argv[1])


@blocking
def run_cmd():
    panda.revert_sync("root")
    print(panda.run_serial_cmd("uname -a"))
    panda.end_analysis()


@panda.cb_asid_changed()
def asidchange(env, old_asid, new_asid):
    if old_asid != new_asid:
        print("Asid changed from %d to %d" % (old_asid, new_asid))
    return 0


panda.queue_async(run_cmd)

panda.run()