見出し画像

C言語でDLL Injectionを体験する(Windows環境)


1 全般

 勉強のため、Windows 環境下で DLL Injection を行えるプログラムをC言語で作成しました。手法を記載します。

※ 本記事に記載されている内容を許可されていない第三者に対して行うと犯罪行為になります。絶対に悪用しないでください。

※ また、本記事の内容を実行する際は自己責任でお願いします。

2 DLL Injectionのイメージ図

詳細は後述します。

3 DLL Injectionの仕組み

① DLLについて

  DLL(Dynamic Link Library)とは、バイナリの一種(Portable Executable)で、動的リンクを使ったライブラリです。

たとえば、「マウスカーソルが現在、画面上のどの座標にあるかを調べる」などという普遍性・一般性を持つ機能は、さまざまな実行プログラム(アプリケーション)から参照される可能性があるが、その部分をモジュール化して、さまざまなプログラムから使えるようにすることでコードの再利用性を高め、多重開発(車輪の再発明)を防ぐことができる。このような場合に、この機能をダイナミックリンクライブラリとして実装し、アプリケーション実行プログラムの開始時に動的リンクしてから利用する方法がある。

https://ja.wikipedia.org/wiki/ダイナミックリンクライブラリ

② DLL Injection について

DLLインジェクション (DLL Injection) とは、アプリケーションのDLL上のルーチンやリソースへ本来の処理とは異なる処理を行わせるために、DLLイメージを注入してDLL関数の呼び出しを横取り (インターセプト) する技法のこと。通常、アプリケーション (DLL) 開発者と別の者が、何らかの理由でアプリケーション開発者の意図している処理を改変させる場合に用いられる。

https://ja.wikipedia.org/wiki/DLLインジェクション

 DLL Injectionは、セキュリティ対策ソフトによる検出を回避することにも利用できます。

 今回は、Notepad.exe Kernel32.dll を利用したDLL Injectionを行います。

③ Notepad.exe について

 Notepad.exe は、いわゆるメモ帳です。

 Notepad.exe は、テキストファイルの操作を行うため、Kernel32.dll を読み込んでいます。
 例えば、ファイルを開くために Kernel32.dll 内の CreateFile() や ReadFile() を使用し、ファイルを閉じるために CloseHandle() を使用しています。

④ Kernel32.dll について

 Kernel32.dll は、Windows の基本的な機能を提供するライブラリです。中には、DLLの読み込みを行う関数や、新しいスレッドの作成を行う関数などが含まれています。

 今回は、Kernel32.dll の LoadLibrary()CreateRemoteThread() をDLL Injction のために利用します。

4 DLL Injection の流れ

※ 引数は抽象的に表現しており、引数は重要なものだけ記載しています。

pichu.exe:攻撃者が用意した実行ファイル
dll.dll :攻撃者が用意したDLLファイル

① Load Kernel32.dll

 Notepad.exe 実行時に自動的に Kernel32.dll が読み込まれます。

② OpenProcess()

 PIDを指定し、プロセスを開きます。(今回は Notepad.exe)

③ VirturlAllocEx()

 Notepad.exe の仮想メモリの中に、領域を確保します。確保するサイズは、dll.dll の絶対パスの長さです。

④ 0x12345678

 確保できた領域の先頭アドレスを pichu.exe に返します。

⑤ WriteProcessMemory(0x12345678,"C":\Users\kali\Desktop\dll.dll")

 Notepad.exe の 0x12345678 に対し、読み込ませたいDLLファイルの絶対パス("C":\Users\kali\Desktop\dll.dll")を挿入します。

⑥ GetModuleHandle()

 Kernel32.dll のハンドルを取得します。(図では戻り値を省略)

⑦ GetProcAddress(LoadLibrary())

 Kernel32.dll 内の LoadLibrary() のアドレスを要求します。

⑧ 0x98765432

 Kernel32.dll 内の LoadLibrary() の先頭アドレスを pichu.exe に返します。

⑨ CreateRemoteThread(0x98765432,0x12345678)

 新しく Notepad.exe の中でスレッドを作成します。
  0x98765432 = LoadLibrary()
  0x12345678 = "C":\Users\kali\Desktop\dll.dll"

⑩ LoadLibrary("C":\Users\kali\Desktop\dll.dll")

 結果として用意した dll.dll が読み込まれ、dll.dll に実装されている KeyLogger() が実行されます。

5 作成したコード

① コード本体

② KeyLogger() について:dll.c

 キーロガーは windows.h 内の GetAsyncKeyState() を利用して実装しています。引数にキー(仮想キーコード)を渡すことで、そのキーが押されているかどうかを監視し、結果を戻り値で表してくれます。

6 実施手順

① pichu.c と dll.c を任意の場所に格納

② dll.c から dll.dll を作成

PS C:\Users\kali\Desktop> gcc -c -o dll.o dll.c
PS C:\Users\kali\Desktop> gcc -shared -o dll.dll dll.o

③ main.c から main.exe を作成

PS C:\Users\kali\Desktop> gcc -o pichu.exe pichu.c

④ メモ帳を起動

PS C:\Users\kali\Desktop> Notepad.exe

⑤ pichu.exe を実行

 PS C:\Users\kali\Desktop> .\pichu.exe
pichu.exe の実行結果(画像はVS Codeでの実行)
dll.dll の読み込みに成功

⑥ dll.c で設定した時間だけ、キーロガーが実行

dll.dll の終了時

⑦ デスクトップに log.txt が生成され、入力したキーが保存されている

log.txt

7 まとめ

・ 攻撃先の端末で .exe が実行できる環境であるならば、容易にDLL Injectionが可能です。
 → 不用意に実行ファイルを実行しない。

・ DLL Injection はウイルス対策ソフト等による検知を回避するのに有効ですが、場合によっては弾かれる場合があります。筆者の環境では Microsoft Defender の「コントロールされたフォルダーアクセス」により、C:\Users\kali\Documents への書き込みが制限されました。
 → 環境に合わせた設定及び対策が必要。

8 参考文献

・ DLL Injection

・ キーロガー


この記事が気に入ったらサポートをしてみませんか?