共有ライブラリ (つまり任意のコード) を、ptrace を使わずに動作中の Linux プロセスに注入します。 Cexigua や linux-inject などに触発されました。
.___.__ .__ __ __
__| _/| | |__| ____ |__| ____ _____/ |_ ______ ___.__.
/ __ | | | | |/ \ | |/ __ \_/ ___\ __\ \____ < | |
/ /_/ | | |_| | | \ | \ ___/\ \___| | | |_> >___ |
\____ | |____/__|___| /\__| |\___ >\___ >__| /\| __// ____|
\/ \/\______| \/ \/ \/|__| \/
source: https://github.com/DavidBuchanan314/dlinject
usage: dlinject.py [-h] [--stopmethod {sigstop,cgroup_freeze,none}]
pid /path/to/lib.so
Inject a shared library into a live process.
positional arguments:
pid The pid of the target process
/path/to/lib.so Path of the shared library to load (note: must be
relative to the target process's cwd, or absolute)
optional arguments:
-h, --help show this help message and exit
--stopmethod {sigstop,cgroup_freeze,none}
How to stop the target process prior to shellcode
injection. SIGSTOP (default) can have side-effects.
cgroup freeze requires root. 'none' is likely to cause
race conditions.
できるから。
さまざまな アンチ ptrace テクニック が存在しますが、これは ptrace を単に使わないことで回避します。
ptrace が好きではありません。
LD_PRELOAD を使うと、注入したいプロセスがクリーンな環境で別のプロセスから起動される場合、扱いにくかったり不可能だったりすることがあります。
ターゲットプロセスに停止シグナルを送信します(オプション)。
_dl_open() シンボルを特定します。
/proc/[pid]/syscall を介して RIP と RSP を取得します。
スタックの一部と、シェルコードで上書きしようとしているコードのバックアップを、/proc/[pid]/mem から読み取って作成します。
プライマリシェルコードとセカンダリシェルコードのバッファを生成します。
/proc/[pid]/mem への書き込みにより、プライマリシェルコードを RIP に挿入します。
プライマリシェルコード:
mmap() を介してセカンダリシェルコードをロードします。セカンダリシェルコード:
_dl_open() を呼び出して、ユーザー指定のライブラリをロードします。ロード時にコンストラクタは通常通り実行されます。SIGSTOP 時点の場所にジャンプして戻ります。SIGSTOP を送信すると、例えば別のスレッドが waitpid() で待機している場合など、望ましくない副作用が生じる可能性があります。--stopmethod=cgroup_freeze オプションはこれを回避しますが、root 権限が必要です(少なくともほとんどのディストリビューションでは)。
複雑なマルチスレッドアプリケーションとの相互作用については完全には確信が持てません。破損の可能性は確かにあります。
x86-64 Linux のみ対応(現時点では。32ビット対応は将来的に追加可能かもしれません)。
root 権限、または緩和された YAMA 設定(テスト時には echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope が便利です)が必要です。
ターゲットプロセスがサンドボックス化されている場合(例:seccomp フィルター)、第2ステージのシェルコードを mmap() したり、ライブラリを dlopen() する権限がない可能性があります。