/** * This file is part of Rubanetra. * Copyright (C) 2013,2014 Stefan Swerk (stefan_rubanetra@swerk.priv.at) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import at.jku.fim.rubanetra.protocol.activity.*; import at.jku.fim.rubanetra.protocol.activity.tls.*; import at.jku.fim.rubanetra.protocol.activity.http.*; import at.jku.fim.rubanetra.protocol.activity.ip.*; import at.jku.fim.rubanetra.protocol.activity.icmp.*; import at.jku.fim.rubanetra.protocol.activity.dns.*; import at.jku.fim.rubanetra.protocol.activity.tcp.*; import at.jku.fim.rubanetra.protocol.activity.udp.*; import at.jku.fim.rubanetra.protocol.activity.skype.*; import at.jku.fim.rubanetra.protocol.activity.DroolsBaseActivity; import java.util.SortedSet; import java.util.TreeSet; import org.xbill.DNS.Record; import java.net.InetSocketAddress import java.util.List; import java.util.Set import java.util.HashSet import org.jnetpcap.protocol.tcpip.Udp; // using the MVEL expression language, see http://mvel.codehaus.org/ dialect "mvel" /** * A logger that may be used for logging custom messages */ global org.slf4j.Logger log; // forward declaration declare DroolsBaseActivity end /** * Represents a Skype payload of arbitrary type, consisting of an source/destination object id and hosts. */ declare SkypePayloadActivity extends DroolsBaseActivity @role( event ) @timestamp( getStartTimestamp() ) sourceObjectId : int destinationObjectId : int sourceHost : InetSocketAddress destinationHost : InetSocketAddress end /** * This rule is based on a crude heuristic which is again partially based on: https://github.com/matthiasbock/OpenSkype. * Skype traffic usually consists of Udp-packets containing a certain kind of object id, therefore those special packets * have to be matched first. * This rule should be disabled/removed/improved if it causes false-positives (to reduce the negative impact, this * rule does not replace any Activities, but extends them instead). * Possible enhancements include: * - Use Dns-matches to obtain the skype hosts, if possible (see Dropbox/Spideroak examples) * - Extend the SkypePayloadActivity according to the known metadata (see https://github.com/matthiasbock/OpenSkype) */ rule "Skype Payload (one way, two matches)" no-loop when $udp : UdpActivity( $objectId : SkypeActivityHelper.objectId(udp), SkypeActivityHelper.hasSkypePayload(udp)) $udpResp : UdpActivity( $objectIdResp : SkypeActivityHelper.objectId(udp), SkypeActivityHelper.hasSkypePayload(udp), sourceSocketAddress==$udp.destinationSocketAddress, destinationSocketAddress==$udp.sourceSocketAddress, this after[0s,10s] $udp) exists( UdpActivity($oid : SkypeActivityHelper.objectId(udp), ($objectId + 10) > $oid, $oid > $objectId, SkypeActivityHelper.hasSkypePayload(udp), sourceSocketAddress==$udp.sourceSocketAddress, destinationSocketAddress==$udp.destinationSocketAddress, this after[0s,10s] $udp) ) exists( UdpActivity($oid : SkypeActivityHelper.objectId(udp), ($objectIdResp + 10) > $oid, $oid > $objectIdResp, SkypeActivityHelper.hasSkypePayload(udp), sourceSocketAddress==$udpResp.sourceSocketAddress, destinationSocketAddress==$udpResp.destinationSocketAddress, this after[0s,10s] $udpResp) ) not ( exists UdpActivity( SkypeActivityHelper.objectId(udp)<$objectId, SkypeActivityHelper.hasSkypePayload(udp), sourceSocketAddress==$udp.sourceSocketAddress, destinationSocketAddress==$udp.destinationSocketAddress, this after[10s] $udp)) not ( exists UdpActivity( SkypeActivityHelper.objectId(udp)<$objectIdResp, SkypeActivityHelper.hasSkypePayload(udp), sourceSocketAddress==$udpResp.sourceSocketAddress, destinationSocketAddress==$udpResp.destinationSocketAddress, this after[10s] $udpResp)) not ( exists SkypePayloadActivity(sourceObjectId==$objectId || sourceObjectId==$objectIdResp || destinationObjectId==$objectId || destinationObjectId==$objectIdResp)) then SkypePayloadActivity act = new SkypePayloadActivity(); act.setSourceObjectId($objectId); act.setDestinationObjectId($objectIdResp); act.setSourceHost($udp.getSourceSocketAddress()); act.setDestinationHost($udp.getDestinationSocketAddress()); act.extendActivity($udp); act.extendActivity($udpResp); insert(act); end