狠狠撸

狠狠撸Share a Scribd company logo
ntt.com
Transform your business, transcend expectations with our technologically advanced solutions.
Copyright ? NTT Communications Corporation. All rights reserved.
DLLインジェクション
NTTコムエンジニアリング
波多浩昭
Copyright ? NTT Communications Corporation. All rights reserved.
自己紹介
名前:波多浩昭
所属:NTTコムエンジニアリング ソフトウェアツール開発センタ
入社直後の専門:組み込み系(NTTグループには生存していないと思われている種)
NTTの電話局に設置される交換機という装置の内部で動作するソフトウェアの開発
モトローラ68Kプロセッサのアセンブリ言語による開発
リアルタイムOS(TRON)上でのアプリケーション開発
その後の出向:NTTPCコミュニケーション
InfoSphereというISPで,ネットワーク管理系ソフトウェア開発
企業向け通信サービスで利用されるソフトウェア開発
現在NTTコミュニケーショングループでは
企業向け通信サービスで利用されるソフトウェア開発を担当
2/19
Copyright ? NTT Communications Corporation. All rights reserved.
DLLインジェクションとは?
EXE
実行中プロセス
EXE
攻撃プロセス
DLL
偽DLL
セキュリティ攻撃の文脈では
実行中のプロセスに悪意を持つ任意のプログラ
ムを実行させる攻撃
BOFは攻撃対象プログラムの入力に,任意のプ
ログラムを与えることで注入に成功する
DLLインジェクションは,悪意を持つDLLを強
制的に読み込ませて,実行させる
偽DLL
1.注入
2.呼び出し先
改ざん
3/19
Copyright ? NTT Communications Corporation. All rights reserved.
VisualStudio Community 2017 の C++デスクトップ開発環境のインストール
https://www.visualstudio.com/ja/vs/whatsnew/ からインストーラをダンロードして起動
開発環境の準備
インストーラ画面からC++
によるデスクトップ開発
をインストールする
x64 Native Tool Command
Promptを起動する
実行ファイルのビルド
>cl A.c
DLLファイルのビルド
>cl B.c /LD
clコマンドを投入してコンパ
イラバージョンが表示され
ることを確認する
64ビット版開発環境である
ことを確認する
インストール後
4/19https://github.com/h-hata/dllinjection
実験用ソースコードは上記よりダウンロード可能です
Copyright ? NTT Communications Corporation. All rights reserved.
プロセスと仮想メモリ
プロセスA
メモリ空間
プロセスB
メモリ空間
カーネル空間
ユーザ空間
同じアドレスでもプロセス
により内容は異なる
他プロセスのメモリ空間に
はアクセスできない
カーネル空間はすべてのあ
プロセスで共有されている
5/19
Copyright ? NTT Communications Corporation. All rights reserved.
VirtualAllocExとWriteProcessMemory
プロセスA
メモリ空間
プロセスB
メモリ空間
VirtualAllocEx
他プロセスのメモリ空間に,利用可能なメモリ領域を確保する
WriteProcessMemory
VirtualAllocExで確保されたメモリ領域に,自プロセスのメモリ内容をコピーする
6/19
通常のプロセス間通信や共
有メモリと異なり,書き込
まれたプロセスは書き込ま
れた場所や書き込まれたタ
イムングを検知できない
VirtualAllocExと
WriteProcessMemoryを使えば他
プロセスのメモリ空間にデータの
書き込みが可能.
Copyright ? NTT Communications Corporation. All rights reserved.
VirtualAllocExとWriteProcessMemory実験
①
② ③
④⑤
⑥
事前準備
プロセスを2つ起動するために,2つの
コマンドプロンプトを起動します.
testmemディレクトリのta.cとmw.cをビル
ドします.
$cl ta.c
$cl mw.c
mw.exeはta.exeのメモリを確保してデー
タを書き込みます.
実験
①ta.exeを起動します.pidが表示されることを確認します
②他画面からmw.exeでta.exeプロセスのメモリを確保して”ABCDEFG“という文字列を書き込みます
③ta.exeでは該当アドレスにデータが書き込まれていることを確認できます
④まだ未使用のエリアのメモリダンプを試みると例外が発生します(経験上次は1D0000が確保され
る予感)
⑤mw.exeで,もう一度別のメモリエリアを確保して”12345678”という文字列を書き込みます.予想
通り1D0000からメモリ確保されました
⑥ta.exeで1D0000をダンプすると,今度は書き込まれたデータが確認できます 7/19
Copyright ? NTT Communications Corporation. All rights reserved.
プロセスとスレッド
プロセスA
メモリ空間
プロセスB
メモリ空間
最初プロセスには1スレッ
ドが存在する.
CreateThread APIでサブス
レッドを生成できる
プロセス内スレッドは,同
じメモリ空間を共有する
8/19
Copyright ? NTT Communications Corporation. All rights reserved.
CreateRemoteThread
プロセスA
メモリ空間
プロセスB
メモリ空間
他プロセスに強制的にス
レッドを生成する.
9/19
CreateRemoteThread
Copyright ? NTT Communications Corporation. All rights reserved.
CreateRemoteThreadの実験
①②
③
事前準備
プロセスを2つ起動するために,2つのコマンドプロンプトを起動します.
testmemディレクトリのta.cとcr.cをビルドします.
$cl mw.c
cr.exeはta.exeの関数DispMessageを強制的に起動します.
実験
①taを起動します.DispMessage関数の開始アドレスが13FB41000であることが確認されます
②crを起動します.taのプロセスIDとDispMessage関数の開始アドレスを起動パラメータにします
③ta側でDispMessageが起動され,”log:”という文字列がいきなり表示されてしまいます.
9-2/19
Copyright ? NTT Communications Corporation. All rights reserved.
kernel32.libのロード位置
プロセスA
メモリ空間
プロセスB
メモリ空間
kernel32.dll kernel32.dllロード位置
function() function()
同じアドレス
同じアドレス開始位置
kernel32.dllはすべてのノーマルプロセスで同一のアドレスにロードされる
kernel32.dll内の関数はすべてのプロセスで同一開始アドレスである
kernel32.dll内の関数はRemoteCreateThreadを使って他プロセスで起動できる
10/19
Copyright ? NTT Communications Corporation. All rights reserved.
DLLの作り方と使い方
sub.c
(例)
main.cとsub.cから構成されmain.exeがsub.dllを利用するアプリケー
ションをビルドする
sub.dll sub.lib
main.c
#include <windows.h>
__declspec(dllexport) int sub(int a,int b)
{return a-b;}
WINAPI
DllMain(HINSTANCE h,DWORD reasin,PVOID imp)
{return TRUE;}
#include <windows.h>
#include <stdio.h>
int main(int arc,char **argv)
{printf("sub=%d?n",sub(5,3));}
>main
sub=2
+
sub.lib+ main.exe
>cl /LD sub.c
>cl main.c sub.lib
sub.c
main.c
実行結果ビルド時にlibファイルが必要
実行時にはlibファイルは不要dllのみ必要
DllMainはロードされた時に実行される(通常何もしない)
11/19
Copyright ? NTT Communications Corporation. All rights reserved.
実行可能ファイルがDLLを呼び出す仕組み
#include <windows.h>
#include <stdio.h>
typedef int(*T)(int,int);
int main(int arc,char **argv){
T f;
HMODULE hm;
hm=LoadLibrary(”add.dll");
if(hm==NULL){
printf("Load Error?n"); return 1;
}
f=(T)GetProcAddress(hm,”myadd");
printf(”add=%d?n",f(5,3));
}
libファイルがなくてもDLLの持つ関数の
シグネチャーを知っていれば利用可能
main.exe
add.dll
?
?
?
myadd()
?
?
?
myadd(){
}
LoadLibrary
起動
GetProcAddress
実行時にDLLをロードしてから関数のアドレスを探し出して呼び出すこともできる
12/19
Copyright ? NTT Communications Corporation. All rights reserved.
EXEとDLLを結びつける仕組み IATとEAT
B.DLL
EAT
b() ? RVA of b
C.DLL
EAT
c() ? RVA of c
A.EXE
B.DLL
b() ? B Base +RVA
C.DLL
c() ? C Base +RVA
IAT
B Base
+
C Base
+
13/19
Copyright ? NTT Communications Corporation. All rights reserved.
IATテーブルの取得実験
C:Usershatasrcdllinjection>cl dumpmain.c add.lib /nologo
dumpmain.c
C:?Users?hata?src?dllinjection>dumpmain
myadd=-1
dumpIAT
DLL:add.dll
AddressOfData:00019F30
myadd => F1BA1000
DLL:imagehlp.dll
AddressOfData:00019F40
ImageDirectoryEntryToDataEx => FFBD21C0
DLL:KERNEL32.dll
AddressOfData:0001A258 TerminateProcess => 7796C140 AddressOfData:0001A454
WriteConsoleW => 779331E0 AddressOfData:0001A446 CreateFileW => 77930D10
AddressOfData:0001A438 CloseHandle => 77941910 AddressOfData:00019F6C
GetModuleHandleA => 77935A80
add.dllのIAT / myadd関数のアドレス
imagehlp.dllのIAT
kernel32.dll
のIAT
14/19
Copyright ? NTT Communications Corporation. All rights reserved.
(1)攻撃対象のプロセス内メモリに偽DLLのファイル名を書き込む
?VirtualAllocExとWriteProcessMemoryを使う
(2)偽DLLを攻撃対象のプロセスに読み込ませる
?CreateRemoteThread を使う.
起動パラメータは, LoadLibraryと上記で書き込んだリモートアドレス
(3)攻撃対象のプロセスのIATの,ターゲット関数のアドレスを偽DLLの関数アドレスで上書き
?偽DLLのDllMain関数で実行
DLLインジェクションの手順
15/19
Copyright ? NTT Communications Corporation. All rights reserved.
イメージ図
main.exe
add.dll
prtintf(“a+b=%d“,add(15,3));
Create RemoteThread
?LoadLibrary
起動
IAT
add.dll
add => X
add(){
return a-b;
}
X inj.exe
newadd.dll
main.exe
add.dll
newadd.dllZ newproc(){
return a+b;
}
DllMain(){
IAT書き換え
}
Z
16/19
Copyright ? NTT Communications Corporation. All rights reserved.
DLLインジェクション実験
①
②
③
④
①ターゲットプロセスを起動 main.exe
②ターゲットプロセスのプロセスIDを調査
③DLLインジェクション実行
④ターゲットプロセスのバグが修正された
17/19
Copyright ? NTT Communications Corporation. All rights reserved.
APIフック
アプリケーション
WinAPI
kernel32.dll
DLLインジェクション
で挿入したkernel32.dll
の偽物
呼ばれたパラメータをそのまま
使って本物のAPIを呼ぶ
APIコールのログ収集
18/19
Copyright ? NTT Communications Corporation. All rights reserved.
告知
技術書典#3
日時 2017/10/22 (日) 11:00?
17:00
場所 アキバ?スクエア
主催 TechBooster/達人出版会
一般参加 無料
技術系同人誌即売会
出展案内
サークル名:おかか通研
書名:公開鍵暗号計算演習書
予価:500円
(ご注意)17時までやっていますが,半数のサークルは
14時頃に売り切れ閉店します.入場時に並びますが,な
るべく午前中にお越しください.

More Related Content

Dll Injection

  • 1. ntt.com Transform your business, transcend expectations with our technologically advanced solutions. Copyright ? NTT Communications Corporation. All rights reserved. DLLインジェクション NTTコムエンジニアリング 波多浩昭
  • 2. Copyright ? NTT Communications Corporation. All rights reserved. 自己紹介 名前:波多浩昭 所属:NTTコムエンジニアリング ソフトウェアツール開発センタ 入社直後の専門:組み込み系(NTTグループには生存していないと思われている種) NTTの電話局に設置される交換機という装置の内部で動作するソフトウェアの開発 モトローラ68Kプロセッサのアセンブリ言語による開発 リアルタイムOS(TRON)上でのアプリケーション開発 その後の出向:NTTPCコミュニケーション InfoSphereというISPで,ネットワーク管理系ソフトウェア開発 企業向け通信サービスで利用されるソフトウェア開発 現在NTTコミュニケーショングループでは 企業向け通信サービスで利用されるソフトウェア開発を担当 2/19
  • 3. Copyright ? NTT Communications Corporation. All rights reserved. DLLインジェクションとは? EXE 実行中プロセス EXE 攻撃プロセス DLL 偽DLL セキュリティ攻撃の文脈では 実行中のプロセスに悪意を持つ任意のプログラ ムを実行させる攻撃 BOFは攻撃対象プログラムの入力に,任意のプ ログラムを与えることで注入に成功する DLLインジェクションは,悪意を持つDLLを強 制的に読み込ませて,実行させる 偽DLL 1.注入 2.呼び出し先 改ざん 3/19
  • 4. Copyright ? NTT Communications Corporation. All rights reserved. VisualStudio Community 2017 の C++デスクトップ開発環境のインストール https://www.visualstudio.com/ja/vs/whatsnew/ からインストーラをダンロードして起動 開発環境の準備 インストーラ画面からC++ によるデスクトップ開発 をインストールする x64 Native Tool Command Promptを起動する 実行ファイルのビルド >cl A.c DLLファイルのビルド >cl B.c /LD clコマンドを投入してコンパ イラバージョンが表示され ることを確認する 64ビット版開発環境である ことを確認する インストール後 4/19https://github.com/h-hata/dllinjection 実験用ソースコードは上記よりダウンロード可能です
  • 5. Copyright ? NTT Communications Corporation. All rights reserved. プロセスと仮想メモリ プロセスA メモリ空間 プロセスB メモリ空間 カーネル空間 ユーザ空間 同じアドレスでもプロセス により内容は異なる 他プロセスのメモリ空間に はアクセスできない カーネル空間はすべてのあ プロセスで共有されている 5/19
  • 6. Copyright ? NTT Communications Corporation. All rights reserved. VirtualAllocExとWriteProcessMemory プロセスA メモリ空間 プロセスB メモリ空間 VirtualAllocEx 他プロセスのメモリ空間に,利用可能なメモリ領域を確保する WriteProcessMemory VirtualAllocExで確保されたメモリ領域に,自プロセスのメモリ内容をコピーする 6/19 通常のプロセス間通信や共 有メモリと異なり,書き込 まれたプロセスは書き込ま れた場所や書き込まれたタ イムングを検知できない VirtualAllocExと WriteProcessMemoryを使えば他 プロセスのメモリ空間にデータの 書き込みが可能.
  • 7. Copyright ? NTT Communications Corporation. All rights reserved. VirtualAllocExとWriteProcessMemory実験 ① ② ③ ④⑤ ⑥ 事前準備 プロセスを2つ起動するために,2つの コマンドプロンプトを起動します. testmemディレクトリのta.cとmw.cをビル ドします. $cl ta.c $cl mw.c mw.exeはta.exeのメモリを確保してデー タを書き込みます. 実験 ①ta.exeを起動します.pidが表示されることを確認します ②他画面からmw.exeでta.exeプロセスのメモリを確保して”ABCDEFG“という文字列を書き込みます ③ta.exeでは該当アドレスにデータが書き込まれていることを確認できます ④まだ未使用のエリアのメモリダンプを試みると例外が発生します(経験上次は1D0000が確保され る予感) ⑤mw.exeで,もう一度別のメモリエリアを確保して”12345678”という文字列を書き込みます.予想 通り1D0000からメモリ確保されました ⑥ta.exeで1D0000をダンプすると,今度は書き込まれたデータが確認できます 7/19
  • 8. Copyright ? NTT Communications Corporation. All rights reserved. プロセスとスレッド プロセスA メモリ空間 プロセスB メモリ空間 最初プロセスには1スレッ ドが存在する. CreateThread APIでサブス レッドを生成できる プロセス内スレッドは,同 じメモリ空間を共有する 8/19
  • 9. Copyright ? NTT Communications Corporation. All rights reserved. CreateRemoteThread プロセスA メモリ空間 プロセスB メモリ空間 他プロセスに強制的にス レッドを生成する. 9/19 CreateRemoteThread
  • 10. Copyright ? NTT Communications Corporation. All rights reserved. CreateRemoteThreadの実験 ①② ③ 事前準備 プロセスを2つ起動するために,2つのコマンドプロンプトを起動します. testmemディレクトリのta.cとcr.cをビルドします. $cl mw.c cr.exeはta.exeの関数DispMessageを強制的に起動します. 実験 ①taを起動します.DispMessage関数の開始アドレスが13FB41000であることが確認されます ②crを起動します.taのプロセスIDとDispMessage関数の開始アドレスを起動パラメータにします ③ta側でDispMessageが起動され,”log:”という文字列がいきなり表示されてしまいます. 9-2/19
  • 11. Copyright ? NTT Communications Corporation. All rights reserved. kernel32.libのロード位置 プロセスA メモリ空間 プロセスB メモリ空間 kernel32.dll kernel32.dllロード位置 function() function() 同じアドレス 同じアドレス開始位置 kernel32.dllはすべてのノーマルプロセスで同一のアドレスにロードされる kernel32.dll内の関数はすべてのプロセスで同一開始アドレスである kernel32.dll内の関数はRemoteCreateThreadを使って他プロセスで起動できる 10/19
  • 12. Copyright ? NTT Communications Corporation. All rights reserved. DLLの作り方と使い方 sub.c (例) main.cとsub.cから構成されmain.exeがsub.dllを利用するアプリケー ションをビルドする sub.dll sub.lib main.c #include <windows.h> __declspec(dllexport) int sub(int a,int b) {return a-b;} WINAPI DllMain(HINSTANCE h,DWORD reasin,PVOID imp) {return TRUE;} #include <windows.h> #include <stdio.h> int main(int arc,char **argv) {printf("sub=%d?n",sub(5,3));} >main sub=2 + sub.lib+ main.exe >cl /LD sub.c >cl main.c sub.lib sub.c main.c 実行結果ビルド時にlibファイルが必要 実行時にはlibファイルは不要dllのみ必要 DllMainはロードされた時に実行される(通常何もしない) 11/19
  • 13. Copyright ? NTT Communications Corporation. All rights reserved. 実行可能ファイルがDLLを呼び出す仕組み #include <windows.h> #include <stdio.h> typedef int(*T)(int,int); int main(int arc,char **argv){ T f; HMODULE hm; hm=LoadLibrary(”add.dll"); if(hm==NULL){ printf("Load Error?n"); return 1; } f=(T)GetProcAddress(hm,”myadd"); printf(”add=%d?n",f(5,3)); } libファイルがなくてもDLLの持つ関数の シグネチャーを知っていれば利用可能 main.exe add.dll ? ? ? myadd() ? ? ? myadd(){ } LoadLibrary 起動 GetProcAddress 実行時にDLLをロードしてから関数のアドレスを探し出して呼び出すこともできる 12/19
  • 14. Copyright ? NTT Communications Corporation. All rights reserved. EXEとDLLを結びつける仕組み IATとEAT B.DLL EAT b() ? RVA of b C.DLL EAT c() ? RVA of c A.EXE B.DLL b() ? B Base +RVA C.DLL c() ? C Base +RVA IAT B Base + C Base + 13/19
  • 15. Copyright ? NTT Communications Corporation. All rights reserved. IATテーブルの取得実験 C:Usershatasrcdllinjection>cl dumpmain.c add.lib /nologo dumpmain.c C:?Users?hata?src?dllinjection>dumpmain myadd=-1 dumpIAT DLL:add.dll AddressOfData:00019F30 myadd => F1BA1000 DLL:imagehlp.dll AddressOfData:00019F40 ImageDirectoryEntryToDataEx => FFBD21C0 DLL:KERNEL32.dll AddressOfData:0001A258 TerminateProcess => 7796C140 AddressOfData:0001A454 WriteConsoleW => 779331E0 AddressOfData:0001A446 CreateFileW => 77930D10 AddressOfData:0001A438 CloseHandle => 77941910 AddressOfData:00019F6C GetModuleHandleA => 77935A80 add.dllのIAT / myadd関数のアドレス imagehlp.dllのIAT kernel32.dll のIAT 14/19
  • 16. Copyright ? NTT Communications Corporation. All rights reserved. (1)攻撃対象のプロセス内メモリに偽DLLのファイル名を書き込む ?VirtualAllocExとWriteProcessMemoryを使う (2)偽DLLを攻撃対象のプロセスに読み込ませる ?CreateRemoteThread を使う. 起動パラメータは, LoadLibraryと上記で書き込んだリモートアドレス (3)攻撃対象のプロセスのIATの,ターゲット関数のアドレスを偽DLLの関数アドレスで上書き ?偽DLLのDllMain関数で実行 DLLインジェクションの手順 15/19
  • 17. Copyright ? NTT Communications Corporation. All rights reserved. イメージ図 main.exe add.dll prtintf(“a+b=%d“,add(15,3)); Create RemoteThread ?LoadLibrary 起動 IAT add.dll add => X add(){ return a-b; } X inj.exe newadd.dll main.exe add.dll newadd.dllZ newproc(){ return a+b; } DllMain(){ IAT書き換え } Z 16/19
  • 18. Copyright ? NTT Communications Corporation. All rights reserved. DLLインジェクション実験 ① ② ③ ④ ①ターゲットプロセスを起動 main.exe ②ターゲットプロセスのプロセスIDを調査 ③DLLインジェクション実行 ④ターゲットプロセスのバグが修正された 17/19
  • 19. Copyright ? NTT Communications Corporation. All rights reserved. APIフック アプリケーション WinAPI kernel32.dll DLLインジェクション で挿入したkernel32.dll の偽物 呼ばれたパラメータをそのまま 使って本物のAPIを呼ぶ APIコールのログ収集 18/19
  • 20. Copyright ? NTT Communications Corporation. All rights reserved. 告知 技術書典#3 日時 2017/10/22 (日) 11:00? 17:00 場所 アキバ?スクエア 主催 TechBooster/達人出版会 一般参加 無料 技術系同人誌即売会 出展案内 サークル名:おかか通研 書名:公開鍵暗号計算演習書 予価:500円 (ご注意)17時までやっていますが,半数のサークルは 14時頃に売り切れ閉店します.入場時に並びますが,な るべく午前中にお越しください.