Wie kann man "ptrace-Operation nicht erlaubt" lösen, wenn versucht wird, GDB an einen Prozess anzuhängen?


75

Ich versuche, ein Programm mit gdb anzuhängen, aber es gibt Folgendes zurück:

Anhängen an Prozess 29139 An Prozess
konnte nicht angehängt werden. Wenn Ihre UID mit der UID des Zielprozesses übereinstimmt, überprüfen Sie die Einstellung von / proc / sys / kernel / yama / ptrace_scope oder versuchen Sie es erneut als Root-Benutzer. Weitere Informationen finden Sie unter /etc/sysctl.d/10-ptrace.conf
ptrace: Operation nicht zulässig.

gdb-debugger gibt zurück "Fehler beim Anhängen an den Prozess, überprüfen Sie die Berechtigungen und versuchen Sie es erneut."

strace gibt zurück "attach: ptrace (PTRACE_ATTACH, ...): Operation nicht erlaubt"

Ich habe "kernel.yama.ptrace_scope" 1 auf 0 und /proc/sys/kernel/yama/ptrace_scope1 auf 0 geändert und Folgendes versucht set environment LD_PRELOAD=./ptrace.so:

#include <stdio.h>
int ptrace(int i, int j, int k, int l) {
    printf(" ptrace(%i, %i, %i, %i), returning -1\n", i, j, k, l);
    return 0;
}

Es wird jedoch immer noch der gleiche Fehler zurückgegeben. Wie kann ich es an Debugger anhängen?

Antworten:


174

Wenn Sie Docker verwenden, benötigen Sie wahrscheinlich die folgenden Optionen:

docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined

49
Auch wenn in der Frage Docker nicht erwähnt wurde, bin ich deshalb hierher gekommen. Dies wurde für mich gelöst und ich danke Ihnen, dass Sie über die Frage hinausgegangen sind.
Perennialista

Dies funktionierte für mich mit GCC 8.2 und GDB 8.1 in Docker
ThetaSinner

