Пример #1
0
def main():
    # Check the command line
    if len(argv) < 2:
        print("usage: %s program [arg1 arg2 ...]" % argv[0], file=stderr)
        print("   or: %s pid" % argv[0], file=stderr)
        exit(1)

    # Get the process identifier
    is_attached = False
    has_pid = False
    if len(argv) == 2:
        try:
            # User asked to attach a process
            pid = int(argv[1])
            has_pid = True
        except ValueError:
            pass

    if not has_pid:
        # User asked to create a new program and trace it
        arguments = argv[1:]
        pid = traceProgram(arguments)
        is_attached = True

    # Create the debugger and attach the process
    dbg = PtraceDebugger()
    process = dbg.addProcess(pid, is_attached)

    # Play with the process and then quit
    playWithProcess(process)
    dbg.quit()
Пример #2
0
 def __init__(self, pid):
     self.maps = []
     self.pid = pid
     self.current_ip = None
     self.tracer = PtraceDebugger()
     self.process = False
     self.attached = False
Пример #3
0
    def _startServer(self):
        # create child via ptrace debugger
        # API: createChild(arguments[], no_stdout, env=None)
        logging.debug("START: " + str(
            serverutils.getInvokeTargetArgs(self.config, self.targetPort +
                                            1000)))
        self.pid = createChild(
            serverutils.getInvokeTargetArgs(self.config, self.targetPort),
            False,  # no_stdout
            None,
        )

        # Attach to the process with ptrace and let it run
        self.dbg = PtraceDebugger()
        self.proc = self.dbg.addProcess(self.pid, True)
        self.proc.cont()

        time.sleep(1)

        # i dont think this works here...
        # FIXME
        event = self.dbg.waitProcessEvent(blocking=False)
        if event is not None and type(event) == ProcessExit:
            logging.error("Started server, but it already exited: " +
                          str(event))
            return False

        return True
Пример #4
0
def injectmex64(pid, shellcode):
    from sys import platform

    if platform.startswith('win'):
        print("\nPtrace not working on windows machines ..\n")
        return False
    else:
        try:
            from ptrace.debugger.debugger import PtraceDebugger
            from ptrace.debugger.debugger import PtraceProcess
        except ImportError:
            print(
                "\nYou must install ptrace library before use this script.\n")
            return False
        else:
            try:
                dbg = PtraceDebugger()
                process = dbg.addProcess(int(pid), False)
                rip = process.getInstrPointer()
                bytes = process.writeBytes(
                    rip,
                    shellcode.replace("\\x", "").decode("hex"))
                process.setreg("rbx", 0)
                process.cont()
            except Exception as error:
                print(error)
                print("\nPlease do not forget report !\n")
            else:
                print("\nInject complate !\n")
Пример #5
0
def main():
    if len(argv) < 2:
        print(T.red("Error: No command given."))
        print("Usage: %s COMMAND [ARGUMENT]..." % argv[0])
        exit(1)

    # This is basically "shlex.join"
    command = " ".join([(("'%s'" % arg) if (" " in arg) else arg) for arg in argv[1:]])

    arguments = argv[1:]
    arguments[0] = locateProgram(arguments[0])

    try:
        pid = createChild(arguments, False)
    except Exception as error:
        print(T.red("Error executing %s: %s." % (T.bold(command) + T.red, error)))
        exit(1)

    debugger = PtraceDebugger()
    debugger.traceExec()
    try:
        debugger.traceFork()
    except DebuggerError:
        print(T.yellow("Warning: Running without traceFork support. " +
                       "Syscalls from subprocesses can not be intercepted."))

    process = debugger.addProcess(pid, True)
    prepareProcess(process)

    try:
        operations = get_operations(debugger)
    except Exception as error:
        print(T.red("Error tracing process: %s." % error))
        exit(1)
    except KeyboardInterrupt:
        print(T.yellow("%s terminated by keyboard interrupt." % (T.bold(command) + T.yellow)))
        exit(2)
    finally:
        # Cut down all processes no matter what happens
        # to prevent them from doing any damage
        debugger.quit()

    if operations:
        print("%s has prevented %s from performing %d file system operations:\n" %
              (T.bold("maybe"), T.bold(command), len(operations)))
        for operation in operations:
            print("  " + operation)
        try:
            choice = input("\nDo you want to rerun %s and permit these operations? [y/N] " % T.bold(command))
        except KeyboardInterrupt:
            choice = ""
        if choice.lower() == "y":
            call(argv[1:])
    else:
        print("%s has not detected any file system operations from %s." %
              (T.bold("maybe"), T.bold(command)))
