void PacketIDMEFReporter::receive(Packet* p)
{
	IDMEFMessage* msg = idmefManager.getNewInstance();
	msg->init(idmefTemplate, analyzerId);
	analyzePacket(p, msg);
	msg->applyVariables();
	send(msg);
}
void TRWPortscanDetector::addConnection(Connection* conn)
{
	TRWEntry* te = getEntry(conn);

	// this host was already decided on, don't do anything any more
	if (te->decision != PENDING) return;

	// determine if connection was a failed or successful connection attempt
	// by looking if answering host sets the syn+ack bits for the threeway handshake
	bool connsuccess;
	if ((conn->dstTcpControlBits&(Connection::SYN|Connection::ACK))!=(Connection::SYN|Connection::ACK)) {
		// no, this is not a successful connection attempt!
		te->numFailedConns++;
		connsuccess = false;

	} else {
		te->numSuccConns++;
		connsuccess = true;
	}

	te->timeExpire = time(0) + timeExpirePending;

	// only work with this connection, if it wasn't accessed earlier by this host
	if (find(te->accessedHosts.begin(), te->accessedHosts.end(), conn->dstIP) != te->accessedHosts.end()) return;

	te->accessedHosts.push_back(conn->dstIP);

	te->S_N += (connsuccess ? X_0 : X_1);

	// aggregate new connection into entry
	if (te->dstSubnet==0 && te->dstSubnetMask==0xFFFFFFFF) {
		te->dstSubnet = conn->dstIP;
	} else {
		// adapt subnet mask so that new destination ip is inside given subnet
		while ((te->dstSubnet&te->dstSubnetMask)!=(conn->dstIP&te->dstSubnetMask)) {
			te->dstSubnetMask = ntohl(te->dstSubnetMask);
			te->dstSubnetMask <<= 1;
			te->dstSubnetMask = htonl(te->dstSubnetMask);
			te->dstSubnet &= te->dstSubnetMask;
		}
	}

	DPRINTF("IP: %s, S_N: %f", IPToString(te->srcIP).c_str(), te->S_N);
	
	// look if information is adequate for deciding on host
	if (te->S_N<logeta_0) {
		// no portscanner, just let entry stay here until it expires
		te->timeExpire = time(0)+timeExpireBenign;
		te->decision = BENIGN;
	} else if (te->S_N>logeta_1) {
		//this is a portscanner!
		te->decision = SCANNER;
		statNumScanners++;
		te->timeExpire = time(0)+timeExpireScanner;
		msg(MSG_DEBUG, "portscanner detected:");
		msg(MSG_DEBUG, "srcIP: %s, dstSubnet: %s, dstSubMask: %s", IPToString(te->srcIP).c_str(), 
				IPToString(te->dstSubnet).c_str(), IPToString(te->dstSubnetMask).c_str());
		msg(MSG_DEBUG, "numFailedConns: %d, numSuccConns: %d", te->numFailedConns, te->numSuccConns);

		IDMEFMessage* msg = idmefManager.getNewInstance();
		msg->init(idmefTemplate, analyzerId);
		msg->setVariable(PAR_SUCC_CONNS, te->numSuccConns);
		msg->setVariable(PAR_FAILED_CONNS, te->numFailedConns);
		msg->setVariable(IDMEFMessage::PAR_SOURCE_ADDRESS, IPToString(te->srcIP));
		msg->setVariable(IDMEFMessage::PAR_TARGET_ADDRESS, IPToString(te->dstSubnet)+"/"+IPToString(te->dstSubnetMask));
		msg->applyVariables();
		send(msg);
	}
}
示例#3
0
void RBSWormDetector::addConnection(Connection* conn)
{
	RBSEntry* te = getEntry(conn);
	
	//worms must not influence our average fanout frequency of non-worm hosts
	if (te->decision == WORM) return;
	
	// FOLLOWING CODE IS FOR BENIGN AND PENDING HOSTS

	// only work with this connection, if it wasn't accessed earlier by this host
	if (find(te->accessedHosts.begin(), te->accessedHosts.end(), conn->dstIP) != te->accessedHosts.end()) return;
	te->accessedHosts.push_back(conn->dstIP);

	//host was moved from benign to pending (for average fanouts)
	if (te->switched)	
	{
	te->switched = false;
	te->startTime = conn->srcTimeStart;
	}

	//timeelams represents time since 1970 in milliseconds
	uint64_t time_elams = conn->srcTimeStart; 
	

	//duration between last 2 packets
	uint64_t intarrival = labs((int64_t) (time_elams - te->lastPacket));

	//last two connection attempts where within 1 second
	if (intarrival < 1000) 
	{	
		te->totalSSNum++;
		te->totalSSDur += intarrival;
		te->mean = (te->totalSSDur/ (double) 1000) / (double) (te->totalSSNum);
	}

	te->lastPacket = time_elams;

	//we are still in the startup phase, dont decide on hosts
	if (lambda_0 == 0) return;

	// this host was already decided on, don't do anything any more
	if (te->decision != PENDING) return;


	// FOLLOWING CODE IS FOR PENDING HOSTS ONLY


	te->timeExpire = time(0) + timeExpirePending;
	te->numFanouts++;
	

	double trace_ela = (double) (time_elams - te->startTime) / 1000;
	//traceela is packet trace time in seconds

	// calculate thresholds
	float thresh_0 = te->numFanouts * slope_0a - slope_0b;
	float thresh_1 = te->numFanouts * slope_1a - slope_1b;

	//need more connections to evaluate
	if (te->numFanouts < lambda_0) return;  

	// look if information is adequate for deciding on host
	if (trace_ela>thresh_0)
	{
		// no worm, just let entry stay here until it expires
		te->timeExpire = time(0)+timeExpireBenign;
		te->decision = BENIGN;
		statCurBenign++;
	}
	else if (trace_ela<thresh_1) 
	{
		//this is a worm
		te->decision = WORM;
		statNumWorms++;
		te->timeExpire = time(0)+timeExpireWorm;
		msg(LOG_INFO, "Worm detected:");
		msg(LOG_INFO, "srcIP: %s", IPToString(te->srcIP).c_str());
		msg(LOG_INFO, "numFanOut: %d, totalTime: %f",te->numFanouts, trace_ela);

		IDMEFMessage* msg = idmefManager.getNewInstance();
		msg->init(idmefTemplate, analyzerId);
		msg->setVariable(PAR_FAN_OUT, (uint32_t) te->numFanouts);
		msg->setVariable(PAR_TOTALTIME, trace_ela);
		string hosts;
		list<uint32_t>::iterator iter = te->accessedHosts.begin();
		while(iter != te->accessedHosts.end()) 
		{
		hosts.append(IPToString(*iter));
		hosts.append(" ");
		iter++;
		}	
		msg->setVariable(PAR_HOSTS,hosts.c_str());
		msg->setVariable(IDMEFMessage::PAR_SOURCE_ADDRESS, IPToString(te->srcIP));
		msg->applyVariables();
		send(msg);
	}
}
/**
 * Calculates criterias for every host which were active during the ongoing interval
 */
