C++ Packet Manipulation on IP level

This C program shows how to sends MAC-spoofed TCP-Packets to achieve various interesting effects. Have a look at the Source Code for the documentation. This shows how to create faked MAC and IP Adresses to inject ACK, SYN or RST Packets e.g.

/******************************************************************************
*   tcpInject 0.001 (closed)
*   MaMa, 2004, Germany
*
*
*   INFO:
*
*       Tutorial-By-Code. This Program sends MAC-spoofed TCP-Packets. Have a
*       look at the Source Code for the Documentation. This shows how to create
*       faked MAC & IP Adresses to inject ACK, SYN or RST Packets e.g.
*
*       This code uses the SYN as default and sends only the amount of 0xFF packets.
*       Source-MAC was set to 00-00-00-00-00-00
*       Source-IP was set to 127.0.0.1
*       There is no argument interface, just code...
*
*
*   TOPIC:
*
*       This SourceCode is completely FREEWARE. Do whatever you want with this
*       code, if you are aiming at securing Networking Issues.
*
*       WARNING! some software-firewalls do some autocorrection to invalid CRCs.
*
*
*   REQUIREMENTS:
*
*       + WinPCap 3.0 (or higher) Driver installed ( \WinPCap\WinPcap_3_0.exe )
*       + WinPCap SDK Files ( \Include )
*       + Administrative Rights (for enabling the Driver)
*
*       + Compile with bcc (my first choice) or gcc e.g
*       + Written for Win32. Yes, you can do _exactly_ the same
*         Network gimmics on Win32. This proofes... Dont bug me with Linux. Rewrite it :D
*
*
*   CONTACT:
*
*       mama at gmx dot biz [FRI 21 Mai 2004]
*
******************************************************************************/
#include
#include
#include "Include\packet32.h"
#define PACKETS                 0xFF // 0xFFFFFFFF-1
#define MAX_DEVICES             5
#define DEVICE_CAPTION_LENGTH   0x400
char FDeviceList[MAX_DEVICES][DEVICE_CAPTION_LENGTH];

typedef char* PCHAR;
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned int UINT;
typedef unsigned long ULONG;

typedef struct mac_address  // 6 Bytes
{
    UCHAR Byte1;
    UCHAR Byte2;
    UCHAR Byte3;
    UCHAR Byte4;
    UCHAR Byte5;
    UCHAR Byte6;
} mac_address;

typedef struct ip_address   // 4 Bytes
{
    UCHAR Byte1;
    UCHAR Byte2;
    UCHAR Byte3;
    UCHAR Byte4;
} ip_address;

typedef struct ip_header    // 20 Bytes
{
    UCHAR ver_ihl;          // Version + Header-length
    UCHAR tos;              // Type of service
    USHORT tlen;            // Total length
    USHORT identification;  // Identification
    USHORT flags_fo;        // Flags (3 bits) + Fragment offset (13 bits)
    UCHAR ttl;              // Time to live
    UCHAR proto;            // Protocol
    USHORT crc;             // Header checksum
    ip_address saddr;       // Source address
    ip_address daddr;       // Destination address
} ip_header;

typedef struct tcp_header   // 20 Bytes
{
    USHORT sport;           // Source port
    USHORT dport;           // Destination port
    UINT seqnum;            // Sequence Number
    UINT acknum;            // Acknowledgement number
    UCHAR hlen;             // Header length
    UCHAR flags;            // packet flags
    USHORT win;             // Window size
    USHORT crc;             // Header Checksum
    USHORT urgptr;          // Urgent pointer
} tcp_header;

typedef struct
{
    mac_address SrcMAC;
    mac_address DestMAC;
    ip_header IPHeader;
    tcp_header TCPHeader;
} tcp_packet;

/******************************************************************************
    calculate header crc
******************************************************************************/
USHORT crc( USHORT *Data, int Words )
{
    ULONG Crc=0;
    for( Crc=0; Words>0; Words-- )
    {
        Crc += *Data++;
    }
    Crc = ( Crc>>16 ) + ( Crc&0xFFFF );
    Crc += ( Crc>>16 );
    return (USHORT) ~Crc;
}