Пример #6
0
def start(pid):
    # need to attach to the process with ptrace before you can read it's proc/$pid/maps
    # or be root I guess
    # https://unix.stackexchange.com/questions/6301/how-do-i-read-from-proc-pid-mem-under-linux
    # http://lkml.iu.edu/hypermail/linux/kernel/0505.0/0858.html
    dbg = PtraceDebugger()
    try:
        process = dbg.addProcess(pid, False)
    except:
        print("Could not attach to process {}".format(pid))
        return
    dump(process, pid)
    dbg.quit()
Пример #7
0
def main():
    sys.argv = sys.argv[1:]
    filter_scopes = SYSCALL_FILTERS.keys()
    syscall_filters = {}

    for filter_scope in SYSCALL_FILTERS:
        if filter_scope in filter_scopes:
            for syscall in SYSCALL_FILTERS[filter_scope]:
                syscall_filters[syscall] = SYSCALL_FILTERS[filter_scope][
                    syscall]

    # Suppress logging output from python-ptrace
    getLogger().addHandler(NullHandler())

    # Prevent python-ptrace from decoding arguments to keep raw numerical values
    DIRFD_ARGUMENTS.clear()
    SYSCALL_ARG_DICT.clear()
    ARGUMENT_CALLBACK.clear()

    try:
        sys.argv[0] = locateProgram(sys.argv[0])
        pid = createChild(sys.argv, False)
    except Exception as error:
        print(f"Error executing {sys.argv}: {error}.")
        return 1

    debugger = PtraceDebugger()
    debugger.traceFork()
    debugger.traceExec()

    process = debugger.addProcess(pid, True)
    process.syscall()

    try:
        operations = get_operations(debugger, syscall_filters, True)
    except Exception as error:
        print(f"Error tracing process: {error}.")
        return 1
    finally:
        # Cut down all processes no matter what happens
        # to prevent them from doing any damage
        debugger.quit()

    if operations:
        for operation in operations:
            print("  " + operation)
    else:
        print(f"Not detected any file system operations from: {sys.argv}")
Пример #8
0
 def dump(self):
     """ Dump the memory """
     self.dbg = PtraceDebugger()
     #print "Created object"
     try:
         self.dbg.addProcess(self.pid, False)
         #print "Attached to process"
     except:
         #print "Error adding process", sys.exc_info()[1]
         pass
     try:
         #print "Resolving process's name"
         self.processName = getProcessName(self.pid)
         #print "Resolving segmnents"
         segments = getMemorySegments(self.pid, True)
         #print "SEGMENTS:", segments
         #print "Now dumping memory"
         dumpProcessMemory(self.pid, self.outFile, segments, True)
     except:
         pass
Пример #9
0
def attach(pid):
    print "%s{+} Attaching to %s %s" % (cyan, pid, clear)
    dbg = PtraceDebugger()
    process = dbg.addProcess(int(pid), False)
    return process
Пример #10
0
 def __init__(self, pid) :
     self.tracer = PtraceProcess(PtraceDebugger(), pid, True)
