Letztes Mal versuche ich einfache genetische Fuzzer zu schreiben (unter strikten Mac OS, nur zum Spaß). Meine Idee ist so etwas wie die:Mac OS (10.13.1) task_for_pid für gegabelten Prozess "(os/kern) failure"
-> Hauptprogramm, das Verfahren
Gabelsteuerung - Binärcode> gegabelt Prozesslast von der Festplatte und springen hinein.
-> Eltern für Aufgabe fragen (task_for_pid (mach_task_self(), childPID, & Aufgabe))
-> Eltern versuchen, Fallen zu fangen (0xcc), zu überprüfen, ob wir es vorher gewesen war, genau wie AFL Werke (natürlich vereinfacht)
-> Kind lädt einige rohe Binärcode (in meinem Beispiel hat System V ABI sein)
-I-Fehler erhalten, wie unten:
16:10|domin568[15] ~/Desktop/experiments/Instrumentation $ ./run.sh
PARENT 3866
task_for_pid() failed with message (os/kern) failure !
CHILD 3867
run.sh:
#!/bin/sh
clang -sectcreate __TEXT __info_plist Info.plist -o server server.c
codesign -s instrument ./server
./server
"Instrument" ist an meinem Schlüsselbund vorhanden ist, und immer vertrauen für die Code-Gesang, so dass ich denke, es ist Fall sein should't.
Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SecTaskAccess</key>
<array>
<string>allowed</string>
<string>debug</string>
</array>
</dict>
</plist>
Natürlich mein Code nur nützlich für die speziellen Fall ist, wird versucht, eine Funktion Fuzz, die Eingabezeichenfolge und vergleichen Sie es mit anderen Zeichenfolge ist.
server.c:
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <mach/mach.h>
#include <stdlib.h>
int main (int argc,char ** argv)
{
pid_t pid = fork();
pid_t parentPID, childPID; //maybe it's not really safe, nevermind
int status;
if (pid == 0)
{
printf ("CHILD %i\n",getpid());
childPID = getpid();
FILE * f = fopen(argv[1],"rb");
if (f == NULL)
{
return -2;
puts ("Cannot open file specified\n");
}
int from,to = 0;
sscanf(argv[2],"%x",&from);
sscanf(argv[3],"%x",&to);
if (from >= to)
{
puts ("R u out of your mind ? check your range of bytes within the file... \n");
return -3;
}
int fileSize = to - from;
void * mem = mmap (NULL,fileSize,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_PRIVATE,fileno(f),0);
if (mem == MAP_FAILED)
{
puts ("[!] Cannot allocate memory for file");
return -4;
}
printf ("[-] File mapped to virtual memory : [%p]\n",mem);
int (*pFunc)(char * str) = (int(*)(char *))(mem+from);
int ret = pFunc("AAAAA");
printf ("Returned : %d\n",ret);
}
else
{
printf ("PARENT %i\n",getpid());
parentPID = getpid();
kern_return_t kret;
mach_port_t task;
mach_port_t target_exception_port;
kret = task_for_pid (mach_task_self(),childPID,&task);
if (kret != KERN_SUCCESS)
{
printf ("task_for_pid() failed with message %s !\n",mach_error_string(kret));
sleep(100000);
}
//save the set of exception ports registered in the process
exception_mask_t saved_masks[EXC_TYPES_COUNT];
mach_port_t saved_ports[EXC_TYPES_COUNT];
exception_behavior_t saved_behaviors[EXC_TYPES_COUNT];
thread_state_flavor_t saved_flavors[EXC_TYPES_COUNT];
mach_msg_type_number_t saved_exception_types_count;
task_get_exception_ports(task,
EXC_MASK_ALL,
saved_masks,
&saved_exception_types_count,
saved_ports,
saved_behaviors,
saved_flavors);
//allocate and authorize a new port
mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_RECEIVE,
&task);
mach_port_insert_right(mach_task_self(),
target_exception_port,
target_exception_port,
MACH_MSG_TYPE_MAKE_SEND);
//register the exception port with the target process
task_set_exception_ports(task,
EXC_MASK_ALL,
target_exception_port,
EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES,
THREAD_STATE_NONE);
ptrace (PT_ATTACHEXC, childPID,0,0);
}
return 0;
}
Warum dieser Fehler ausgibt? Ist es der Fall, wie fork unter OSX funktioniert? Was ist das Problem da draußen? Ich bin kein Experte, wie Osx darunter funktioniert, vielleicht habe ich etwas verpasst. Danke für die Hilfe :) !
Dominik
1. Haben Sie die Berechtigung "SecTaskAccess" (https: // developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man8/taskgated.8.html) in Ihrer Info.plist? 2. Ist Ihre ausführbare Datei signiert? 3. Ihr Prozess muss möglicherweise als root ausgeführt werden, aber ich bin mir nicht sicher, da der Zugriff auf untergeordnete Prozesse ohne Root-Berechtigungen funktionieren kann. – pmdj
Ja, ich habe das alles getan. Wenn ich eine Aufgabe für Finder möchte, erzeugt es keinen Fehler. Wie ich denke, es funktioniert nicht, da childPID für Eltern in der Zeit unbekannt ist, wird die task_for_pid() aufgerufen. Ich weiß nicht, wie ich es anders machen soll. Wie kann ich Code ausführen und als Debugger in einem Programm in Mac OS steuern (wie in der GDB)? Ich habe versucht, gdb Quellcode zu lesen, aber es ist ziemlich schwer für mich zu verstehen, wie es dort gemacht wird. – Domin568
Ok, es ist also nur ein Experiment, aber ich denke immer noch, dass Sie das Folgende überprüfen sollten, bevor Sie sich mit dem Problem "task_for_pid" beschäftigen. Zuerst die Binärdatei, die von Ihrem Child-Prozess zur Ausführung gemappt wurde, müssen Sie sicherstellen, dass die Funktion 'from' keine faulen Symbole oder unaufgelöste Symbole aufruft, weil dydd hier nicht funktionieren würde. Beachten Sie, dieses Ereignis 'printf' ist ein faules Symbol und sollte daher nicht verwendet werden. Zweitens, entsprechend Ihrer Ausgabe, ist es möglich, dass der Kindprozess nicht einmal erstellt wurde, als der Elternteil task_for_pid ausprobiert hat. Überlegen Sie, ob Sie diese beiden Prozesse synchronisieren wollen. – Zohar81