JBtje 0 Newbie Poster

Hello,

On a website I found the next source code "sniffer.cpp"

Sniffer.cpp

/*

  OoOoOoOoOoOoOoOoOoO
  o HTTP-Sniffer    o
  O www.1plus.se    O
  oOoOoOoOoOoOoOoOoOo

  INFO: The trick is to use raw packets with SIO_RCVALL

 */

#include <iostream>
#include <fstream>
#include <string>
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include "packet_headers.h"

using namespace std;

#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) 

/*
	Init Winsock
	Startup winsock, version 2.
*/

bool fInitWinsock(){
	WSADATA lWsa;

	if ( WSAStartup(MAKEWORD(2,0), &lWsa) != 0 )
		return false;
	
	return true;
}

void LogToFile(const char *log, ... )
{
	va_list va_alist;
	char buff[1024]="";
	va_start (va_alist, log);
	_vsnprintf (buff, sizeof(buff), log, va_alist);
	va_end (va_alist);

	ofstream lOutput;
	lOutput.open("packetlog.txt",ios::app);
	if(lOutput.fail()) return;
	lOutput << buff;
	lOutput.close();
}

/*
	Init Raw Sockets
	!!SIO_RCVALL!!
  */

SOCKET fInitSocket(){
	SOCKET lSock;
	DWORD  lpBuffer[255]; // Should be enough if you dont have like 100 adapters. :P
	DWORD  lSize;
	SOCKET_ADDRESS_LIST *lSaddrlist;

	// RAW SOCKET, PROTOCOL IP
	if( (lSock = WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET){
       return -1;
    }

	/*
	MSDN: 
	The SIO_ADDRESS_LIST_QUERY socket I/O control operation allows a
	WSK application to query the current list of local transport
	addresses for a socket's address family. 

    OutputBuffer A pointer to the buffer that receives the current list of local transport addresses 
	*/
	WSAIoctl(lSock,SIO_ADDRESS_LIST_QUERY,NULL,0,lpBuffer,sizeof(lpBuffer),&lSize,NULL,NULL);
	lSaddrlist = (SOCKET_ADDRESS_LIST*)lpBuffer;

	// Assume its the first. 
	// Dont know how many got more then one network adapter in use.
	// TODO: Fix ? 
	const sockaddr *lSockAddr=lSaddrlist->Address[0].lpSockaddr;

	/* Bind socket to first address */
    if(bind(lSock,lSockAddr,sizeof(SOCKADDR_IN)) == SOCKET_ERROR) {
        printf("bind() error");
        return -1;
    }

	/* Heres where the fun happens ;) */
	unsigned int  optval = 1;
	if(WSAIoctl(lSock,SIO_RCVALL,&optval,sizeof(optval),NULL,0,&lSize,NULL,NULL) == SOCKET_ERROR){
		printf("ERROR!\n");
        return -1;
    }

	return lSock;

}

int main(void){
	char lPacket[1024];
	SOCKET lSock;
	IP *lIP;
	TCP *lTCP;

	// Same as packet. :)
	// Pointer never changes, so we can set it at the begging.
	lIP = (IP*)lPacket;

	// Print Banner.
	printf("  OoOoOoOoOoOoOoOoOoO\n");
	printf("  o HTTP-Sniffer    o\n");
	printf("  O www.1plus.se    O\n");
	printf("  oOoOoOoOoOoOoOoOoOo\n\n");

	LogToFile("  OoOoOoOoOoOoOoOoOoO\n");
	LogToFile("  o HTTP-Sniffer    o\n");
	LogToFile("  O www.1plus.se    O\n");
	LogToFile("  oOoOoOoOoOoOoOoOoOo\n\n");
	SYSTEMTIME lol;
	GetSystemTime(&lol);
	LogToFile("  Started at: %i:%i:%i\n\n",lol.wDay,lol.wMonth,lol.wYear);


	// Init Winsock.
	if(!fInitWinsock()) return -1;

	// Init socket to recieve all packets.
	lSock = fInitSocket();

	// Failed to initialize socket
	if(lSock==-1){
		printf("Failed to initialize socket\n");
		return -1;
	}


	// Main loop
	while(1){
		// NOTE: Usually you should check if RECV is 0. but connection is never closed, so no need!
		int lRecv=recv(lSock,lPacket,1024,0);


		// TCP-Packet.
		if(lIP->protocol==6){
			
			// Get Ip Header Length.
			unsigned short lHeaderLength=lIP->ihl*4;

			// Change TCP-Header pointer to corect address
			lTCP = (TCP*)(lPacket+lHeaderLength);


			// Port 80?
			if(ntohs((unsigned short)lTCP->dest_port)==80){
				// Get data offset.
				unsigned short lDataStart=lTCP->data*4;

				// The data part.
				char *lData = (char*)(lPacket+lHeaderLength+lDataStart);
			
				// End the string :)
				char *lEndPtr = (char*)(lPacket+lRecv);
				*lEndPtr='\0';

				// Dont log SYN/ACK packets
				if(lTCP->flags == 24){
					LogToFile("%s\n",lData);
					printf("%s\n",lData);
				}
			}
		}
	}

}

But in the rar on the website, the file "packet_headers.h" was NOT included :S so I had to recover it myself.... There I have no experience with C++, I'm shure there the mistake is....

packet_headers.h

#pragma once
#pragma comment(lib, "ws2_32.lib")

#ifndef _WIN32_WINNT            // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600     // Change this to the appropriate value to target other versions of Windows.
#endif


typedef struct lIP
{
	unsigned char ihl; // Version and IP Header Length
	unsigned int protocol;
} IP;

typedef struct lTCP
{
	unsigned short flags; //Flags 3 bits and Fragment offset 13 bits
	unsigned short data;
	unsigned long dest_port;
} TCP;

With these files I am capable to make an executable, but it doesn't do what it is supposed to do :S

On line 147 of Sniffer.cpp ther is standing " if(lIP->protocol==6){" This checks if the protocol is TCP, as I need it to be...
Unfortunately, when I print lIP->protocol on the screen it returns 1,2 and 5 but not the needed 6 as it should do when I brows the internet with IE...


Can anyone help me with finding a solution for this lIP->protocol problem, so the correct value is inthere?
The source of "packet_headers.h" Is all "scripted" by me, and not (as far as I know) the original source......
The source of "Sniffer.cpp" is downloaded and should be working perfectly (in combination with "packet_headers.h" ofcourse)


Also I'm working with C++ for 2 days now, so there is a realy big change I made a mistake somewhere!


Thanks in advance,
Jeffrey

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.