Пример #11
0
def main(argv=sys.argv[1:]):
    filter_scopes = sorted(SYSCALL_FILTERS.keys())

    # Insert positional argument separator, if not already present
    if "--" not in argv:
        for i, argument in enumerate(argv):
            if not argument.startswith("-"):
                argv.insert(i, "--")
                break

    arg_parser = ArgumentParser(
        prog="maybe",
        usage="%(prog)s [options] command [argument ...]",
        description=
        "Run a command without the ability to make changes to your system " +
        "and list the changes it would have made.",
        epilog="For more information, to report issues or to contribute, " +
        "visit https://github.com/p-e-w/maybe.",
    )
    arg_parser.add_argument("command",
                            nargs="+",
                            help="the command to run under maybe's control")
    arg_group = arg_parser.add_mutually_exclusive_group()
    arg_group.add_argument(
        "-a",
        "--allow",
        nargs="+",
        choices=filter_scopes,
        metavar="OPERATION",
        help="allow the command to perform the specified operation(s). " +
        "all other operations will be denied. " +
        "possible values for %(metavar)s are: %(choices)s")
    arg_group.add_argument(
        "-d",
        "--deny",
        nargs="+",
        choices=filter_scopes,
        metavar="OPERATION",
        help="deny the command the specified operation(s). " +
        "all other operations will be allowed. " +
        "see --allow for a list of possible values for %(metavar)s. " +
        "--allow and --deny cannot be combined")
    arg_parser.add_argument(
        "-l",
        "--list-only",
        action="store_true",
        help="list operations without header, indentation and rerun prompt")
    arg_parser.add_argument(
        "--style-output",
        choices=["yes", "no", "auto"],
        default="auto",
        help="colorize output using ANSI escape sequences (yes/no) " +
        "or automatically decide based on whether stdout is a terminal (auto, default)"
    )
    arg_parser.add_argument(
        "-v",
        "--verbose",
        action="count",
        help="if specified once, print every filtered syscall. " +
        "if specified twice, print every syscall, highlighting filtered syscalls"
    )
    arg_parser.add_argument("--version",
                            action="version",
                            version="%(prog)s 0.4.0")
    args = arg_parser.parse_args(argv)

    initialize_terminal(args.style_output)

    if args.allow is not None:
        filter_scopes = set(filter_scopes) - set(args.allow)
    elif args.deny is not None:
        filter_scopes = args.deny

    syscall_filters = {}

    for filter_scope in filter_scopes:
        for syscall in SYSCALL_FILTERS[filter_scope]:
            syscall_filters[syscall] = SYSCALL_FILTERS[filter_scope][syscall]

    # Prevent python-ptrace from decoding arguments to keep raw numerical values
    DIRFD_ARGUMENTS.clear()
    SYSCALL_ARG_DICT.clear()
    ARGUMENT_CALLBACK.clear()

    # This is basically "shlex.join"
    command = " ".join([(("'%s'" % arg) if (" " in arg) else arg)
                        for arg in args.command])

    try:
        args.command[0] = locateProgram(args.command[0])
        pid = createChild(args.command, False)
    except Exception as error:
        print(
            T.red("Error executing %s: %s." %
                  (T.bold(command) + T.red, error)))
        return 1

    debugger = PtraceDebugger()
    debugger.traceFork()
    debugger.traceExec()

    process = debugger.addProcess(pid, True)
    process.syscall()

    try:
        operations = get_operations(debugger, syscall_filters, args.verbose)
    except Exception as error:
        print(T.red("Error tracing process: %s." % error))
        return 1
    except KeyboardInterrupt:
        print(
            T.yellow("%s terminated by keyboard interrupt." %
                     (T.bold(command) + T.yellow)))
        return 2
    finally:
        # Cut down all processes no matter what happens
        # to prevent them from doing any damage
        debugger.quit()

    if operations:
        if not args.list_only:
            print(
                "%s has prevented %s from performing %d file system operations:\n"
                % (T.bold("maybe"), T.bold(command), len(operations)))
        for operation in operations:
            print(("" if args.list_only else "  ") + operation)
        if not args.list_only:
            try:
                choice = input(
                    "\nDo you want to rerun %s and permit these operations? [y/N] "
                    % T.bold(command))
            except KeyboardInterrupt:
                choice = ""
                # Ctrl+C does not print a newline automatically
                print("")
            if choice.lower() == "y":
                subprocess.call(args.command)
    else:
        print("%s has not detected any file system operations from %s." %
              (T.bold("maybe"), T.bold(command)))