1
Wie kann ich das tun, wenn Docker erstellt statt ausgeführt wird? es scheint nicht diese Argumente zu nehmen? (Ich habe einen seltsamen Fehler, der nur bei Verwendung der Docker-
Datei

3
In docker-compose.yml musste ich nur cap_add: - SYS_PTRACE(mit einer neuen Zeile nach dem Doppelpunkt) in meine Containerspezifikation einfügen .
Rafał G.

1
In neuerer Docker-Version 18+ --security-opt seccomp=unconfinedwird nicht mehr benötigt.
BZ

59

Dies liegt an der Kernel-Härtung unter Linux. Sie können dieses Verhalten deaktivieren, indem Sie es ändern echo 0 > /proc/sys/kernel/yama/ptrace_scopeoder ändern/etc/sysctl.d/10-ptrace.conf

Siehe auch diesen Artikel darüber in Fedora 22 (mit Links zur Dokumentation) und diesen Kommentarthread über Ubuntu und.


3
Das echo ...hat in meinem Fall nur funktioniert, wenn ich zuerst eine Root-Konsole mit geöffnet habe sudo -i( sudo echo ...hat aufgrund des Umleitungssymbols nicht funktioniert)
R Yoda

Einige Shell-Konstrukte sind schwierig in Argumenten für Befehle wie sudo zu verwenden.
Jesus

16
Wenn Sie sudo und redirection verwenden, können Sie verwendenecho 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
Daniel Serodio

12

Ich möchte hinzufügen, dass ich --security-opt apparmor=unconfinedzusammen mit den Optionen, die @wisbucky erwähnte, brauchte. Dies war unter Ubuntu 18.04 (sowohl Docker-Client als auch Host). Daher lautet der vollständige Aufruf zum Aktivieren des GDB-Debuggens in einem Container:

docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --security-opt apparmor=unconfined


Dies gibt keine Antwort auf die Frage. Sobald Sie einen ausreichenden Ruf haben, können Sie jeden Beitrag kommentieren . Geben Sie stattdessen Antworten, die nicht vom Fragesteller geklärt werden müssen . - Von der Überprüfung
Rafael

2
@ Rafael Die Antwort wurde mit der vollständigen Befehlszeile aktualisiert. Es bietet jetzt eine völlig eigenständige Antwort auf die Frage.
Juraj Oršulić

11

Ich habe den obigen Anwendungsfall nicht wirklich angesprochen, aber ich hatte dieses Problem:

Problem : Es ist passiert, dass ich mein Programm mit gestartet habe sudo, also gab es mir beim Starten von gdb ptrace: Operation not permitted.

Lösung :sudo gdb ...


1
Beachten Sie jedoch, dass dies sudo gdbauch nicht funktioniert, wenn echo 3 | sudo tee /proc/sys/kernel/yama/ptrace_scope( kernel.org/doc/Documentation/security/Yama.txt ) und Ihre .gdbinitSkripte nicht angezeigt werden .
Ciro Santilli 法轮功 冠状 病 六四 事件 28

3

Jesups Antwort ist richtig; Dies liegt an der Verhärtung des Linux-Kernels. In meinem Fall verwende ich Docker Community für Mac. Um das Flag zu ändern, muss ich die LinuxKit-Shell mit justin cormacks nsenter (ref: https://www.bretfisher.com/docker-for-mac-commands) aufrufen -für-in-local-docker-vm / ).

docker run -it --rm --privileged --pid=host justincormack/nsenter1

/ # cat / etc / issue

Willkommen bei LinuxKit

                    ##         .
              ## ## ##        ==
           ## ## ## ## ##    ===
       /"""""""""""""""""\___/ ===
      {                       /  ===-
       \______ O           __/
         \    \         __/
          \____\_______/

/ # cat / proc / sys / kernel / yama / ptrace_scope

1

/ # echo 0> / proc / sys / kernel / yama / ptrace_scope

/ # Ausfahrt


2

Vielleicht hat jemand diesen Prozess mit gdb verbunden.

  • ps -ef | grep gdb

gdb kann den gleichen Prozess nicht zweimal anhängen.


1

Wenn Berechtigungen ein Problem darstellen, möchten Sie wahrscheinlich gdbserver verwenden. (Ich verwende gdbserver fast immer, wenn ich gdb, Docker oder nein, aus zahlreichen Gründen.) Sie müssen gdbserver (Deb) oder gdb-gdbserver (RH) im Docker-Image installiert haben. Führen Sie das Programm im Docker mit aus

$ sudo gdbserver :34567 myprogram arguments

(Wählen Sie eine Portnummer, 1025-65535). Dann sagen wir in gdb auf dem Host

(gdb) target remote 172.17.0.4:34567

Wo 172.17.0.4ist die IP-Adresse des Docker-Images, die durch /sbin/ip addr listAusführen im Docker-Image gemeldet wird ? Dies wird an einem Punkt vor dem mainAusführen angehängt. Sie können tb mainund czu stoppen main, oder wo immer Sie möchten. Führen Sie gdb unter cgdb, emacs, vim oder sogar in einer IDE oder einfach aus. Sie können gdb in Ihrer Quelle ausführen oder einen Baum erstellen, damit es weiß, wo sich alles befindet. (Wenn Ihre Quellen nicht gefunden werden können, verwenden Sie den dirBefehl.) Dies ist normalerweise viel besser als das Ausführen im Docker-Image.

gdbserver ist darauf angewiesen ptrace, daher müssen Sie auch die anderen oben vorgeschlagenen Schritte ausführen . --privileged --pid=hostgenügte mir.

Wenn Sie auf anderen Betriebssystemen oder eingebetteten Zielen bereitstellen, können Sie dort gdbserver oder einen gdb-Stub ausführen und gdb auf die gleiche Weise ausführen, indem Sie eine Verbindung über ein reales Netzwerk oder sogar über eine serielle Schnittstelle herstellen ( /dev/ttyS0).


1

Ich habe meinen Code mit höheren Berechtigungen für den Umgang mit Ethernet Raw Sockets ausgeführt, indem ich in Debian Distribution den Befehl set Capability gesetzt habe. Ich habe die obige Lösung ausprobiert: echo 0 > /proc/sys/kernel/yama/ptrace_scope oder durch Ändern, /etc/sysctl.d/10-ptrace.confaber das hat bei mir nicht funktioniert.

Zusätzlich habe ich auch versucht, mit dem Befehl set functions für gdb im installierten Verzeichnis (usr / bin / gdb) und es funktioniert : /sbin/setcap CAP_SYS_PTRACE=+eip /usr/bin/gdb. Stellen Sie sicher, dass Sie diesen Befehl mit Root-Rechten ausführen.


0

Ich weiß nicht, was Sie mit LD_PRELOAD oder Ihrer ptrace-Funktion machen.

Warum versuchen Sie nicht, gdb an ein sehr einfaches Programm anzuhängen? Erstellen Sie ein Programm, das einfach wiederholt Hallo oder etwas druckt, und hängen Sie es mit gdb --pid [Hallo Programm-PID] an.

Wenn das nicht funktioniert, haben Sie wirklich ein Problem.

Ein weiteres Problem ist die Benutzer-ID. Stellt sich das Programm, das Sie verfolgen, auf eine andere UID ein? Wenn dies der Fall ist, können Sie es nur verfolgen, wenn Sie dieselbe Benutzer-ID verwenden oder root sind.


Es hängt einfache Programme an, aber ich versuche, eine Crackme-Datei anzuhängen. es hat anti-Debug - Schutz wie diese .
user2850750

@ user2850750: Ich habe der Antwort ein weiteres Bit hinzugefügt.
Zan Lynx

Ich versuche es als root
user2850750

@ user2850750: In Ordnung. Nun, ist es möglich, dass gdb irgendwie die ptrace-Funktion in Ihrem freigegebenen Objekt aufruft? Wenn Sie gdb in einem Hallo-Welt-Programm mit Ihrem Preload-Objekt ausführen, schlägt dies ebenfalls fehl?
Zan Lynx

0

Ich habe mich dem gleichen Problem gestellt und viele Lösungen ausprobiert, aber schließlich habe ich die Lösung gefunden, aber ich weiß wirklich nicht, was das Problem war. Zuerst habe ich den Wert von ptrace_conf geändert und mich als Root bei Ubuntu angemeldet, aber das Problem tritt immer noch auf. Aber das Seltsamste, was passiert ist, ist, dass die GDB mir eine Nachricht gezeigt hat, die besagt:

Could not attach to process. If your uid matches the uid of the target process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try again as the root user.
For more details, see /etc/sysctl.d/10-ptrace.conf warning: process 3767 is already traced by process 3755 ptrace: Operation not permitted.

Mit dem ps-Befehlsterminal wurde der Prozess 3755 nicht aufgelistet.

Ich habe den Prozess 3755 in / proc / $ pid gefunden, aber ich verstehe nicht, was es war !!

Schließlich habe ich die Zieldatei (foo.c) gelöscht, die ich mit PTRACE_ATTACH syscall an das Programm vid gdb und tracer c anhängen möchte, und im anderen Ordner ein anderes c-Programm erstellt und kompiliert.

Das Problem ist gelöst und ich konnte entweder über gdb oder ptrace_attach syscall eine Verbindung zu einem anderen Prozess herstellen.

(gdb) attach 4416

Attaching to process 4416

und ich sende viele Signale an Prozess 4416. Ich habe es sowohl mit gdb als auch mit ptrace getestet, beide laufen korrekt.

Ich weiß wirklich nicht, was das Problem war, aber ich denke, es ist kein Fehler in Ubuntu, da viele Websites darauf verwiesen haben, wie z. B. /ubuntu/143561/why-wont-strace- gdb-attach-to-a-process-obwohl-im-root


0

Zusatzinformation

Wenn Sie Änderungen an den Schnittstellen vornehmen möchten, z. B. die Ovs-Brücke hinzufügen möchten, müssen Sie --privilegedstattdessen verwenden --cap-add NET_ADMIN.

sudo docker run -itd --name=testliz --privileged --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ubuntu

0

Ich wollte diese alte Frage beantworten, da sie nicht akzeptiert wird und alle anderen Antworten nicht verstanden werden. Die eigentliche Antwort ist möglicherweise bereits geschrieben, /etc/sysctl.d/10-ptrace.confwie es unter Ubuntu der Fall ist. Diese Datei sagt:

Für Anwendungen, die Crash-Handler starten, die PTRACE benötigen, können Ausnahmen vom Debugee registriert werden, indem im Segfault-Handler angegeben wird, welcher Prozess PTRACE für den Debugee verwendet: prctl (PR_SET_PTRACER, debugger_pid, 0, 0, 0);

Machen Sie also einfach das Gleiche wie oben: Behalten Sie /proc/sys/kernel/yama/ptrace_scope1 bei und fügen Sie prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);den Debugee hinzu. Dann erlaubt der Debugee dem Debugger, es zu debuggen. Dies funktioniert ohne sudound ohne Neustart.

Normalerweise muss der Debugee auch anrufen waitpid, um ein Beenden nach dem Absturz zu vermeiden, damit der Debugger die PID des Debugee finden kann.


0

Ich möchte nur eine verwandte Antwort hervorheben . Nehmen wir an, Sie sind root und haben es geschafft:

strace -p 700

und bekomme:

strace: attach: ptrace(PTRACE_SEIZE, 700): Operation not permitted

Prüfen:

cat /proc/700/status | grep TracerPid

Wenn Sie so etwas wie " TracerPid: 12Null" sehen, ist dies die PID des Programms, das bereits den Systemaufruf "ptrace" verwendet. Beides gdbund stracebenutze es, und es kann immer nur eines aktiv sein.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.