Samstag, Januar 18, 2020

Wie kann ich Sie dtrace ausführen, die verfolgt Befehl keine root-Privilegien?

OS X fehlt linux strace, aber es hat dtrace was soll so viel besser sein.

Allerdings vermisse ich die Möglichkeit zu tun, einfache Rückverfolgung auf einzelne Befehle. Zum Beispiel auf linux, ich kann schreiben strace -f gcc hello.c zu caputre alle system-Aufrufe, die gibt mir die Liste der alle die Dateinamen benötigt der compiler um mein Programm zu kompilieren (die ausgezeichnete memoize Skript baut auf diesen trick)

Möchte ich memoize-port auf dem mac, also brauche ich irgendeine Art von strace. Was ich eigentlich brauche ist die Liste der Dateien gcc liest und schreibt in das, was ich also brauche, ist mehr von einer truss. Sicher genug kann ich sagen dtruss -f gcc hello.c – und etwas der gleichen Funktionalität, aber dann ist der compiler die Ausführung mit root-Privilegien, was natürlich nicht wünschenswert ist (abgesehen von der massiven Sicherheitsrisiko, ein Problem ist, dass die a.out Datei ist jetzt im Besitz von root 🙂

Dann habe ich versucht dtruss -f sudo -u myusername gcc hello.c, aber das fühlt sich ein bisschen falsch, und sowieso nicht funktioniert (ich bekomme keine a.out Datei überhaupt in dieser Zeit, nicht sicher, warum)

Alle, die lange Geschichte, die versucht zu motivieren, meine ursprüngliche Frage: wie bekomme ich dtrace meinen Befehl mit normalen Benutzerrechten, wie strace in linux ?

Edit: scheint, dass ich bin nicht die einzige, die sich Fragen, wie dies zu tun: Frage #1204256 ist so ziemlich das gleiche ist wie meins (und hat die gleichen suboptimalen sudo Antwort 🙂

InformationsquelleAutor Gyom | 2010-06-09

7 Kommentare

  1. 5

    Nicht die Antwort auf deine Frage, aber etwas zu wissen. OpenSolaris hat dieses Problem gelöst (teilweise) mit „Privilegien“ – siehe auf dieser Seite. Auch in OpenSolaris, wäre es nicht möglich, einen Benutzer ohne zusätzliche Berechtigungen, um dtruss Ihren eigenen Prozess.
    Der Grund ist die Art, wie dtrace funktioniert – es ermöglicht Sonden in den kernel. So dass ein nicht-privilegierter Benutzer zu untersuchen kernel bedeutet, dass der Benutzer tun können, viele unerwünschte Dinge z.B. sniffing anderen Benutzers passwd durch Aktivierung von Sonden in der Tastatur-Treiber!

    • Du hast wahrscheinlich Recht. obwohl erlangen von root-rechten ist nicht ein Problem hier, da auf meinem laptop kann ich (und getan haben) chmod a+s dtrace noch, dtrace ist nicht gedacht als ein „unix power-user“ – tool, sondern als ein „unix-administrator“ – tool. Das ist, warum versuchen die Verwendung von user-Programmen führt zu einer solchen eine erfundene situation. Vielen Dank für deine Antwort.
    • Konnte es denn nicht einen „eingeschränkten Modus“, wo nur einige Sonden (wie die syscall probes, oder userspace probes) auslösen würde, und nur in einigen Prozessen (diejenigen im Besitz der jeweiligen Benutzer), und nur einige Funktionen zur Verfügung stehen würden: diejenigen, die einfach nur überprüfen der eigenen Prozesse oder die nur Zugang zu den Informationen bereits zur Verfügung, um den Benutzer auf andere Weise?
  2. 44

    Der einfachste Weg ist die Verwendung von sudo:

    sudo dtruss -f sudo -u $USER whoami
    

    Andere Lösung wäre, den debugger starten, erste und monitor für die neuen spezifischen Prozesse.
    E. g.

    sudo dtruss -fn whoami
    

    Dann in einem anderen Terminal einfach ein:

    whoami
    

    Einfach.

    Komplizierter Argumente finden Sie im Handbuch: man dtruss


    Alternativ können Sie dtruss zu den Laufenden user-Prozesse z.B. auf dem Mac:

    sudo dtruss -fp PID
    

    oder ähnlich auf Linux/Unix mithilfe von strace:

    sudo strace -fp PID
    

    Anderen hacky trick sein könnte, um den Befehl auszuführen und gleich danach an den Prozess Anhängen. Hier sind einige Beispiele:

    sudo true; (./Pages &); sudo dtruss -fp `pgrep -n -x Pages`
    sudo true; (sleep 1 &); sudo dtruss -fp `pgrep -n -x sleep`
    sudo true; (tail -f /var/log/system.log &); sudo dtruss -fp `pgrep -n -x tail`
    

    Hinweis:

    • ersten sudo ist nur für das caching, das Passwort beim ersten mal laufen,

    • dieser trick funktioniert nicht für schnelle Befehlszeilen wie ls, date wie es einige Zeit dauert, bis debugger an den Prozess Anhängen,

    • geben Sie den Befehl in zwei Orten,

    • können Sie ignorieren & ausführen des Prozesses in den hintergrund, wenn es bereits tun,

    • nach Beendigung Debuggen, müssen Sie manuell löschen Sie die hintergrund-Prozess (z.B. killall -v tail)

    • Du bist ein rockstar für den Hinweis auf die -n option für dtruss. Das ist 100% die richtige Antwort.
  3. 8

    Den -n argument dtruss verursachen dtruss warten und prüfen Prozesse, die mit dem argument -n. Die -f option wird noch Folgen Prozesse entstanden aus den Prozessen angepasst durch -n.

    All dies bedeutet, dass, wenn Sie wollen dtruss ein Prozess (aus Gründen der argument, lassen Sie uns sagen, es ist whoami) laufen als Ihre nicht privilegierten Benutzer, gehen Sie folgendermaßen vor:

    1. Öffnen Sie eine root-shell
    2. Laufen dtruss -fn whoami
      • dies wird sitzen und warten, für einen Prozess namens „whoami“ zu existieren
    3. Öffnen einer nicht privilegierten shell
    4. Laufen whoami
      • dies wird ausgeführt, und normal beenden
    5. Beobachten system call trace in dtruss Fenster
      • dtruss wird nicht verlassen, auf seinen eigenen — wird es weiterhin warten für die matching — Prozesse-so brechen aus ihm heraus, wenn Sie fertig sind

    Diese Antwort kopiert den letzten Teil von @kenorb die Antwort, aber es verdient eine erstklassige Antwort.

  4. 5

    Ich weiß nicht, ob Sie bekommen können dtruss zu sein als nicht-invasive wie strace.

    Eine Variante von „sudo [root] dtruss sudo [zurück zum nonroot] cmd“, das scheint zu funktionieren besser in einigen schnellen Tests für mich ist:

    sudo dtruss -f su -l `whoami` cd `pwd` && cmd....
    

    Den äußeren sudo ist natürlich so dtruss als root läuft.

    Die innere su ist wieder zu mir zurück, und mit -l erstellt die Umgebung richtig, an dem Punkt müssen wir die cd zurück, wo wir angefangen haben.

    Denke ich „su -l „user“ ist besser als „sudo -u user“, wenn Sie wollen, dass die Umwelt das zu sein, was, der user bekommt normalerweise. Dass Sie Ihre login-Umgebung, obwohl, ich weiß nicht, ob es eine gute Möglichkeit, lassen die Umwelt Erben, die durch die zwei Benutzer änderungen statt.

    In Ihrer Frage, eine weitere Beschwerde, die Sie hatte über den „sudo dtruss sudo“ Abhilfe, andere als hässlich war, dass „ich bekomme nicht ein.aus Datei in all dieser Zeit, nicht sicher, warum“. Ich weiß nicht warum, aber in meinem kleinen test-script, ein „sudo dtruss sudo“ – Variante auch nicht zu schreiben, um eine test-Ausgabe-Datei, und das „sudo dtruss su“ – Variante oben hast, erstellen Sie die Ausgabe-Datei.

    • in der Tat, vielen Dank für diesen Versuch. noch, es sieht aus wie ich werde haben, zu geben, bis auf diese eine. Auf linux, die ich verwendet, um strace Befehle aus einer makefile-Ersatz-Skript, um Spion auf welche Dateien wurden berührt durch die Befehle. Ich wollte an diesen port Skripten auf mac os x, aber am Ende des Tages merke ich, dass ich nicht wie die Idee des habens alle meine builds, bei denen mehrere Ebenen von sudo einfach zu spy auf meine eigenen Befehle.
    • Ja. Direkt versucht zu machen dtruss handeln, als eine nicht-invasive strace Ersatz scheint auf dem Holzweg, für die Gründe, die Sie beschreiben. Vielleicht ein alternativer Ansatz erforderlich ist. 2 Dinge, die mir kommen, das könnte möglich sein: 1) greifen Sie die dtrace-source-ändern Sie den userlevel-frontend (muss als root ausgeführt werden), so dass es nur startet neue Prozesse und nur Spione auf diese, fügen Sie eine option, um es anzuweisen, die beginnen jene Prozesse, dann machen Sie es setuid root gehören.
    • Und #2 (Fortsetzung von vorheriger Kommentar): verwenden Sie dtrace direkt die Art und Weise es entworfen wurde, um die Frage zu beantworten, die Sie beantwortet haben möchten, anstatt zu versuchen, es zu benutzen als ein dropin Ersatz für strace in die makefiles zu beobachten, was das Kind Befehle Taten-können Sie schreiben dtrace probes außerhalb der make-Prozess das identifizieren und kommentieren, was der make-Prozess ist zu tun?
    • Vielen Dank für diese Kommentare. Für #1 … aber, ich fürchte, ich werde nicht haben weder genug Zeit noch genug skill (und bei weitem!!!) diesen Weg gehen. Option #2 klingt realistischer zu mir, und ich habe versucht, vertraut genug mit DTrace zu versuchen. Wenn ich schreiben kann, ein DTrace-Skript, das als daemon läuft und beobachtet alle meine bauen von außen, dann ja, ich kann die Informationen bekommen, die ich brauche. Es ist nicht klar, obwohl, wie ich mitteilen kann dieser Dämon, wenn es neue Prozesse zu verfolgen. Ich poste ein update, wenn ich einige Fortschritte erzielt. Nochmals vielen Dank.
  5. 3

    Scheint es, dass OS X unterstützt nicht die Verwendung von dtrace zu replizieren alle Funktionen von strace, die Sie benötigen. Jedoch, ich würde vorschlagen, Sie versuchen zu erstellen einen wrapper um die passenden syscalls. Es sieht aus wie DYLD_INSERT_LIBRARIES die Umgebungsvariable ist, die Sie wollen zu hacken ein bisschen. Das ist im Grunde das gleiche wie LD_PRELOAD für Linux.

    Einen viel einfacheren Weg, das zu tun-Bibliothek-Funktion überschreibt, ist mit der
    DYLD_INSERT_LIBRARIES environment-variable (Analog zu LD_PRELOAD auf
    Linux). Das Konzept ist einfach: beim laden der dynamische linker (dyld)
    wird laden alle dynamischen Bibliotheken angegeben in DYLD_INSERT_LIBRARIES
    bevor irgendwelche Bibliotheken, die ausführbaren will geladen. Durch die Benennung einer Funktion
    die gleiche ist wie in einer Bibliothek-Funktion überschreibt er alle Anrufe
    das original.

    Die ursprüngliche Funktion wird auch geladen und kann abgerufen werden, mithilfe der
    dlsym(RTLD_NEXT, „Funktionsname“); Funktion. Dies ermöglicht eine einfache
    Methode der Umhüllung vorhandenen library-Funktionen.

    Entsprechend der Beispiel von Tom Robinson stellen Sie DYLD_FORCE_FLAT_NAMESPACE=1 auch.

    Kopie der original-Beispiel ( lib_overrides.c ), der überschreibt nur fopen:

    #include <stdio.h>
    #include <unistd.h>
    #include <dlfcn.h>
    
    //for caching the original fopen implementation
    FILE * (*original_fopen) (const char *, const char *) = NULL;
    
    //our fopen override implmentation
    FILE * fopen(const char * filename, const char * mode)
    {
        //if we haven’t already, retrieve the original fopen implementation
        if (!original_fopen)
            original_fopen = dlsym(RTLD_NEXT, "fopen");
    
        //do our own processing; in this case just print the parameters
        printf("== fopen: {%s,%s} ==\n", filename, mode);
    
        //call the original fopen with the same arugments
        FILE* f = original_fopen(filename, mode);
    
        //return the result
        return f;
    }
    

    Verwendung:

    $ gcc -Wall -o lib_overrides.dylib -dynamiclib lib_overrides.c
    $ DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=lib_overrides.dylib command-to-test
    
  6. 2

    Disclaimer: dies ist abgeleitet von @kenorb ist Antwort. Es hat einige Vorteile aber: PID ist spezifischer als execname. Und wir können ein kurzlebiger Prozess warten, DTrace, bevor es beginnt.

    Dies ist ein bisschen race-conditiony, aber…

    Sagen wir, wir möchten zu verfolgen cat /etc/hosts:

    sudo true && \
    (sleep 1; cat /etc/hosts) &; \
    sudo dtrace -n 'syscall:::entry /pid == $1/{@[probefunc] = count();}' $!; \
    kill $!

    Verwenden wir sudo true um sicherzustellen, dass wir klar sudo-s Passwort eingeben, bevor wir starten, läuft alles zeitkritisch.

    Starten wir einen hintergrund-Prozess („warten 1 sec, dann tun Sie etwas Interessantes“). Mittlerweile, beginnen wir mit DTrace. Wir haben erfasst den hintergrund-Prozess der PID in $!, so dass wir passieren können, dass auf DTrace als arg.

    Den kill $! läuft nach dem schließen wir DTrace. Es ist nicht notwendig für unsere cat Beispiel (Prozess schließt auf seine eigenen), aber es hilft uns end lange im hintergrund Laufenden Prozesse wie ping. Vorbei -p $! zu DTrace ist der bevorzugte Weg, dies zu tun, aber auf macOS offenbar erfordert eine code-signierte ausführbare.


    Die andere Sache, die Sie tun können ist, führen Sie den Befehl in eine separate Schale und snoop, die shell. Siehe meine Antwort.

  7. 1

    Ich weiß nicht, einen Weg zu laufen, was Sie wollen, wie ein normaler user, wie es scheint, dass dtruss, die verwendet dtrace benötigt su-Rechte.

    Aber ich glaube, der Befehl, den Sie gesucht haben, anstatt

    dtruss -f sudo -u myusername gcc hello.c

    ist

    sudo dtruss -f gcc hello.c

    Im Anschluss an die Eingabe Ihres Passworts, dtruss wird, führen Sie dtrace wird sudo-Berechtigungen, und Sie werden die trace-als auch die eine.aus Datei.

    Sorry, ich konnte nicht weiter helfen.

    • das problem mit dem eigentlichen ausführen der eigentliche Befehl als root aus (abgesehen von den offensichtlichen riesiges Sicherheits-Risiko) ist, dass sudo runtime-Umgebung (PATH, env-Variablen, Berechtigungen) ist sehr Verschieden von der normalen, und die Auswirkungen dramatisch das Verhalten der verfolgte Programm. Linux strace im Gegenteil, ist fast durchsichtig in Bezug auf funktionale Verhalten der verfolgt Befehl.

Kostenlose Online-Tests