Пример #12
0
 def __init__(self, pid=None):
     self.sessions = {}
     self.connections = {}
     self.dbg = PtraceDebugger()
     self.processes = {}
Пример #13
0
	def __init__(self, process):
		self.maps = []
		self.current_ip = None
		self.tracer = PtraceDebugger()
		self.process = self.tracer.addProcess(process.pid, False)
		self.maps.extend(self.process.readMappings()[0:4])
Пример #14
0
def doFuzz(config,
           setupEnvironment=_setupEnvironment,
           chooseInput=_chooseInput,
           generateSeed=_generateSeed,
           runFuzzer=_runFuzzer,
           runTarget=_runTarget,
           checkForCrash=_checkForCrash,
           handleOutcome=_handleOutcome):
    seed = 0
    count = 0
    haveOutcome = False
    outcome = None
    done = False

    # Step 1: Setup environment
    setupEnvironment(config)

    print "Running fuzzer:", config["fuzzer"]

    sys.stdout.write("%8d: " % (0))
    sys.stdout.flush()

    while not done:
        # Step 2: Choose an input
        inFile = chooseInput(config)

        # We're done if no input is returned
        if inFile is None:
            print "\nNo more inputs, exiting."
            break

        # Step 3: Generate a seed
        seed = generateSeed(config)

        # Generate a name for the output file
        outExt = os.path.splitext(inFile)[1]
        outFile = os.path.join(os.getcwd(), str(seed) + outExt)

        # Step 4: Run fuzzer
        runFuzzer(config, inFile, seed, outFile, count)

        # Step 5: Run the target
        pid = runTarget(config, outFile)

        #######################################################################
        # This is where the magic happens. We monitor the process to determine
        # if it has crashed
        # Attach to the process with ptrace
        dbg = PtraceDebugger()
        proc = dbg.addProcess(pid, True)
        proc.cont()

        # Calculate the maximum time the target will be allowed to run
        endTime = time.time() + config["target_timeout"]

        outcome = None
        while True:
            try:
                # Check if there is an event pending for the target applicaiton
                # This will return immediately with either an event or None if
                # there is no event. We do this so we can kill the target after
                # it reaches the timeout
                event = dbg.waitProcessEvent(blocking=False)

                # Check if the process exited
                if type(event) == ProcessExit:
                    # Step 6: Check for crash
                    outcome = checkForCrash(config, event)

                    # The target application exited so we're done here
                    break

                elif type(event) == ProcessSignal:
                    # SIGCHLD simply notifies the parent that one of it's
                    # children processes has exited or changed (exec another
                    # process). It's not a bug so we tell the process to
                    # continue and we loop again to get the next event
                    if event.signum == SIGCHLD:
                        event.process.cont()
                        continue

                    outcome = checkForCrash(config, event)
                    break

            except KeyboardInterrupt:
                done = True
                break

            # Check if the process has reached the timeout
            if time.time() >= endTime:
                break
            else:
                # Give the CPU some timeslices to run other things
                time.sleep(0.1)

        # Step 7: Handle any crashes
        if outcome is not None:
            handleOutcome(config, outcome, inFile, seed, outFile, count)

            haveOutcome = True

        # Done with the process
        proc.terminate()

        # Delete the output
        try:
            os.remove(outFile)
        except:
            print "Failed to remove file %s!" % outFile

        # Update the counter and display the visual feedback
        count += 1
        if count % 2 == 0:
            if haveOutcome:
                sys.stdout.write("!")
                haveOutcome = False
            else:
                sys.stdout.write(".")

            sys.stdout.flush()

        if count % 100 == 0:
            sys.stdout.write("\n%8d: " % count)
            sys.stdout.flush()