void P2PDetector::onTimeout(void* dataPtr)
{
	timeoutRegistered = false;

	//criterias
	double udpRate;
	double udpHostRate;
	double tcpRate;
	double coexistentTCPCons;
	double rateLongTCPCons;
	double tcpVariance;
	double failedConsPercent;
	double tcpFailedRate;
	double tcpFailedVariance;

	//loop through all entries
	for(map<uint32_t, P2PEntry>::iterator iter = hostList.begin(); iter != hostList.end(); iter++){
		udpRate = ((double)(iter->second.numUDPBiFlows)) / intLength;
		udpHostRate = ((double)(iter->second.contactedUDPHosts.size())) / intLength;
		tcpRate = ((double)(iter->second.numTCPBiFlows)) / intLength;
		coexistentTCPCons = ((double)(iter->second.sumTCPLength)) / intLength;
		rateLongTCPCons = ((double)(iter->second.numLongTCPCons)) / intLength;
		//tcpVariance
		if(iter->second.succBiFlowStarts.size() < 3)
			tcpVariance = -1;
		else{
			double sum = 0;
			double qsum = 0;
			double variance;
			iter->second.succBiFlowStarts.sort();
			list<uint64_t>::iterator ptr1 = iter->second.succBiFlowStarts.begin();
			list<uint64_t>::iterator ptr2 = ptr1++;

			for(; ptr1 != iter->second.succBiFlowStarts.end(); ptr1++, ptr2++){
				sum += *ptr1 - *ptr2;
				qsum += (*ptr1 - *ptr2) * (*ptr1 - *ptr2);
			}
			//sample variance (stichprobenvarianz) /  n = succBiFlowStarts.size()-1: the differences not the starting points itself
			variance = (1.0/(iter->second.succBiFlowStarts.size()-2))*(qsum - ((1.0/(iter->second.succBiFlowStarts.size()-1))*(sum*sum)));
			tcpVariance = sqrt(variance)/(iter->second.succBiFlowStarts.size()-1);
		}
		failedConsPercent = (((double)(iter->second.numFailedTCPCons)) * 100) / iter->second.numTCPBiFlows;
		tcpFailedRate = ((double)(iter->second.numFailedTCPCons)) / intLength;
		//variance of failed connections
		if(iter->second.failedBiFlowStarts.size() < 3)
			tcpFailedVariance = -1;
		else{
			double sum = 0;
			double qsum = 0;
			double variance;
			iter->second.failedBiFlowStarts.sort();
			list<uint64_t>::iterator ptr1 = iter->second.failedBiFlowStarts.begin();
			list<uint64_t>::iterator ptr2 = ptr1++;

			for(; ptr1 != iter->second.failedBiFlowStarts.end(); ptr1++, ptr2++){
				sum += *ptr1 - *ptr2;
				qsum += (*ptr1 - *ptr2) * (*ptr1 - *ptr2);
			}
			//sample variance (stichprobenvarianz) /  n = failedBiFlowStarts.size()-1: the differences not the starting points itself
			variance = (1.0/(iter->second.failedBiFlowStarts.size()-2))*(qsum - ((1.0/(iter->second.failedBiFlowStarts.size()-1))*(sum*sum)));
			tcpFailedVariance = sqrt(variance)/(iter->second.failedBiFlowStarts.size()-1);
		}

		//decide whether researched host is peer-to-peer or not
		int points = 0;
		if(udpRate > udpRateThreshold)
			points++;
		if(udpHostRate > udpHostRateThreshold)
			points++;
		if(tcpRate > tcpRateThreshold)
			points++;
		if(coexistentTCPCons > coexistentTCPConsThreshold)
			points++;
		if(rateLongTCPCons > rateLongTCPConsThreshold)
			points++;
		if((tcpVariance <= tcpVarianceThreshold) && (tcpVariance >= 0))
			points++;
		if(failedConsPercent > failedConsPercentThreshold)
			points++;
		if(tcpFailedRate > tcpFailedRateThreshold)
			points++;
		if((tcpFailedVariance <= tcpFailedVarianceThreshold) && (tcpFailedVariance >= 0))
			points++;

		//host is a p2p client
		if(points > 6){
			//send Message
			msg(MSG_INFO, "P2P client detected:");
			msg(MSG_INFO, "IP: %s, dstSubnet: %s, dstSubMask: %s", IPToString(iter->first).c_str(),
				IPToString(subnet).c_str(), IPToString(subnetmask).c_str());

			IDMEFMessage* msg = idmefManager.getNewInstance();
			msg->init(idmefTemplate, analyzerId);

			msg->setVariable("UDP_RATE", udpRate);
			(udpRate > udpRateThreshold) ? msg->setVariable("TRUE1", "1") : msg->setVariable("TRUE1", "0");

			msg->setVariable("UDP_HOST_RATE", udpHostRate);
			(udpHostRate > udpHostRateThreshold) ? msg->setVariable("TRUE2", "1") : msg->setVariable("TRUE2", "0");

			msg->setVariable("TCP_RATE",  tcpRate);
			(tcpRate > tcpRateThreshold) ? msg->setVariable("TRUE3", "1") : msg->setVariable("TRUE3", "0");

			msg->setVariable("COEXISTENT_TCP_CONS", coexistentTCPCons);
			(coexistentTCPCons > coexistentTCPConsThreshold) ? msg->setVariable("TRUE4", "1") : msg->setVariable("TRUE4", "0");

			msg->setVariable("RATE_LONG_TCP_CONS", rateLongTCPCons);
			(rateLongTCPCons > rateLongTCPConsThreshold) ? msg->setVariable("TRUE5", "1") : msg->setVariable("TRUE5", "0");

			msg->setVariable("TCP_VARIANCE", tcpVariance);
			((tcpVariance <= tcpVarianceThreshold) && (tcpVariance >= 0)) ? msg->setVariable("TRUE6", "1") : msg->setVariable("TRUE6", "0");

			msg->setVariable("FAILED_CONS_PERCENT", failedConsPercent);
			(failedConsPercent > failedConsPercentThreshold) ? msg->setVariable("TRUE7", "1") : msg->setVariable("TRUE7", "0");

			msg->setVariable("TCP_FAILED_RATE", tcpFailedRate);
			(tcpFailedRate > tcpFailedRateThreshold) ? msg->setVariable("TRUE8","1") : msg->setVariable("TRUE8", "0");

			msg->setVariable("TCP_FAILED_VARIANCE", tcpFailedVariance);
			((tcpFailedVariance <= tcpFailedVarianceThreshold) && (tcpFailedVariance >= 0)) ? msg->setVariable("TRUE9","1") : msg->setVariable("TRUE9", "0");

			msg->setVariable("PEER_ADDRESS", IPToString(iter->first).c_str());
			msg->applyVariables();
			send(msg);
		}

	}

	//new interval starts
	hostList.clear();
}