/*
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);
}
}
}
}
}