Пример #1
0
void *TrainingLoop(void *ptr)
{
	MaskKillSignals();

	//Training Loop
	do
	{
		sleep(Config::Inst()->GetClassificationTimeout());

		// Get list of Suspects that need a classification and feature update
		vector<uint64_t> updateKeys = suspects.GetKeys_of_ModifiedSuspects();
		suspects.UpdateAllSuspects();
		for(uint i = 0; i < updateKeys.size(); i++)
		{
			UpdateAndStore(updateKeys[i]);
		}
	} while(Config::Inst()->GetClassificationTimeout());

	//Shouldn't get here!
	if(Config::Inst()->GetClassificationTimeout())
	{
		LOG(CRITICAL, "The code should never get here, something went very wrong.", "");
	}
	return NULL;
}
Пример #2
0
void *ClassificationLoop(void *ptr)
{
	MaskKillSignals();

	//Builds the Silent Alarm Network address
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(Config::Inst()->GetSaPort());

	//Classification Loop
	do
	{
		sleep(Config::Inst()->GetClassificationTimeout());
		CheckForDroppedPackets();

		//Calculate the "true" Feature Set for each Suspect
		vector<uint64_t> updateKeys = suspects.GetKeys_of_ModifiedSuspects();
		for(uint i = 0; i < updateKeys.size(); i++)
		{
			UpdateAndClassify(updateKeys[i]);
		}
		engine->m_dopp->UpdateDoppelganger();

		if(Config::Inst()->GetSaveFreq() > 0)
		{
			if((time(NULL) - lastSaveTime) > Config::Inst()->GetSaveFreq())
			{
				AppendToStateFile();
			}
		}

		if(Config::Inst()->GetDataTTL() > 0)
		{
			if((time(NULL) - lastLoadTime) > Config::Inst()->GetDataTTL())
			{
				AppendToStateFile();
				suspects.EraseAllSuspects();
				RefreshStateFile();
				LoadStateFile();
			}
		}
	}while(Config::Inst()->GetClassificationTimeout() && !Config::Inst()->GetReadPcap());

	if(Config::Inst()->GetReadPcap())
	{
		return NULL;
	}

	//Shouldn't get here!!
	if(Config::Inst()->GetClassificationTimeout())
	{
		LOG(CRITICAL, "The code should never get here, something went very wrong.", "");
	}

	return NULL;
}
Пример #3
0
void *ClassificationLoop(void *ptr)
{
	MaskKillSignals();

	//Classification Loop
	do
	{
		struct timespec timespec;
		struct timeval timeval;
		gettimeofday(&timeval, NULL);
		timespec.tv_sec  = timeval.tv_sec;
		timespec.tv_nsec = timeval.tv_usec*1000;
		timespec.tv_sec += Config::Inst()->GetClassificationTimeout();

		{
			//Protection for the queue structure
			Lock lock(&shutdownClassificationMutex);

			//While loop to protect against spurious wakeups
			while(!shutdownClassification)
			{
				if(pthread_cond_timedwait(&shutdownClassificationCond, &shutdownClassificationMutex, &timespec) == ETIMEDOUT)
				{
					break;
				}
			}
			if(shutdownClassification)
			{
				return NULL;
			}
		}

		CheckForDroppedPackets();

		Database::Inst()->m_count = 0;
		suspects.WriteToDatabase();
		doppel->UpdateDoppelganger();

	}while(Config::Inst()->GetClassificationTimeout() && !Config::Inst()->GetReadPcap());

	if(Config::Inst()->GetReadPcap())
	{
		return NULL;
	}

	//Shouldn't get here!!
	if(Config::Inst()->GetClassificationTimeout())
	{
		LOG(CRITICAL, "The code should never get here, something went very wrong.", "");
	}

	return NULL;
}
Пример #4
0
void *UpdateWhitelistIPFilter(void *ptr)
{
	MaskKillSignals();

	while(true)
	{
		if(whitelistWatch > 0)
		{
			int BUF_LEN = (1024 * (sizeof(struct inotify_event)) + 16);
			char buf[BUF_LEN];

			// Blocking call, only moves on when the kernel notifies it that file has been changed
			int readLen = read(whitelistNotifyFd, buf, BUF_LEN);
			if(readLen > 0)
			{
				whitelistWatch = inotify_add_watch(whitelistNotifyFd, Config::Inst()->GetPathWhitelistFile().c_str(),
						IN_CLOSE_WRITE | IN_MOVED_TO | IN_MODIFY | IN_DELETE);
				whitelistIpAddresses = WhitelistConfiguration::GetIps();
				whitelistIpRanges = WhitelistConfiguration::GetIpRanges();

				{
					Lock lock(&packetCapturesLock);
					for(uint i = 0; i < packetCaptures.size(); i++)
					{
						try
						{
							string captureFilterString = ConstructFilterString(packetCaptures.at(i)->GetIdentifier());
							packetCaptures.at(i)->SetFilter(captureFilterString);
						}
						catch (Nova::PacketCaptureException &e)
						{
							LOG(ERROR, string("Unable to update capture filter: ") + e.what(), "");
						}
					}
				}
			}
		}
		else
		{
			// This is the case when there's no file to watch, just sleep and wait for it to
			// be created by honeyd when it starts up.
			sleep(3);
			whitelistWatch = inotify_add_watch(whitelistNotifyFd, Config::Inst()->GetPathWhitelistFile().c_str(),
					IN_CLOSE_WRITE | IN_MOVED_TO | IN_MODIFY | IN_DELETE);
		}
	}

	return NULL;
}
Пример #5
0
void *UpdateWhitelistIPFilter(void *ptr)
{
	MaskKillSignals();

	while(true)
	{
		if(whitelistWatch > 0)
		{
			int BUF_LEN = (1024 *(sizeof(struct inotify_event)) + 16);
			char buf[BUF_LEN];
			struct bpf_program fp;
			char filter_exp[64];
			char errbuf[PCAP_ERRBUF_SIZE];

			bpf_u_int32 maskp;
			bpf_u_int32 netp;

			// Blocking call, only moves on when the kernel notifies it that file has been changed
			int readLen = read(whitelistNotifyFd, buf, BUF_LEN);
			if(readLen > 0)
			{
				whitelistWatch = inotify_add_watch(whitelistNotifyFd, Config::Inst()->GetPathWhitelistFile().c_str(),
						IN_CLOSE_WRITE | IN_MOVED_TO | IN_MODIFY | IN_DELETE);
				whitelistIpAddresses = WhitelistConfiguration::GetIps();
				whitelistIpRanges = WhitelistConfiguration::GetIpRanges();
				string filterString = ConstructFilterString();
				for(uint i = 0; i < handles.size(); i++)
				{

					/* ask pcap for the network address and mask of the device */
					int ret = pcap_lookupnet(Config::Inst()->GetInterface(i).c_str(), &netp, &maskp, errbuf);
					if(ret == -1)
					{
						LOG(ERROR, "Unable to start packet capture.",
							"Unable to get the network address and mask: "+string(strerror(errno)));
						exit(EXIT_FAILURE);
					}

					if(pcap_compile(handles[i], &fp, filterString.data(), 0, maskp) == -1)
					{
						LOG(ERROR, "Unable to enable packet capture.",
							"Couldn't parse pcap filter: "+ string(filter_exp) + " " + pcap_geterr(handles[i]));
					}
					if(pcap_setfilter(handles[i], &fp) == -1)
					{
						LOG(ERROR, "Unable to enable packet capture.",
							"Couldn't install pcap filter: "+ string(filter_exp) + " " + pcap_geterr(handles[i]));
					}
					pcap_freecode(&fp);

					// Clear any suspects that were whitelisted from the GUIs
					for(uint i = 0; i < whitelistIpAddresses.size(); i++)
					{
					if(suspects.Erase(inet_addr(whitelistIpAddresses.at(i).c_str())))
					{
						UpdateMessage *msg = new UpdateMessage(UPDATE_SUSPECT_CLEARED, DIRECTION_TO_UI);
						msg->m_IPAddress = inet_addr(whitelistIpAddresses.at(i).c_str());
						NotifyUIs(msg,UPDATE_SUSPECT_CLEARED_ACK, -1);
					}
				}

				}

				/*
				// TODO: Should we clear IP range whitelisted suspects? Could be a huge number of clears...
				// This doesn't work yet.
				for(uint i = 0; i < whitelistIpRanges.size(); i++)
				{
					uint32_t ip = htonl(inet_addr(WhitelistConfiguration::GetIp(whitelistIpRanges.at(i)).c_str()));

					string netmask = WhitelistConfiguration::GetSubnet(whitelistIpRanges.at(i));
					uint32_t mask;
					if(netmask != "")
					{
						mask = htonl(inet_addr(netmask.c_str()));
					}

					while(mask != ~0)
					{
						if(suspects.Erase(ip))
						{
							UpdateMessage *msg = new UpdateMessage(UPDATE_SUSPECT_CLEARED, DIRECTION_TO_UI);
							msg->m_IPAddress = ip;
							NotifyUIs(msg,UPDATE_SUSPECT_CLEARED_ACK, -1);

						}

						in_addr foo;
						foo.s_addr = ntohl(ip);

						ip++;
						mask++;
					}

				}
				*/
			}
		}
		else
		{
			// This is the case when there's no file to watch, just sleep and wait for it to
			// be created by honeyd when it starts up.
			sleep(3);
			whitelistWatch = inotify_add_watch(whitelistNotifyFd, Config::Inst()->GetPathWhitelistFile().c_str(),
					IN_CLOSE_WRITE | IN_MOVED_TO | IN_MODIFY | IN_DELETE);
		}
	}

	return NULL;
}
Пример #6
0
void *UpdateIPFilter(void *ptr)
{
	MaskKillSignals();

	while(true)
	{
		if(honeydDHCPWatch > 0)
		{
			int BUF_LEN = (1024 *(sizeof(struct inotify_event)) + 16);
			char buf[BUF_LEN];
			char errbuf[PCAP_ERRBUF_SIZE];
			char filter_exp[64];
			struct bpf_program *fp = new struct bpf_program();

			bpf_u_int32 maskp;
			bpf_u_int32 netp;

			// Blocking call, only moves on when the kernel notifies it that file has been changed
			int readLen = read(honeydDHCPNotifyFd, buf, BUF_LEN);
			if(readLen > 0)
			{
				honeydDHCPWatch = inotify_add_watch(honeydDHCPNotifyFd, dhcpListFile.c_str(),
						IN_CLOSE_WRITE | IN_MOVED_TO | IN_MODIFY | IN_DELETE);
				haystackDhcpAddresses = Config::GetIpAddresses(dhcpListFile);
				string haystackAddresses_csv = ConstructFilterString();

				UpdateHaystackFeatures();

				for(uint i = 0; i < handles.size(); i++)
				{
					// ask pcap for the network address and mask of the device
					int ret = pcap_lookupnet(Config::Inst()->GetInterface(i).c_str(), &netp, &maskp, errbuf);
					if(ret == -1)
					{
						LOG(ERROR, "Unable to start packet capture.",
							"Unable to get the network address and mask: "+string(strerror(errno)));
						exit(EXIT_FAILURE);
					}

					if(pcap_compile(handles[i], fp, haystackAddresses_csv.data(), 0, maskp) == -1)
					{
						LOG(ERROR, "Unable to enable packet capture.",
							"Couldn't parse pcap filter: "+ string(filter_exp) + " " + pcap_geterr(handles[i]));
					}
					if(pcap_setfilter(handles[i], fp) == -1)
					{
						LOG(ERROR, "Unable to enable packet capture.",
							"Couldn't install pcap filter: "+ string(filter_exp) + " " + pcap_geterr(handles[i]));
					}
					//Free the compiled filter program after assignment, it is no longer needed after set filter
					pcap_freecode(fp);
				}
			}
			delete fp;
		}
		else
		{
			// This is the case when there's no file to watch, just sleep and wait for it to
			// be created by honeyd when it starts up.
			sleep(2);
			honeydDHCPWatch = inotify_add_watch(honeydDHCPNotifyFd, dhcpListFile.c_str(),
					IN_CLOSE_WRITE | IN_MOVED_TO | IN_MODIFY | IN_DELETE);
		}
	}
	return NULL;
}
Пример #7
0
void *SilentAlarmLoop(void *ptr)
{
	MaskKillSignals();

	int sockfd;
	u_char buf[MAX_MSG_SIZE];
	struct sockaddr_in sendaddr;

	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		LOG(CRITICAL, "Unable to create the silent alarm socket.",
				"Unable to create the silent alarm socket: "+string(strerror(errno)));
		close(sockfd);
		exit(EXIT_FAILURE);
	}

	sendaddr.sin_family = AF_INET;
	sendaddr.sin_port = htons(Config::Inst()->GetSaPort());
	sendaddr.sin_addr.s_addr = INADDR_ANY;

	memset(sendaddr.sin_zero, '\0', sizeof sendaddr.sin_zero);
	struct sockaddr *sockaddrPtr = (struct sockaddr*) &sendaddr;
	socklen_t sendaddrSize = sizeof sendaddr;

	if(::bind(sockfd, sockaddrPtr, sendaddrSize) == -1)
	{
		LOG(CRITICAL, "Unable to bind to the silent alarm socket.",
			"Unable to bind to the silent alarm socket: "+string(strerror(errno)));
		close(sockfd);
		exit(EXIT_FAILURE);
	}

	stringstream ss;
	ss << "sudo iptables -A INPUT -p udp --dport "
			<< Config::Inst()->GetSaPort() << " -j REJECT"
					" --reject-with icmp-port-unreachable";
	if(system(ss.str().c_str()) == -1)
	{
		LOG(ERROR, "Failed to update iptables.", "");
	}
	ss.str("");
	ss << "sudo iptables -A INPUT -p tcp --dport "
			<< Config::Inst()->GetSaPort()
			<< " -j REJECT --reject-with tcp-reset";
	if(system(ss.str().c_str()) == -1)
	{
		LOG(ERROR, "Failed to update iptables.", "");
	}

	if(listen(sockfd, SOCKET_QUEUE_SIZE) == -1)
	{
		LOG(CRITICAL, "Unable to listen on the silent alarm socket.",
			"Unable to listen on the silent alarm socket.: "+string(strerror(errno)));
		close(sockfd);
		exit(EXIT_FAILURE);
	}

	int connectionSocket, bytesRead;
	Suspect suspectCopy;

	//Accept incoming Silent Alarm TCP Connections
	while(1)
	{

		bzero(buf, MAX_MSG_SIZE);

		//Blocking call
		if((connectionSocket = accept(sockfd, sockaddrPtr, &sendaddrSize)) == -1)
		{
			LOG(CRITICAL, "Problem while accepting incoming silent alarm connection.",
				"Problem while accepting incoming silent alarm connection: "+string(strerror(errno)));
			continue;
		}

		if((bytesRead = recv(connectionSocket, buf, MAX_MSG_SIZE, MSG_WAITALL))== -1)
		{
			LOG(CRITICAL, "Problem while receiving incoming silent alarm connection.",
				"Problem while receiving incoming silent alarm connection: "+string(strerror(errno)));
			close(connectionSocket);
			continue;
		}

		for(uint i = 0; i < hostAddrs.size(); i++)
		{
			//If this is from ourselves, then drop it.
			if(hostAddrs[i].sin_addr.s_addr == sendaddr.sin_addr.s_addr)
			{
				close(connectionSocket);
				continue;
			}
		}

		CryptBuffer(buf, bytesRead, DECRYPT);

		in_addr_t addr = 0;
		memcpy(&addr, buf, 4);
		uint64_t key = addr;
		Suspect *newSuspect = new Suspect();
		if(newSuspect->Deserialize(buf, MAX_MSG_SIZE, MAIN_FEATURE_DATA) == 0)
		{
			close(connectionSocket);
			continue;
		}
		//If this suspect exists, update the information
		if(suspects.IsValidKey(key))
		{
			suspectCopy = suspects.CheckOut(key);
			suspectCopy.SetFlaggedByAlarm(true);
			FeatureSet fs = newSuspect->GetFeatureSet(MAIN_FEATURES);
			suspectCopy.AddFeatureSet(&fs, MAIN_FEATURES);
			suspects.CheckIn(&suspectCopy);

			// TODO: This looks like it may be a memory leak of newSuspect
		}
		//If this is a new suspect put it in the table
		else
		{
			newSuspect->SetIsHostile(false);
			newSuspect->SetFlaggedByAlarm(true);
			//We set isHostile to false so that when we classify the first time
			// the suspect will go from benign to hostile and be sent to the doppelganger module
			suspects.AddNewSuspect(newSuspect);
		}

		LOG(CRITICAL, string("Got a silent alarm!. Suspect: "+ newSuspect->ToString()), "");
		if(!Config::Inst()->GetClassificationTimeout())
		{
			UpdateAndClassify(newSuspect->GetIpAddress());
		}

		close(connectionSocket);
	}
	close(sockfd);
	LOG(CRITICAL, "The code should never get here, something went very wrong.", "");
	return NULL;
}