Example #1
0
Handle<Value> NovaNode::GetSuspectDetailsString(const Arguments &args) {
	HandleScope scope;
	string details;

	string suspectIp = cvv8::CastFromJS<string>(args[0]);
	string suspectInterface = cvv8::CastFromJS<string>(args[1]);

	struct in_addr address;
	inet_pton(AF_INET, suspectIp.c_str(), &address);

	SuspectIdentifier id;
	id.m_ip = htonl(address.s_addr);
	id.m_interface = suspectInterface;

	Suspect *suspect = GetSuspectWithData(id);
	if (suspect != NULL) {
		details = suspect->ToString();
		details += "\n";
		details += suspect->GetFeatureSet().toString();
		delete suspect;
	} else {
		details = "Unable to complete request";
	}

	return scope.Close(cvv8::CastToJS(details));
}
Example #2
0
void PrintSuspectData(in_addr_t address, string interface)
{
	Connect();

	SuspectIdentifier id(ntohl(address), interface);

	Suspect *suspect = GetSuspectWithData(id);

	if (suspect != NULL)
	{
		cout << suspect->ToString() << endl;


		cout << "Details follow" << endl;
		cout << suspect->GetFeatureSet(MAIN_FEATURES).toString() << endl;
	}
	else
	{
		cout << "Error: No suspect received" << endl;
	}

	delete suspect;

	CloseNovadConnection();


}
Example #3
0
void update(const in_addr_t& key)
{
	in_addr_t foo = key;
	suspects.ClassifySuspect(foo);

	//Check that we updated correctly
	Suspect suspectCopy = suspects.GetSuspect(foo);

	if(suspects.IsEmptySuspect(&suspectCopy))
	{
		cout << "Got an empty suspect when trying to classify" << endl;
		return;
	}

	//Store in training file if needed
	trainingFileStream << string(inet_ntoa(suspectCopy.GetInAddr())) << " ";

	FeatureSet fs = suspectCopy.GetFeatureSet(MAIN_FEATURES);
	if(fs.m_features[0] != fs.m_features[0] )
	{
		cout << "This can't be good..." << endl;
	}
	for(int j = 0; j < DIM; j++)
	{
		trainingFileStream << fs.m_features[j] << " ";
	}
	trainingFileStream << "\n";
}
Example #4
0
// Update our internal suspect list to that of novad
void NovaNode::SynchInternalList()
{
	vector<in_addr_t> *suspects;
	suspects = GetSuspectList(SUSPECTLIST_ALL);

	if (suspects == NULL)
	{
		cout << "Failed to get suspect list" << endl;
	}
	for (uint i = 0; i < suspects->size(); i++)
	{
		Suspect *suspect = GetSuspect(suspects->at(i));

		if (suspect != NULL)
		{
			HandleNewSuspect(suspect);
			if (m_suspects.count(suspect->GetIpAddress()) == 0)
			{
				delete m_suspects[suspect->GetIpAddress()];
			}	
			m_suspects[suspect->GetIpAddress()] = suspect;
		}
		else
		{
			cout << "Error: No suspect received" << endl;
		}
	}
}
Example #5
0
void ConvertCaptureToDump(std::string captureFolder)
{
	engine = new ClassificationAggregator();

	Database::Inst()->ClearAllSuspects();

	if(chdir(Config::Inst()->GetPathHome().c_str()) == -1)
	{
		LOG(CRITICAL, "Unable to change folder to " + Config::Inst()->GetPathHome(), "");
	}

	string dumpFile = captureFolder + "/nova.dump";
	string pcapFile = captureFolder + "/capture.pcap";

   	string haystackFile = captureFolder + "/haystackIps.txt";
	UpdateHaystackFeatures(haystackFile);


	trainingFileStream.open(dumpFile);
	if(!trainingFileStream.is_open())
	{
		LOG(CRITICAL, "Unable to open the training capture file.", "Unable to open training capture file at: "+dumpFile);
	}

	FilePacketCapture capture(pcapFile);
	capture.SetPacketCb(HandleTrainingPacket);
	capture.Init();
	capture.SetFilter(ConstructFilterString());
	capture.StartCaptureBlocking();

	LOG(DEBUG, "Done processing PCAP file.", "");

	suspects.WriteToDatabase();

	vector<Suspect> suspects = Database::Inst()->GetSuspects(SUSPECTLIST_ALL);

	for (int i = 0; i < suspects.size(); i++)
	{
		Suspect suspectCopy = suspects[i];

		//Store in training file if needed
		trainingFileStream << suspectCopy.GetIpString() << " ";

		suspectCopy.GetFeatureSet();
		EvidenceAccumulator fs = suspectCopy.GetFeatureSet(MAIN_FEATURES);
		if(fs.m_features[0] != fs.m_features[0] )
		{
			cout << "This can't be good..." << endl;
		}
		for(int j = 0; j < DIM; j++)
		{
			trainingFileStream << fs.m_features[j] << " ";
		}
		trainingFileStream << "\n";
	}


	trainingFileStream.close();
}
Example #6
0
void MonitorCallback()
{
    while (true)
    {
	    if( ! Nova::ConnectToNovad() )
	    {
	        LOG(ERROR, "CLI Unable to connect to Novad right now. Trying again in 3 seconds...","");
	        sleep(3);
	        continue;
	    }


		CallbackChange cb;
		CallbackHandler callbackHandler;
	    Suspect s;

		do
		{
			cb = callbackHandler.ProcessCallbackMessage();
			switch( cb.m_type )
			{
			case CALLBACK_NEW_SUSPECT:
				cout << "Got new suspect: " << cb.m_suspect->GetIdString() << + " with classification of " << cb.m_suspect->GetClassification() << endl;

				// We get a suspect pointer and are responsible for deleting it
				delete cb.m_suspect;
				break;

			case CALLBACK_ERROR:
				cout << "WARNING: Recieved a callback error message!" << endl;
				break;

			case CALLBACK_ALL_SUSPECTS_CLEARED:
				cout << "Got notice that all suspects were cleared" << endl;
				break;

			case CALLBACK_SUSPECT_CLEARED:
				s.SetIdentifier(cb.m_suspectIP);
				cout << "Got a notice that suspect was cleared: " + s.GetIdString() << endl;
				break;
			case CALLBACK_HUNG_UP:
				cout << "Got CALLBACK_HUNG_UP" << endl;
				break;
			default:
				cout << "WARNING: Got a callback message we don't know what to do with. Type " << cb.m_type << endl;
				break;
			}
		}
		while(cb.m_type != CALLBACK_HUNG_UP);
		cout << "Novad hung up, closing callback processing and trying again in 3 seconds" << endl;
		sleep(3);
   }
}
Example #7
0
int NovaNode::HandleSuspectClearedOnV8Thread(eio_req* req)
{
	HandleScope scope;
	Suspect* suspect = static_cast<Suspect*>(req->data);
	if (m_suspects.keyExists(suspect->GetIdentifier())) {
		delete m_suspects[suspect->GetIdentifier()];
	}
	m_suspects.erase(suspect->GetIdentifier());

	v8::Persistent<Value> weak_handle = Persistent<Value>::New(SuspectJs::WrapSuspect(suspect));
	weak_handle.MakeWeak(suspect, &DoneWithSuspectCallback);
	Persistent<Value> argv[1] = { weak_handle };	
	m_SuspectClearedCallback->Call(m_SuspectClearedCallback, 1, argv);
	
	return 0;
}
Example #8
0
void NovaNode::NovaCallbackHandling(eio_req*)
{
	using namespace Nova;
	CallbackChange cb;

	LOG(DEBUG, "Initializing Novad callback processing","");

	CallbackHandler callbackHandler;

	m_callbackRunning = true;
	do
	{
		Suspect *s;
		cb = callbackHandler.ProcessCallbackMessage();
		switch( cb.m_type )
		{
		case CALLBACK_NEW_SUSPECT:
			HandleNewSuspect(cb.m_suspect);
			break;

		case CALLBACK_ERROR:
			HandleCallbackError();
			break;

		case CALLBACK_ALL_SUSPECTS_CLEARED:
			HandleAllSuspectsCleared();
			break;

		case CALLBACK_SUSPECT_CLEARED:
			s = new Suspect();
			s->SetIdentifier(cb.m_suspectIP);
			LOG(DEBUG, "Got a clear callback request for a suspect on interface " + cb.m_suspectIP.m_interface, "");
			HandleSuspectCleared(s);
			break;

		default:
			break;
		}
	}
	while(cb.m_type != CALLBACK_HUNG_UP);         
	LOG(DEBUG, "Novad hung up, closing callback processing","");
	m_callbackRunning = false;
}
Example #9
0
int NovaNode::HandleNewSuspectOnV8Thread(eio_req* req)
{
	HandleScope scope;
	
	Suspect* suspect = static_cast<Suspect*>(req->data);
		
	if (suspect != NULL) {	
		if (m_suspects.keyExists(suspect->GetIdentifier())) {
			delete m_suspects[suspect->GetIdentifier()];
		}
		
		m_suspects[suspect->GetIdentifier()] = suspect;
		SendSuspect(suspect);
	} else {
		LOG(DEBUG, "HandleNewSuspectOnV8Thread got a NULL suspect pointer. Ignoring.", "");
	}
	return 0;

}
Example #10
0
void PrintSuspect(in_addr_t address, string interface)
{
	Connect();

	SuspectIdentifier id(ntohl(address), interface);

	Suspect *suspect = GetSuspect(id);

	if(suspect != NULL)
	{
		cout << suspect->ToString() << endl;
	}
	else
	{
		cout << "Error: No suspect received" << endl;
	}

	delete suspect;

	CloseNovadConnection();
}
Example #11
0
void PrintAllSuspects(enum SuspectListType listType, bool csv)
{
	Connect();

	vector<SuspectIdentifier> suspects = GetSuspectList(listType);

	// Print the CSV header
	if (csv)
	{
		cout << "IP,";
		cout << "INTERFACE,";
		for(int i = 0; i < DIM; i++)
		{
			cout << FeatureSet::m_featureNames[i] << ",";
		}
		cout << "CLASSIFICATION" << endl;
	}

	for(uint i = 0; i < suspects.size(); i++)
	{
		Suspect *suspect = GetSuspect(suspects.at(i));

		if(suspect != NULL)
		{
			if(!csv)
			{
				cout << suspect->ToString() << endl;
			}
			else
			{
				cout << suspect->GetIpString() << ",";
				cout << suspect->GetIdentifier().m_interface << ",";
				for(int i = 0; i < DIM; i++)
				{
					cout << suspect->GetFeatureSet().m_features[i] << ",";
				}
				cout << suspect->GetClassification() << endl;
			}

			delete suspect;
		}
		else
		{
			cout << "Error: No suspect received" << endl;
		}
	}

	CloseNovadConnection();

}
Example #12
0
void NovaNode::NovaCallbackHandling(eio_req*)
{
	LOG(DEBUG, "Initializing Novad callback processing","");

	while(true)
	{
		Nova::Message *message = DequeueUIMessage();
		//If this is a callback for a specific operation
		if(message->m_contents.has_m_messageid())
		{
			eio_nop(EIO_PRI_DEFAULT, NovaNode::HandleMessageWithIDOnV8Thread, message);
			continue;
		}

		switch(message->m_contents.m_type())
		{
			case UPDATE_SUSPECT:
			{
				if(!message->m_suspects.empty())
				{
					HandleNewSuspect(message->m_suspects[0]);
				}
				break;
			}
			case REQUEST_ALL_SUSPECTS_REPLY:
			{
				for(uint i = 0; i < message->m_suspects.size(); i++)
				{
					HandleNewSuspect(message->m_suspects[i]);
				}
				break;
			}
			case REQUEST_SUSPECT_REPLY:
			{
				break;
			}
			case UPDATE_ALL_SUSPECTS_CLEARED:
			{
				HandleAllSuspectsCleared();
				break;
			}
			case UPDATE_SUSPECT_CLEARED:
			{
				Suspect *suspect = new Suspect();
				suspect->SetIdentifier(message->m_contents.m_suspectid());
				LOG(DEBUG, "Got a clear suspect response for a suspect on interface " + message->m_contents.m_suspectid().m_ifname(), "");
				HandleSuspectCleared(suspect);
				break;
			}
			case REQUEST_PONG:
			{
				break;
			}
			case CONNECTION_SHUTDOWN:
			{
				break;
			}
			default:
			{
				HandleCallbackError();
				break;
			}
		}
		delete message;
	}
}
Example #13
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;
}