WindowsでWrite系のシステムコールを使わずにリモートプロセスにメモリをコピーする別の方法

Urucy

uwu
Staff member
この手法はとあるインジェクション手法で紹介されたコピーテクニックです。
日本語での解説はもちろん、実際にコードとして存在することさえ確認できてないので、貴重な記事としてここに記します。

この手法はAPCキューを悪用することにより、従来のアプローチであるWriteProcessMemoryNtMapViewOfSectionなどを使用せずに、リモートプロセスにメモリをコピーすることが出来ます。
簡単に手順をまとめると次のようになります。
  1. Sleep関数を呼ぶリモートスレッドを一時停止状態で作成する
  2. RtlCopyMemoryの関数ポインタを見つける
  3. NtQueueApcThreadExのAPCルーチンにRtlCopyMemoryを指定し、3つのパラメータを埋める
  4. WaitForSingleObjectExまたは類似の関数をコールして、スレッドのアラートをトリガーする
さて、これを見ると一見簡単そうに見えますが、お気づきになりましたでしょうか。
3の手順のRtlCopyMemoryで、srcはどうするの?という話です。
RtlCopyMemoryはリモートプロセスでコールされるため、srcに渡す仮想アドレスはリモートプロセス内の仮想アドレスを指すことになります。
例えば自分のプロセス内にあるシェルコードのバッファーをコピーしたい時、これをどのように渡すのでしょうか?
これの解決策は、システムDLLのロード仕様を悪用する、が答えです。
kernel32.dllntdll.dllは、全てのプロセスで同じ仮想アドレスの場所に配置される仕様があります。
これを利用し、システムDLLのバッファー内にあるOPコードを1バイトずつコピーすることが出来ます。
NtQueueApcThreadExを呼び出す回数 = APCキューの数 = コピーしたいメモリの長さ になります。

これを踏まえてPoCコードを書くとこんな感じになるでしょう

C-like:
Please, Log in or Register to view codes content!

一部疑似コードのため、そのままでは動きません。

C-like:
Please, Log in or Register to view codes content!

これで、従来のようなメモリコピー手順をしなくてもリモートプロセスにメモリをコピー出来ます。

参考:
Please, Log in or Register to view URLs content!
 
Top