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); } }
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(); }