/******************************************************************************
    fill FDeviceList & display
******************************************************************************/
void ParseDevices( PCHAR DeviceList )
{
    // device listing
    PCHAR pCurDevice = DeviceList;
    PCHAR pNextDevice = DeviceList;
    UINT iDeviceCount = 0;
    // parsing the string. Str1|NULL|Str2|Null|...
    for(ULONG i=0; i iDeviceCount )
    {
        printf("\nDevice No.%d not possible.", iOpenDeviceNo );
        return -1;
    }
    // open the device
    lDevice = PacketOpenAdapter( FDeviceList[iOpenDeviceNo-1] );
    if (!lDevice || (lDevice->hFile == INVALID_HANDLE_VALUE))
    {
        printf( "\nError in PacketOpenAdapter(), Error Code: %lx", GetLastError() );
        return -1;
    }
    // allocate the memory for the packet
	if( ( lpPacket = PacketAllocatePacket() ) == NULL )
    {
		printf("\nError in PacketAllocatePacket()");
		return (-1);
	}
    // "source" mac address
    maSourceMac.Byte1 = 0x00;
    maSourceMac.Byte2 = 0x00;
    maSourceMac.Byte3 = 0x00;
    maSourceMac.Byte4 = 0x00;
    maSourceMac.Byte5 = 0x00;
    maSourceMac.Byte6 = 0x00;
    // destination mac address
    maDestMac.Byte1 = 0x00;
    maDestMac.Byte2 = 0x00;
    maDestMac.Byte3 = 0x00;
    maDestMac.Byte4 = 0x00;
    maDestMac.Byte5 = 0x00;
    maDestMac.Byte6 = 0x00;
    // "source" ip address 127.0.0.1 confuses win2k systems with (lots of) syn packets.
    IPAdressSrc.Byte1 = 127;
    IPAdressSrc.Byte2 = 0;
    IPAdressSrc.Byte3 = 0;
    IPAdressSrc.Byte4 = 1;
    // destination ip address
    IPAdressDest.Byte1 = 0;
    IPAdressDest.Byte2 = 0;
    IPAdressDest.Byte3 = 0;
    IPAdressDest.Byte4 = 0;
    // fill ip header
    IPHeader.ver_ihl = 0x45;
    IPHeader.tos = 0x01;
    IPHeader.tlen = htons(40);
    IPHeader.identification = htons(0x0800);
    IPHeader.flags_fo = 0x0;
    IPHeader.ttl = 0xff;
    IPHeader.proto = 0x06;
    IPHeader.crc = 0x00;
    IPHeader.saddr = IPAdressSrc;
    IPHeader.daddr = IPAdressDest;
    // Calculate the IP Header Checksum
    ip_header ip_hdrcrc;
    memset( &ip_hdrcrc, 0, 20);
    memcpy( &ip_hdrcrc, &IPHeader, 20);
    IPHeader.crc = crc( (USHORT*)&ip_hdrcrc, 10 );
    // fill tcp header
    TCPHeader.sport = 1337;
    TCPHeader.dport = 135;
    TCPHeader.seqnum = htonl(ntohl(0x00) + ntohs(0x00) - 2);
    TCPHeader.acknum = TCPHeader.seqnum + htonl(0x1);
    TCPHeader.hlen = 0x50;
    TCPHeader.flags = 0x02; // 0x02 (SYN) 0x04 (RST)
    TCPHeader.win = 64240;
    TCPHeader.urgptr = 0x00;
    TCPHeader.crc = 0x00;
    /*  | DEST MAC | SRC MAC | TOS | IP HEADER | TCP HEADER |
        | 6 B      | 6 B     | 2 B | 20 B      | 20 B       |  */
    uPacketLength = 54;
    memset( pPacketData, 0, sizeof(pPacketData) );
    memcpy( pPacketData, &maDestMac, 6 );
    memcpy( (pPacketData + 6), &maSourceMac, 6 );
    USHORT ip_tos = htons(0x0800);
    memcpy( (pPacketData + 12), &ip_tos, 2);
    // add ip & tcp header to packet buffer
    memcpy( (pPacketData + 14), &IPHeader, 20 );
    memcpy( (pPacketData + 14 + sizeof(ip_header) ), &TCPHeader, 20 );
    printf("\n%d:%d:%d:%d:%d:%d -> %d:%d:%d:%d:%d:%d", maSourceMac.Byte1,
        maSourceMac.Byte2, maSourceMac.Byte3, maSourceMac.Byte4, maSourceMac.Byte5,
        maSourceMac.Byte6, maDestMac.Byte1, maDestMac.Byte2, maDestMac.Byte3,
        maDestMac.Byte4, maDestMac.Byte5, maDestMac.Byte6 );
    printf("\n%d.%d.%d.%d:%d -> %d.%d.%d.%d:%d ", IPAdressSrc.Byte1,
        IPAdressSrc.Byte2, IPAdressSrc.Byte3, IPAdressSrc.Byte4, ntohs(TCPHeader.sport),
        IPAdressDest.Byte1, IPAdressDest.Byte2, IPAdressDest.Byte3, IPAdressDest.Byte4,
        ntohs(TCPHeader.dport) );
    // create packet structure
    PacketInitPacket( lpPacket, pPacketData, uPacketLength );
    // write more than 1 packet
    if( PacketSetNumWrites( lDevice, PACKETS ) == FALSE )
    {
        printf( "Error in PacketSetNumWrites()\n" );
    }
    // send the packet
    printf( "\n\nGenerating %d packets...", PACKETS );
    if( PacketSendPacket( lDevice, lpPacket, TRUE ) == FALSE )
    {
        printf( "Error in PacketSendPacket(), Error Code: %lx\n", GetLastError() );
        return -1;
    }
    // finish..
    PacketFreePacket( lpPacket );
    PacketCloseAdapter( lDevice );
    printf( "\nFinished.");
    getch();

    return 0;
}

Schreibe einen Kommentar