#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rsniffclnt.h" #include "rasdiag.h" SERVICE_STATUS_HANDLE g_hSs=NULL; SOCKET g_sock; HANDLE g_hTerminateEvent=NULL; #define RSNIFF_SERVICE_NAME TEXT("RSNIFF") #define RSNIFF_DISPLAY_NAME TEXT("RAS REMOTE SNIFF AGENT") #define INSTALL_PATH TEXT("C:\\RSNIFF") BOOL WriteLogEntry(HANDLE hFile, DWORD dwCallID, WCHAR *szClientName, WCHAR *pszTextMsg); BOOL CreateNewService(void); BOOL UninstallService(void); void RSniffServiceMain(DWORD argc, LPTSTR *argv); void BeSniffServer(SOCKET s,PRASDIAGCAPTURE pInterfaces, DWORD dwInterfaces); DWORD WINAPI RSniffSvcHandler(DWORD dwControl,DWORD dwEventType,LPVOID lpEventData,LPVOID lpContext); BOOL SetupListen(SOCKET *ps); BOOL Init(PRASDIAGCAPTURE *ppInterfaces, DWORD *pdwInterfaces, SOCKET *ps); BOOL Init(PRASDIAGCAPTURE *ppInterfaces, DWORD *pdwInterfaces, SOCKET *ps) { PRASDIAGCAPTURE pInterfaces=NULL; DWORD dwInterfaces=0; HRESULT hr; SOCKET s; *ppInterfaces = NULL; *pdwInterfaces = 0; hr = CoInitialize(NULL); if(!SUCCEEDED(hr)) { return FALSE; } // Create a termination event if((g_hTerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) return FALSE; if(InitWinsock() == FALSE) { wprintf(L"could not init winsock\n"); return FALSE; } if(IdentifyInterfaces(&pInterfaces, &dwInterfaces) == FALSE) { wprintf(L"Could not ID interfaces\n"); return FALSE; } if(SetupListen(&s) == FALSE) { wprintf(L"Could not listen!\n"); return FALSE; } *ps = s; *ppInterfaces = pInterfaces; *pdwInterfaces = dwInterfaces; return TRUE; } int __cdecl wmain(int argc, TCHAR **argv) { SERVICE_TABLE_ENTRY ste[] = { RSNIFF_SERVICE_NAME, RSniffServiceMain, NULL, NULL }; if (argc>1) { if(lstrcmpi(argv[1], L"-i") == 0) { wprintf(L"Installing RSNIFF. Result = %s\n", CreateNewService() ? L"Done" : L"Failed!!"); return 0; } if(lstrcmpi(argv[1], L"-u") == 0) { wprintf(L"Uninstalling RSNIFF. Result = %s\n", UninstallService() ? L"Done" : L"Failed!!"); return 0; } if(lstrcmpi(argv[1], L"-?") == 0 || lstrcmpi(argv[1], L"/?") == 0) { wprintf(L"\n" L"------------------------------------------------\n" L"RSNIFF - RAS REMOTE SNIFFING AGENT SERVICE (%d.%d)\n" L"------------------------------------------------\n" L"-i Install RSNIFF service\n" L"-u Uninstall RSNIFF service\n" L"-? This menu\n" L"/? This menu\n" L"------------------------------------------------\n", RASDIAG_MAJOR_VERSION, RASDIAG_MINOR_VERSION ); return 0; } return 0; } if(StartServiceCtrlDispatcher(ste) == FALSE) { return 0; } return 1; } DWORD WINAPI RSniffSvcHandler(DWORD dwControl,DWORD dwEventType,LPVOID lpEventData,LPVOID lpContext) { SERVICE_STATUS ss; switch(dwControl) { case SERVICE_CONTROL_STOP: ss.dwServiceType = SERVICE_WIN32; ss.dwCurrentState = SERVICE_STOP_PENDING; ss.dwControlsAccepted = SERVICE_CONTROL_INTERROGATE; ss.dwWin32ExitCode = 0; ss.dwServiceSpecificExitCode = 0; ss.dwCheckPoint = 1; ss.dwWaitHint = 60*1000; SetServiceStatus(g_hSs, &ss); // // set event that causes service to exit // SetEvent(g_hTerminateEvent); closesocket(g_sock); return NO_ERROR; break; } return ERROR_CALL_NOT_IMPLEMENTED; } void RSniffServiceMain(DWORD argc, LPTSTR *argv) { SERVICE_STATUS_HANDLE hSs; SERVICE_STATUS ss; PRASDIAGCAPTURE pInterfaces=NULL; DWORD dwInterfaces=0; SOCKET s; ZeroMemory(&ss, sizeof(SERVICE_STATUS)); if((g_hSs=hSs=RegisterServiceCtrlHandlerEx(RSNIFF_SERVICE_NAME, RSniffSvcHandler,0)) == 0) return; ss.dwServiceType = SERVICE_WIN32; ss.dwCurrentState = SERVICE_START_PENDING; ss.dwControlsAccepted = SERVICE_ACCEPT_STOP; ss.dwWin32ExitCode = 0; ss.dwServiceSpecificExitCode = 0; ss.dwCheckPoint = 0; ss.dwWaitHint = 0; if(Init(&pInterfaces, &dwInterfaces, &s)==TRUE) { ss.dwCurrentState = SERVICE_RUNNING; SetServiceStatus (hSs, &ss); // // Report start event to eventlog // //MyReportEvent(BEACONMSG_STARTED, EVENTLOG_INFORMATION_TYPE, NULL, 0); // // Execute the service - run until term event is signalled // BeSniffServer(s,pInterfaces,dwInterfaces); // // Unload winsock // WSACleanup(); // // Report halt to event log // //MyReportEvent(BEACONMSG_STOPPED, EVENTLOG_INFORMATION_TYPE, NULL, 0); } else { // // Report the init failure // //MyReportEvent(BEACONMSG_STOPPED, EVENTLOG_INFORMATION_TYPE, NULL, 0); } ss.dwServiceType = SERVICE_WIN32; ss.dwCurrentState = SERVICE_STOPPED; ss.dwControlsAccepted = 0; ss.dwWin32ExitCode = 0; ss.dwServiceSpecificExitCode = 0; ss.dwCheckPoint = 0; ss.dwWaitHint = 0; // // Tell service controller that service is halted. // SetServiceStatus(g_hSs, &ss); //DBGPRINTF(D, TEXT("Beacon service is halting\n")); return; } BOOL SetupListen(SOCKET *ps) { SOCKADDR_IN ServSockAddr = { AF_INET }; SOCKET s; ServSockAddr.sin_port = htons(TCP_SERV_PORT); ServSockAddr.sin_addr.s_addr = INADDR_ANY; ServSockAddr.sin_family = AF_INET; wprintf(L"Create listen socket...\n"); if((g_sock=s=socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { wprintf(L"Create listen socket failed! (%d)", WSAGetLastError()); return FALSE; } // // Bind an address to the socket // wprintf(L"Bind listen socket...\n"); if (bind(s, (const struct sockaddr *) &ServSockAddr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) { wprintf(L"Bind failed...\n"); // // Close the socket // closesocket(s); return FALSE; } // // Attempt to listen // wprintf(L"Listen...\n"); if(listen(s, 1) == SOCKET_ERROR) { wprintf(L"Could not listen...\n"); // // Close the socket // closesocket(s); return FALSE; } *ps = s; return TRUE; } void BeSniffServer(SOCKET s,PRASDIAGCAPTURE pInt, DWORD dwIntCount) { HANDLE hLog; WCHAR szLogFileName[MAX_PATH+1]; SYSTEMTIME st; DWORD dwCallerID=0; GetLocalTime(&st); wsprintf(szLogFileName, L"%s\\%04d%02d%02d%02d%02d-RSNIFFLOG.TXT", INSTALL_PATH, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); hLog = CreateFile(szLogFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0,NULL); if(hLog == INVALID_HANDLE_VALUE) hLog = NULL; WriteLogEntry(hLog, 0, L"RSNIFFSVC", L"Service Started"); while(1) { REMOTECAPTURE rc; REMOTECAPTURE_V5 rc_v5; SOCKADDR_IN PeerSockAddr; SOCKET NewSock=0; BYTE x; int iSize = sizeof(SOCKADDR_IN); DWORD i,dwStatus; SYSTEMTIME st; WCHAR wcRootDir[MAX_PATH+1]; // should always be signalled except when we're going to quit. if(WaitForSingleObject(g_hTerminateEvent, 0) != WAIT_TIMEOUT) { CloseHandle(hLog); return; } wprintf(L"Waiting for connection\n"); if((NewSock = accept(s, (struct sockaddr *) &PeerSockAddr, &iSize)) == INVALID_SOCKET) { wprintf(L"accept() failed\n"); continue; } // Increment the caller count dwCallerID++; GetLocalTime(&st); // Receive least common denominator... if(RecvBuffer(NewSock, (LPBYTE)&rc_v5, sizeof(REMOTECAPTURE_V5)) == FALSE) { wprintf(L"Recv invalid REMOTECAPTURE (rc.dwVer=%d)\n", rc.dwVer); closesocket(NewSock); continue; } // Convert v5 -> v7 structure if(rc_v5.dwVer == sizeof(REMOTECAPTURE_V5)) { REMOTECAPTURE rc_new; PREMOTECAPTURE_V5 pRc5=(PREMOTECAPTURE_V5)&rc_v5; ZeroMemory(&rc_new, sizeof(REMOTECAPTURE)); rc_new.dwVer = sizeof(REMOTECAPTURE); mbstowcs(rc_new.szMachine, pRc5->szMachine, lstrlenA(pRc5->szMachine)+1); WriteLogEntry(hLog, dwCallerID, rc_new.szMachine, L"Version 5 client"); // All pre v7 clients will want to do sniff. rc_new.dwOpt1 = RSNIFF_OPT1_DOSNIFF; memcpy(&rc,&rc_new,sizeof(REMOTECAPTURE)); } else // Convert v6 -> v7 structure if(rc_v5.dwVer == sizeof(REMOTECAPTURE_V6)) { REMOTECAPTURE rc_new; PREMOTECAPTURE_V5 pRc5=(PREMOTECAPTURE_V5)&rc_v5; // copy portion of struct received. memcpy(&rc_new, pRc5, sizeof(REMOTECAPTURE_V5)); WriteLogEntry(hLog, dwCallerID, rc_new.szMachine, L"Version 6 client"); // Receive the remaining part of the v6 structure... if(RecvBuffer(NewSock, (LPBYTE)&rc_new + sizeof(REMOTECAPTURE_V5), (sizeof(REMOTECAPTURE_V6) - sizeof(REMOTECAPTURE_V5))) == FALSE) { WriteLogEntry(hLog, dwCallerID, rc_new.szMachine, L"Recv err!"); wprintf(L"Recv invalid REMOTECAPTURE (rc.dwVer=%d)\n", rc.dwVer); closesocket(NewSock); continue; } // Covert structure (since copied from V6, just change version number rc_new.dwVer = sizeof(REMOTECAPTURE); // All pre v7 clients will want to do sniff. rc_new.dwOpt1 = RSNIFF_OPT1_DOSNIFF; // copy structure memcpy(&rc,&rc_new,sizeof(REMOTECAPTURE)); } else if(rc_v5.dwVer == sizeof(REMOTECAPTURE)) { REMOTECAPTURE rc_new; PREMOTECAPTURE_V5 pRc5=(PREMOTECAPTURE_V5)&rc_v5; // copy portion of struct received. memcpy(&rc_new, pRc5, sizeof(REMOTECAPTURE_V5)); WriteLogEntry(hLog, dwCallerID, rc_new.szMachine, L"Version 7 client"); // Receive the remaining part of the v6 structure... if(RecvBuffer(NewSock, (LPBYTE)&rc_new + sizeof(REMOTECAPTURE_V5), (sizeof(REMOTECAPTURE) - sizeof(REMOTECAPTURE_V5))) == FALSE) { WriteLogEntry(hLog, dwCallerID, rc_new.szMachine, L"Recv err!"); wprintf(L"Recv invalid REMOTECAPTURE (rc.dwVer=%d)\n", rc.dwVer); closesocket(NewSock); continue; } // valid v7 structure - read remaining bytes; no conversion necessary // copy structure memcpy(&rc,&rc_new,sizeof(REMOTECAPTURE)); } else { // no idea what this is... WriteLogEntry(hLog, dwCallerID, L"UNKNOWN CLIENT!", NULL); wprintf(L"Recv invalid REMOTECAPTURE version (rc.dwVer=%d)\n", rc.dwVer); closesocket(NewSock); continue; } wsprintf(wcRootDir, L"%s\\%04d%02d%02d%02d%02d%02d-%s-SID_%03d", INSTALL_PATH, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, rc.szMachine, dwCallerID); CreateDirectory(wcRootDir,NULL); if(rc.dwOpt1 & RSNIFF_OPT1_DOSNIFF) { WriteLogEntry(hLog, dwCallerID, rc.szMachine, L"Request for local network sniff"); wprintf(L"Sniffing traffic for caller: %s\n", rc.szMachine); // start sniffing for(i=0;iStart(szCaptureFile); if(dwStatus != NMERR_SUCCESS) { wprintf(L"pIDelaydC->Start() FAILED! Start rtn %x\n", dwStatus); pInt[i].pIDelaydC->Disconnect(); } else { // convert mbs to wide mbstowcs(pInt[i].szCaptureFileName, szCaptureFile, lstrlenA(szCaptureFile)+1); } } } else { wprintf(L"InitIDelaydC() failed\n"); } } } // Get pre-connect routing table info if(rc.dwOpt1 & RSNIFF_OPT1_GETSRVROUTINGINFO) { WCHAR szRoutingInfo[MAX_PATH+1]; WriteLogEntry(hLog, dwCallerID, rc.szMachine, L"Request for local routing table"); wsprintf(szRoutingInfo, L"route print > %s\\ROUTINGINFO.TXT", wcRootDir); _wsystem(szRoutingInfo); wsprintf(szRoutingInfo, L"ipconfig >> %s\\ROUTINGINFO.TXT", wcRootDir); _wsystem(szRoutingInfo); } // wait until remote closes socket RecvBuffer(NewSock, (LPBYTE)&x, 1); closesocket(NewSock); // Get the routing table info if(rc.dwOpt1 & RSNIFF_OPT1_GETSRVROUTINGINFO) { WCHAR szRoutingInfo[MAX_PATH+1]; wsprintf(szRoutingInfo, L"route print >> %s\\ROUTINGINFO.TXT", wcRootDir); _wsystem(szRoutingInfo); wsprintf(szRoutingInfo, L"ipconfig >> %s\\ROUTINGINFO.TXT", wcRootDir); _wsystem(szRoutingInfo); } if(rc.dwOpt1 & RSNIFF_OPT1_DOSNIFF) { wprintf(L"Sniffing complete\n"); // Stop sniffing... for(i=0;iStop(&pInt[i].stats); if(dwStatus != NMERR_SUCCESS) { wprintf(L"pIDelaydC->Stop() rtn %x\n", dwStatus); pInt[i].pIDelaydC->Disconnect(); } if(pInt[i].stats.TotalBytesCaptured) { WCHAR szNewFileName[MAX_PATH+1]; WCHAR *pChar=NULL; WCHAR *pFn=NULL; pFn = pInt[i].szCaptureFileName + lstrlenW(pInt[i].szCaptureFileName) + 1; // Get the filename while(*pFn != '\\' && pFn!=pInt[i].szCaptureFileName) pFn--; pFn++; wprintf(L"%d LAN bytes captured (%s)\n", pInt[i].stats.TotalBytesCaptured, pInt[i].szCaptureFileName); wsprintf(szNewFileName,L"%s\\%s__%s_SID_%d.CAP", wcRootDir, pFn, rc.szMachine, dwCallerID); if((pChar=wcsstr(szNewFileName, L".")) != NULL) { *pChar='_'; } wprintf(L"Saving %s\n", szNewFileName); MoveFile(pInt[i].szCaptureFileName, szNewFileName); } else { wprintf(L"%d bytes captured (%s)\n", pInt[i].stats.TotalBytesCaptured, pInt[i].szCaptureFileName); } // Disconnect if(pInt[i].pIDelaydC) { pInt[i].pIDelaydC->Disconnect(); } } WriteLogEntry(hLog, dwCallerID, rc.szMachine, L"Client processing complete."); wprintf(L"Sniffing complete\n"); } } } void Listen(PRASDIAGCAPTURE pInt, DWORD dwIntCount) { SOCKADDR_IN ServSockAddr = { AF_INET }; SOCKET s; ServSockAddr.sin_port = htons(TCP_SERV_PORT); ServSockAddr.sin_addr.s_addr = INADDR_ANY; ServSockAddr.sin_family = AF_INET; wprintf(L"Create listen socket...\n"); if((s=socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { wprintf(L"Create listen socket failed! (%d)", WSAGetLastError()); } // // Bind an address to the socket // wprintf(L"Bind listen socket...\n"); if (bind(s, (const struct sockaddr *) &ServSockAddr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) { wprintf(L"Bind failed...\n"); // // Close the socket // closesocket(s); return; } // // Attempt to listen // wprintf(L"Listen...\n"); if(listen(s, 1) == SOCKET_ERROR) { wprintf(L"Could not listen...\n"); // // Close the socket // closesocket(s); return; } while(1) { REMOTECAPTURE rc; SOCKADDR_IN PeerSockAddr; SOCKET NewSock=0; BYTE x; int iSize = sizeof(SOCKADDR_IN); DWORD i,dwStatus; wprintf(L"Waiting for connection\n"); if((NewSock = accept(s, (struct sockaddr *) &PeerSockAddr, &iSize)) == INVALID_SOCKET) { wprintf(L"accept() failed\n"); continue; } if(RecvBuffer(NewSock, (LPBYTE)&rc, sizeof(REMOTECAPTURE)) == FALSE) { wprintf(L"Recv invalid REMOTECAPTURE (rc.dwVer=%d)\n", rc.dwVer); closesocket(NewSock); continue; } wprintf(L"Sniffing traffic for caller: %s\n", rc.szMachine); // start sniffing for(i=0;iStart(szCaptureName); if(dwStatus != NMERR_SUCCESS) { wprintf(L"pIDelaydC->Start() FAILED! Start rtn %x\n", dwStatus); pInt[i].pIDelaydC->Disconnect(); } else { mbstowcs(pInt[i].szCaptureFileName, szCaptureName, lstrlenA(szCaptureName)+1); } } } else { wprintf(L"InitIDelaydC() failed\n"); } } // wait until remote closes socket RecvBuffer(NewSock, (LPBYTE)&x, 1); closesocket(NewSock); wprintf(L"Sniffing complete\n"); // Stop sniffing... for(i=0;iStop(&pInt[i].stats); if(dwStatus != NMERR_SUCCESS) { wprintf(L"pIDelaydC->Stop() rtn %x\n", dwStatus); pInt[i].pIDelaydC->Disconnect(); } if(pInt[i].stats.TotalBytesCaptured) { WCHAR szNewFileName[MAX_PATH+1]; WCHAR *pChar=NULL; wprintf(L"%d LAN bytes captured (%s)\n", pInt[i].stats.TotalBytesCaptured, pInt[i].szCaptureFileName); wsprintf(szNewFileName, L"%s__%s.CAP", pInt[i].szCaptureFileName, rc.szMachine); if((pChar=wcsstr(szNewFileName, L".")) != NULL) { *pChar='_'; } wprintf(L"Saving %s\n", szNewFileName); MoveFile(pInt[i].szCaptureFileName, szNewFileName); } else { wprintf(L"%d bytes captured (%s)\n", pInt[i].stats.TotalBytesCaptured, pInt[i].szCaptureFileName); } // Disconnect if(pInt[i].pIDelaydC) { pInt[i].pIDelaydC->Disconnect(); } } wprintf(L"Sniffing complete\n"); } } BOOL IdentifyInterfaces(PRASDIAGCAPTURE *hLAN, DWORD *pdwLanCount) { DWORD dwStatus; HBLOB hBlob; BLOB_TABLE *pTable=NULL; DWORD i; BOOL bRas=FALSE; DWORD dwLanCount=0; PRASDIAGCAPTURE hLanAr=NULL; *hLAN = NULL; *pdwLanCount = 0; if((hLanAr = (PRASDIAGCAPTURE)LocalAlloc(LMEM_ZEROINIT, sizeof(RASDIAGCAPTURE) * MAX_LAN_CAPTURE_COUNT)) == NULL) return FALSE; wprintf(L"Identifying Network Interfaces\n"); // Create blob for blob table dwStatus = CreateBlob(&hBlob); if(dwStatus != NMERR_SUCCESS) { wprintf(L"Blob not created!\n"); return FALSE; } // Get the blob table dwStatus = GetNPPBlobTable(hBlob, &pTable); if(dwStatus != NMERR_SUCCESS) { wprintf(L"GetNPPBlobTable failed (%d)!\n",dwStatus); DestroyBlob(hBlob); return FALSE; } wprintf(L"Interface Count: %d\n",pTable->dwNumBlobs); for(i=0;idwNumBlobs && (dwLanCount < MAX_LAN_CAPTURE_COUNT);i++) { NETWORKINFO ni; dwStatus = GetNetworkInfoFromBlob(pTable->hBlobs[i], &ni); if(dwStatus == NMERR_SUCCESS) { wprintf(L"----------------------------------------\n"); wprintf(L"%d. LinkSpeed: %d (%d)\n", i,ni.LinkSpeed, ni.MacType ); if(NMERR_SUCCESS != GetBoolFromBlob( pTable->hBlobs[i], OWNER_NPP, CATEGORY_LOCATION, //CATEGORY_NETWORKINFO, TAG_RAS, &bRas)) { DestroyBlob(hBlob); return FALSE; } if(bRas) { wprintf(L"Interface %d: %s\n", i, TAG_RAS); hLanAr[dwLanCount].hBlob=pTable->hBlobs[i]; hLanAr[dwLanCount++].bWan=TRUE; } else { const char *pString=NULL; if(GetStringFromBlob(pTable->hBlobs[i], OWNER_NPP, CATEGORY_LOCATION, TAG_MACADDRESS, &pString) == NMERR_SUCCESS) { //wprintf(L"Interface %d: %s (MAC: %s)\n", i, "LAN", pString); } else { //wprintf(L"Interface %d: %s (UNKNOWN)\n", i, "LAN"); } // use this interface only if the mac type // is one of the following: if(ni.MacType == MAC_TYPE_ETHERNET || ni.MacType == MAC_TYPE_TOKENRING || ni.MacType == MAC_TYPE_ATM) if(pString) { if((hLanAr[dwLanCount].pszMacAddr = (WCHAR*)LocalAlloc(LMEM_ZEROINIT, sizeof(WCHAR) * (lstrlenA(pString) + 1))) != NULL) mbstowcs(hLanAr[dwLanCount].pszMacAddr, pString, lstrlenA(pString)); } hLanAr[dwLanCount++].hBlob = pTable->hBlobs[i]; } } else { wprintf(L"GetNetworkInfoFromBlob rtn %d\n", dwStatus); DestroyBlob(hBlob); return FALSE; } } wprintf(L"----------------------------------------\n"); DestroyBlob(hBlob); if(dwLanCount) { *pdwLanCount = dwLanCount; *hLAN = hLanAr; } return TRUE; } BOOL InitWinsock(void) { WSADATA WSAData; WORD WSAVerReq = MAKEWORD(2,0); if (WSAStartup(WSAVerReq, &WSAData)) { return FALSE; } else return TRUE; } PSOCKCB TcpConnectRoutine(LPSTR pAddr) { SOCKADDR_IN DstAddrIP = { AF_INET }; HOSTENT *pHost; ULONG uAddr; PSOCKCB pSock; BOOL bResult; ULONG ulHostAddr=0; // // Resolve name // if ((ulHostAddr = inet_addr(pAddr)) == -1L) { return NULL; } uAddr = ntohl(ulHostAddr); wprintf(L"Connecting to remote server sniffing agent (ADDR: %d.%d.%d.%d)\n", ((struct in_addr *) &uAddr)->S_un.S_un_b.s_b4, ((struct in_addr *) &uAddr)->S_un.S_un_b.s_b3, ((struct in_addr *) &uAddr)->S_un.S_un_b.s_b2, ((struct in_addr *) &uAddr)->S_un.S_un_b.s_b1); DstAddrIP.sin_port = htons(TCP_SERV_PORT); DstAddrIP.sin_addr.s_addr = htonl(uAddr); // // Create socket // pSock = CreateSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(pSock == NULL) return NULL; // // Connect the socket // if(ConnectSock(pSock, (struct sockaddr *)&DstAddrIP, sizeof(SOCKADDR_IN)) != TRUE) { wprintf(L"Could not connect to remote server sniffing agent!\n"); closesocket(pSock->s); LocalFree(pSock); return NULL; } return pSock; } BOOL ConnectSock(PSOCKCB pSock, SOCKADDR* pDstAddr, int size) { int err; // // Connect the socket // err = connect(pSock->s, pDstAddr, size); if(err==SOCKET_ERROR) { return FALSE; } return TRUE; } PSOCKCB CreateSocket(int Af, int Type, int Proto) { PSOCKCB pSock; if((pSock = (PSOCKCB)LocalAlloc(LMEM_ZEROINIT, sizeof(SOCKCB))) == NULL) return NULL; // // Create a socket // if((pSock->s = socket(Af, Type, Proto)) == INVALID_SOCKET) { LocalFree(pSock); return NULL; } return pSock; } BOOL SendStartSniffPacket(PSOCKCB pSock) { REMOTECAPTURE rc; DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1; ZeroMemory(&rc, sizeof(REMOTECAPTURE)); rc.dwVer = sizeof(REMOTECAPTURE); GetComputerName(rc.szMachine, &dwSize); return SendBuffer(pSock->s, (LPBYTE)&rc, sizeof(REMOTECAPTURE)); } BOOL SendBuffer(SOCKET s, LPBYTE pBuffer, ULONG uSize) { ULONG err,uSent, uBytesSent=0; while(uBytesSent != uSize) { uSent = send(s, (const char *)(pBuffer+uBytesSent), uSize-uBytesSent, 0); switch(uSent) { case SOCKET_ERROR: err = WSAGetLastError(); return FALSE; break; case 0: return FALSE; default: uBytesSent+=uSent; break; } } return TRUE; } BOOL RecvBuffer(SOCKET s, LPBYTE pBuffer, ULONG uSize) { ULONG err=0,uRecv=0, uBytesRecv=0; while(uBytesRecv != uSize) { wprintf(L"Recv...\n"); uRecv = recv(s, (char *)pBuffer+uBytesRecv, uSize-uBytesRecv, 0); switch(uRecv) { case SOCKET_ERROR: err=WSAGetLastError(); wprintf(L"err=%d\n",err); return FALSE; break; case 0: wprintf(L"Socket gracefully closed by peer\n"); return FALSE; default: uBytesRecv += uRecv; wprintf(L"rtn %d bytes recv\n", uBytesRecv); break; } } wprintf(L"RecvBuffer complete\n"); return TRUE; } BOOL InitIDelaydC(HBLOB hBlob, IDelaydC **ppIDelaydC) { DWORD dwStatus; const char *sterrLSID; IDelaydC *pIDelaydC=NULL; wprintf(L"hBlob: %p\n", hBlob); if(NMERR_SUCCESS != GetStringFromBlob(hBlob,OWNER_NPP,CATEGORY_LOCATION,TAG_CLASSID,&sterrLSID)) { wprintf(L"GetStringFromBlob failed\n"); return FALSE; } wprintf(L"ClassID: %s\n",sterrLSID); dwStatus = CreateNPPInterface(hBlob,IID_IDelaydC,(void**)&pIDelaydC); if(dwStatus != NMERR_SUCCESS) { wprintf(L"CreateNPPInterface rtn %x (%p)\n", dwStatus, pIDelaydC); return FALSE; } dwStatus = pIDelaydC->Connect(hBlob,NULL,NULL,NULL); if(dwStatus != NMERR_SUCCESS) { wprintf(L"Connect rtn %x\n", dwStatus); return FALSE; } *ppIDelaydC = pIDelaydC; return TRUE; } BOOL CreateNewService(void) { SC_HANDLE schService, schSCManager; WCHAR szPath[MAX_PATH+1]; LPCTSTR lpszBinaryPathName = szPath; wsprintf(szPath, L"%s\\RSNIFF.EXE", INSTALL_PATH); if((schSCManager= OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE)) == NULL) return FALSE; if((schService = CreateService( schSCManager, // SCManager database RSNIFF_SERVICE_NAME, // name of service RSNIFF_DISPLAY_NAME, // service name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type lpszBinaryPathName, // service's binary NULL, // no load ordering group NULL, // no tag identifier NULL, // no dependencies NULL, // LocalSystem account NULL)) // no password == NULL) { WCHAR szErrTxt[MAX_PATH+1]; wsprintf(szErrTxt, L"Could not install Beacon service. Err=%d", GetLastError()); wprintf(L"%s\n", szErrTxt); CloseServiceHandle(schSCManager); return FALSE; } CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return TRUE; } BOOL UninstallService(void) { SC_HANDLE schService, schSCManager; if((schSCManager=OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE)) == NULL) return FALSE; if((schService = OpenService(schSCManager,RSNIFF_SERVICE_NAME, SERVICE_ALL_ACCESS)) == NULL) { WCHAR szErrTxt[MAX_PATH+1]; wsprintf(szErrTxt, L"Could not uninstall Beacon service. Err=%d", GetLastError()); wprintf(L"%s\n", szErrTxt); CloseServiceHandle(schSCManager); return FALSE; } DeleteService(schService); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return TRUE; } BOOL WriteLogEntry(HANDLE hFile, DWORD dwCallID, WCHAR *szClientName, WCHAR *pszTextMsg) { WCHAR *pBuff; SYSTEMTIME st; DWORD dwBytesWritten; if(hFile == NULL) return FALSE; if(pszTextMsg) pBuff = new WCHAR[(MAX_COMPUTERNAME_LENGTH + lstrlenW(pszTextMsg) + 1 + 100)]; else pBuff = new WCHAR[(MAX_COMPUTERNAME_LENGTH + 1 + 100)]; // no text msg // got buffer? if(pBuff == NULL) return FALSE; GetLocalTime(&st); wsprintf(pBuff, L"%04d%02d%02d%02d%02d%02d %05d %-15.15s %s\r\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, dwCallID, szClientName, pszTextMsg ? pszTextMsg : L""); return WriteFile(hFile, pBuff, lstrlenW(pBuff) * sizeof(WCHAR), &dwBytesWritten, NULL); }