#include #include #include #include #define BUFSIZE 8000 #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) #define MAX_ADDR_LEN 16 #define MAX_HOSTNAME_LAN 255 using namespace std; FILE* SniffLog; char dateStr [9]; char timeStr [9]; // IP/TCP header structures struct IPHDR { unsigned char verlen; /*IP version & length */ unsigned char tos; /*IP type of service*/ unsigned short totallength;/*Total length*/ unsigned short id; /*Unique identifier */ unsigned short offset; /*Fragment offset field*/ unsigned char ttl; /*Time to live*/ unsigned char protocol; /*Protocol(TCP, UDP, etc.)*/ unsigned short checksum; /*IP checksum*/ unsigned int srcaddr; /*Source address*/ unsigned int dstaddr; /*Destination address*/ }; struct TCPHDR { unsigned short srcport; unsigned short dstport; unsigned int seqno; unsigned int ackno; unsigned char offset; unsigned char flags; unsigned short window; unsigned short checksum; unsigned short urgptr; }; typedef struct item {i nt weigth; int init; }; item knapsackarray[6]; const long lNAME_SIZE = 1024; // flags void setthem() {f or (int I=0;I < 6; I++) { knapsackarray[I].init = 0; } knapsackarray[0].weigth=256; // Fin knapsackarray[1].weigth=512; // Syn knapsackarray[2].weigth=1024;// Rst knapsackarray[3].weigth=2048;// Psh knapsackarray[4].weigth=4096;// Ack knapsackarray[5].weigth=8192;// Urg knapsackarray[6].weigth=8192;// Urg } // mathematical knapsack algorithm to check which flags are contained within the flags value and string knapsack(int herein) { string retval; int testitem=0; int tempint=0; int I = 5; bool unsolvable=false; testitem = herein; if (testitem == 0) { retval = "000000"; return retval; } while ((testitem != 0) and (I !=-1)) { if ((knapsackarray[I].weigth <= testitem)) { testitem-=knapsackarray[I].weigth; knapsackarray[I].init=1; } if ((testitem != 0) and (I == 0)) { unsolvable = true; } I--; } if (unsolvable == false) {f or (I=0;I < 6;I++) {i f (knapsackarray[I].init == 1) retval+= "1"; else retval+= "0"; } } else retval = "9"; return retval; } const char* flag (int f1) {i f (f1 == 256) return "Fin"; if (f1 == 512) return "Syn"; if (f1 == 1024) return "Rst"; if (f1 == 2048) return "Psh"; if (f1 == 4096) return "Ack"; if (f1 == 8192) return "Urg"; else { char* FlagTable[6] = {"$Fin.","$Syn.","$Rst.","$Psh.","$Ack.","$Urg."}; string mulres,rval; setthem(); mulres = knapsack(f1); for (int i = 0; i < mulres.length(); i++) {i f (mulres[i] == 49) rval += FlagTable[i]; } return rval.c_str(); }r eturn 0; } // these words in FTP context set the flag bool IsFTPPacket(const char *szBuf) { if(strstr(szBuf, "220 ")) return true; if(strstr(szBuf, "230 ")) return true; if(strstr(szBuf, "USER ")) return true; if(strstr(szBuf, "User ")) return true; if(strstr(szBuf, "user ")) return true; if(strstr(szBuf, "PASS ")) return true; if(strstr(szBuf, "Pass ")) return true; if(strstr(szBuf, "pass ")) return true; return false; } // these words in Telnet context set the flag bool IsTelnetPacket(const char *szBuf) { if(strstr(szBuf, "USERNAME")) return true; if(strstr(szBuf, "Username")) return true; if(strstr(szBuf, "username")) return true; if(strstr(szBuf, "PASSWORD")) return true; if(strstr(szBuf, "Password")) return true; if(strstr(szBuf, "password")) return true; return false; } // these words in HTTP context set the flag bool IsHTTPPacket(const char *szBuf) { if(strstr(szBuf, "paypal")) return true; if(strstr(szBuf, "PAYPAL")) return true; if(strstr(szBuf, "ebay")) return true; if(strstr(szBuf, "EBAY")) return true; if(strstr(szBuf, "bank")) return true; if(strstr(szBuf, "BANK")) return true; if(strstr(szBuf, "Bank")) return true; if(strstr(szBuf, "Set-Cookie:")) return true; if(strstr(szBuf, "login")) return true; if(strstr(szBuf, "LOGIN")) return true; if(strstr(szBuf, "Login")) return true; if(strstr(szBuf, "password")) return true; if(strstr(szBuf, "PASSWORD")) return true; if(strstr(szBuf, "Password")) return true; return false; } // these words in any context set the flag bool IsVULNPacket(const char *szBuf) { if(strstr(szBuf, "OpenSSL/0.9.6")) return true; if(strstr(szBuf, "OpenSSH_2")) return true; return false; } void print_data(int datalen, char *data) { int t=0; for(int i=38;i != datalen;i++) { if(data[i] == 13) { fprintf(SniffLog,"\n"); t=0; } if ((int)data[i] > 0) { if ((((int)data[i]) < 33) or (((int)data[i]) > 126)) // print unreadable characters in hexadecimal fprintf(SniffLog,"[%#x]",data[i]); else fprintf(SniffLog,"%c",data[i]); } t++; if(t > 75) { t=0; fprintf(SniffLog,"\n"); } } } void GoSniff() { SOCKET sock; char RecvBuf[65535] = {0}; DWORD dwBytesRet; unsigned int optval = 1; // make a raw socket sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP); // fetch hostname char FAR name[MAX_HOSTNAME_LAN]; gethostname(name, MAX_HOSTNAME_LAN); struct hostent FAR * pHostent; pHostent = (struct hostent * )malloc(sizeof(struct hostent)); pHostent = gethostbyname(name); SOCKADDR_IN sa; sa.sin_family = AF_INET; sa.sin_port = htons(6000); // bind on port 6000 (doesn't really matter) memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); bind(sock, (SOCKADDR *)&sa, sizeof(sa)); // set in promiscuous mode WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL); while (1) { memset(RecvBuf, 0, sizeof(RecvBuf)); recv(sock, RecvBuf, sizeof(RecvBuf), 0); // Filter Packet IPHDR *pIpheader; TCPHDR *pTcpheader; char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN]; SOCKADDR_IN saSource, saDest; pIpheader = (IPHDR *)RecvBuf; pTcpheader = (TCPHDR *)(RecvBuf+ sizeof(IPHDR)); //Check Source IP saSource.sin_addr.s_addr = pIpheader->srcaddr; strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN); //Check Dest IP saDest.sin_addr.s_addr = pIpheader->dstaddr; strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN); // time and data _strdate( dateStr); _strtime( timeStr ); fprintf(SniffLog,"\n************PACKETstart************\n"); fprintf(SniffLog,"Date: %s\n",dateStr); // date fprintf(SniffLog,"Time: %s\n",timeStr); // time fprintf(SniffLog,"Route:%s->%s\n", szSourceIP, szDestIP); // source -> dest fprintf(SniffLog,"TTL=%d\n",pIpheader->ttl); // TTL fprintf(SniffLog,"Flags=%d\n",htons(pTcpheader->flags)); fprintf(SniffLog,"Flags: \n"); fprintf(SniffLog,"%s\n",flag(htons(pTcpheader->flags))); // format flags fprintf(SniffLog,"destport=%d\nsourceport=%d\n", ntohs(pTcpheader- >dstport),ntohs(pTcpheader->srcport)); // ports // is it a suspicious packet? char* szPacket=(char*)(RecvBuf+sizeof(*pTcpheader)+sizeof(*pIpheader)); // format packet if ((IsTelnetPacket(szPacket)) && ((ntohs(pTcpheader->srcport) == 23) || (ntohs(pTcpheader- >dstport) == 23))) fprintf(SniffLog,"Potentially sensitive Telnet traffic sniffed!\n"); if ((IsFTPPacket(szPacket)) && ((ntohs(pTcpheader->srcport) == 21) || (ntohs(pTcpheader- >dstport) == 21))) fprintf(SniffLog,"Potentially sensitive FTP traffic sniffed!\n"); if ((IsHTTPPacket(szPacket)) && ((ntohs(pTcpheader->srcport) == 80) || (ntohs(pTcpheader- >dstport) == 80) || (ntohs(pTcpheader->dstport) == 81) || (ntohs(pTcpheader->dstport) == 443) || (ntohs(pTcpheader->srcport) == 81) || (ntohs(pTcpheader->srcport) == 443))) fprintf(SniffLog,"Potentially sensitive HTTP traffic sniffed!\n"); if (IsVULNPacket(szPacket)) fprintf(SniffLog,"Potentially sensitive vulnerable traffic sniffed!\n"); fprintf(SniffLog,"\n-----------DATAstart---------\n"); print_data(13+(htons(pIpheader->totallength))-sizeof(pIpheader)-sizeof(pTcpheader), RecvBuf); // print packet fprintf(SniffLog,"\n-----------DATAend---------\n"); fprintf(SniffLog,"\n\n***************PACKETend************\n\n"); } closesocket(sock); WSACleanup(); } int main(int argc, char *argv[]) { if (argc < 2) { printf("Aardvark V1.0\n"); printf("Basic promiscuous-mode,outgoing-packet sniffer by Nomenumbra\n"); printf("Usage:\n Aardvark.exe \n"); exit(-1); } WSADATA wsadata; if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0) return -1; SniffLog = fopen(argv[1],"a+"); GoSniff(); fclose(SniffLog); return 0; }-