GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Brechen Sie einen Systemaufruf mit ptrace() ab

Es gibt unzählige Low-Level-/clevere (und fehleranfällige) Wege, um dieses Problem zu lösen, aber der moderne Linux-Kernel (3.x, Ihre Distribution benötigt möglicherweise einen zurückportierten Patch) unterstützt etwas namens seccomp, mit dem Sie die Systemaufrufe einschränken können ein Prozess machen kann. Sandboxes verwenden diese Funktionalität, einschließlich Chromium.

Sie können eine Diskussion darüber auf StackOverflow hier sehen oder einfach Google für die Dokumentation und Beispielimplementierungen. Es gibt ziemlich viele Informationen da draußen.


Nun, es scheint, dass manchmal PTRACE_KILL nicht sehr gut funktioniert, können Sie kill verwenden stattdessen:

if (orig_eax == 10)
{
    kill(pid, SIGKILL);
}

BEARBEITEN :Ich teste auf meinem Rechner (Ubuntu Kernel 3.4) mit diesem Programm und alles ist ok:

#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h>
#include <stdio.h>

int main(int argc, char **argv)
{   
    pid_t child;
    long orig_eax;
    int status;

    child = fork();
    if(child == 0) 
    {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    }
    else 
    {
        /* Both wait and waitpid works */
        //wait(NULL);
        waitpid(child, &status, 0);
        orig_eax = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
        /* Tracking execve syscall */
        if (orig_eax == 11)
        {
            /* Both PTRACE_KILL and kill() works on my 3.4.4 Kernel */
            fprintf(stdout, "GOT IT\n");
            //ptrace(PTRACE_KILL, child, NULL, NULL);
            kill(child, SIGKILL);
        }
    }

    return 0;
}

AKTUALISIEREN :Das Problem ist, dass Sie 10 verwenden für Tracking-Systemaufruf statt 11 (weil Sie gerade execve ausführen Befehl), funktioniert dieser Code mit Ihrem rm Befehl:

if (orig_eax == 11)
{
    /* Both PTRACE_KILL and kill() works on my 3.4.4 Kernel */
    fprintf(stdout, "INSIDE THE TRAP, FILE WILL NOT BE REMOVED\n");
    ptrace(PTRACE_KILL, child, NULL, NULL);
    //kill(child, SIGKILL);
}

BEARBEITEN :Ich versuche diesen Code und alles funktioniert gut (die Datei abc.out bestehen nach der Ausführung von CALL_REMOVE noch )

/*
 * REMOVE.c
 * gcc -Wall REMOVE.c -o REMOVE
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{
        /* Both calls work */
        //remove("/root/abc.out");
        unlink("/root/abc.out");

        return 0;
}

/*
 * CALL_REMOVE.c
 * gcc -Wall CALL_REMOVE.c -o CALL_REMOVE
 */

#include <signal.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <sys/user.h>
#include <sys/reg.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
        int i;
        pid_t child;
        int status;
        long orig_eax;
        int kill_ret = 0;

        child = fork();

        if(child == 0)
        {
                ptrace(PTRACE_TRACEME, 0, NULL, NULL);
                execl("/root/REMOVE", "REMOVE",  NULL);
        }
        else
        {
                i = 0;
                while(1)
                {
                        wait(&status);
                        if (WIFEXITED(status) || WIFSIGNALED(status) )
                                break;

                        orig_eax = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
                        if (orig_eax == 10)
                        {
                                fprintf(stderr, "Got it\n");
                                kill_ret = kill(child, SIGKILL);
                                if (kill_ret == -1)
                                {
                                    fprintf(stderr, "Failed to kill ---> %s\n", strerror(errno));
                                }
                        }
                        printf("%d time, system call %ld\n", i++, orig_eax);
                        ptrace(PTRACE_SYSCALL, child, NULL, NULL);
                }
        }

        return 0;
}

Wir haben diese Ausgabe:

[email protected]:/root# ll
total 28K
-rw-r--r-- 1 root root    6 2012-08-18 19:37 abc.out
-rw-r--r-- 1 root root 1023 2012-08-18 19:39 CALL_REMOVE.c
-rw-r--r-- 1 root root  213 2012-08-18 19:39 REMOVE.c
-rwxr-xr-x 1 root root 7,3K 2012-08-18 19:39 CALL_REMOVE
-rwxr-xr-x 1 root root 7,0K 2012-08-18 19:39 REMOVE
[email protected]:/root# ./CALL_REMOVE 
0 time, system call 11
1 time, system call 45
2 time, system call 45
3 time, system call 33
4 time, system call 33
5 time, system call 192
6 time, system call 192
7 time, system call 33
8 time, system call 33
9 time, system call 5
10 time, system call 5
11 time, system call 197
12 time, system call 197
13 time, system call 192
14 time, system call 192
15 time, system call 6
16 time, system call 6
17 time, system call 33
18 time, system call 33
19 time, system call 5
20 time, system call 5
21 time, system call 3
22 time, system call 3
23 time, system call 197
24 time, system call 197
25 time, system call 192
26 time, system call 192
27 time, system call 192
28 time, system call 192
29 time, system call 192
30 time, system call 192
31 time, system call 6
32 time, system call 6
33 time, system call 192
34 time, system call 192
35 time, system call 243
36 time, system call 243
37 time, system call 125
38 time, system call 125
39 time, system call 125
40 time, system call 125
41 time, system call 125
42 time, system call 125
43 time, system call 91
44 time, system call 91
Got it
45 time, system call 10
[email protected]:/root# ll
total 28K
-rw-r--r-- 1 root root    6 2012-08-18 19:37 abc.out
-rw-r--r-- 1 root root 1023 2012-08-18 19:39 CALL_REMOVE.c
-rw-r--r-- 1 root root  213 2012-08-18 19:39 REMOVE.c
-rwxr-xr-x 1 root root 7,3K 2012-08-18 19:39 CALL_REMOVE
-rwxr-xr-x 1 root root 7,0K 2012-08-18 19:39 REMOVE
[email protected]:/root# 

Linux
  1. Überwachen Sie Ihr Linux-System in Ihrem Terminal mit procps-ng

  2. Systemaufrufe unter Linux mit strace verstehen

  3. Befehl zum Herunterfahren von Linux (mit Beispielen)

  4. Balance zwischen Linux-Sicherheit und Benutzerfreundlichkeit

  5. Reparieren Sie ein Systemabbild mit DISM

So überwachen Sie ein Linux-System mit dem Glances-Befehl

Linux-Verfügbarkeitsbefehl mit Beispielen

Erste Schritte mit dem Linux-Betriebssystem

Finden Sie Informationen zur Linux-Systemhardware mit Hwinfo

So zeigen Sie Linux-Systemstatistiken mit Saidar an

Sicherheitsaudit mit Lynis