/* * version 1.0 - MUSES prototype software * Copyright MUSES project (European Commission FP7) - 2013 * */ package eu.musesproject.server.dataminer; /* * #%L * MUSES Server * %% * Copyright (C) 2013 - 2014 UGR * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import java.math.BigInteger; import java.sql.Time; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import eu.musesproject.server.db.handler.DBManager; import eu.musesproject.server.entity.Applications; import eu.musesproject.server.entity.Assets; import eu.musesproject.server.entity.Decision; import eu.musesproject.server.entity.DecisionTrustvalues; import eu.musesproject.server.entity.Devices; import eu.musesproject.server.entity.EventType; import eu.musesproject.server.entity.PatternsKrs; import eu.musesproject.server.entity.Roles; import eu.musesproject.server.entity.SecurityViolation; import eu.musesproject.server.entity.SimpleEvents; import eu.musesproject.server.entity.Users; import eu.musesproject.server.scheduler.ModuleType; import org.apache.log4j.Logger; /** * The Class DataMiningUtils. * * @author Paloma de las Cuevas (UGR) * @version Aug 30, 2015 */ public class DataMiningUtils { private static DBManager dbManager = new DBManager(ModuleType.KRS); private static final String MUSES_TAG = "MUSES_TAG"; private Logger logger = Logger.getLogger(DataMiner.class); /** * obtainLabel - For every event, an access request is built by the Event Processor, so the RT2AE can make a final decision about it. * This method obtains the associated label to an event. * * @param accessRequestId Is the access request number associated to an event. * * @return label * */ public String obtainLabel(String accessRequestId){ List<Decision> decisions = dbManager.findDecisionByAccessRequestId(accessRequestId); if (decisions.size() > 0) { return decisions.get(0).getValue(); } else { return "GRANTED"; } } /** * obtainDecisionCause - For every event, it may be several security violations, and each one contains the cause of the violation. * This method returns the decision cause for an event, either if the security violation is linked to a decision id * or not. * * @param accessRequestId Is the access request number associated to an event. * @param eventId The event Id * * @return decisionCause * */ public String obtainDecisionCause(String accessRequestId, String eventId){ List<Decision> decisions = dbManager.findDecisionByAccessRequestId(accessRequestId); if (decisions.size() > 0) { String decisionId = decisions.get(0).getDecisionId(); SecurityViolation securityViolation = dbManager.findSecurityViolationByDecisionId(decisionId); Pattern p = Pattern.compile("<(.+?)>(.+?)</(.+?)>"); if (securityViolation != null) { Matcher matcher = p.matcher(securityViolation.getConditionText()); if (matcher.find()) { return matcher.group(1); } else { return null; } } else { List<SecurityViolation> secViolations = dbManager.findSecurityViolationByEventId(eventId); if (secViolations.size() > 0) { return null; } else { return "ALLOW"; } } } else { return null; } } /** * obtainEventType - For every event, this method obtains its type. * * @param event The event as a Simple Events object. * * @return eventType * */ public String obtainEventType(SimpleEvents event){ EventType eventTypeId = event.getEventType(); String eventType = null; eventType = eventTypeId.getEventTypeKey(); return eventType; } /** * obtainEventLevel - For every event, this method obtains its level (simple or complex). * * @param event The event as a Simple Events object. * * @return eventLevel * */ public String obtainEventLevel(SimpleEvents event){ EventType eventTypeId = event.getEventType(); String eventLevel = null; eventLevel = eventTypeId.getEventLevel(); return eventLevel; } /** * obtainUsername - For every event, this method obtains who is responsible for the event, but maintaining the anonymity. * * @param user The user as a User object. * * @return username * */ public String obtainUsername(Users user){ String username = null; username = user.getUsername(); return username; } /** * passwdLength - This method measures the length of the user password. * * @param user The user as a User object. * * @return passwordLength * */ public int passwdLength(Users user){ int passwordLength = 0; String userPassword = user.getPassword(); // Characters (numbers, letters, and symbols) in the password if (userPassword != null) { passwordLength = userPassword.length(); } return passwordLength; } /** * passwdDigits - This method measures the number of digits (0-9) in the user password. * * @param user The user as a User object. * * @return digitsCount * */ public int passwdDigits(Users user){ int digitsCount = 0; String userPassword = user.getPassword(); String digits = "\\d"; Pattern digitPattern = Pattern.compile(digits); Matcher digitsMatcher = digitPattern.matcher(userPassword); while (digitsMatcher.find()) { digitsCount++; } return digitsCount; } /** * passwdLetters - This method measures the number of letters (a-z) in the user password. * * @param user The user as a User object. * * @return lettersCount * */ public int passwdLetters(Users user){ int lettersCount = 0; String userPassword = user.getPassword(); String letters = "[a-zA-Z]"; Pattern letterPattern = Pattern.compile(letters); Matcher lettersMatcher = letterPattern.matcher(userPassword); while (lettersMatcher.find()) { lettersCount++; } return lettersCount; } /** * passwdCapLetters - This method measures the number of capital letters (A-Z) in the user password. * * @param user The user as a User object. * * @return capLettersCount * */ public int passwdCapLetters(Users user){ int capLettersCount = 0; String userPassword = user.getPassword(); String capLetters = "[A-Z]"; Pattern capLetterPattern = Pattern.compile(capLetters); Matcher capLettersMatcher = capLetterPattern.matcher(userPassword); while (capLettersMatcher.find()) { capLettersCount++; } return capLettersCount; } /** * obtainingUserTrust - This method gathers the user trust value associated to the user, at the time of the decision. * * @param accessRequestId Is the access request number associated to an event. * * @return trustValue * */ public double obtainingUserTrust(String accessRequestId){ double trustValue = Double.NaN; List<Decision> decisions = dbManager.findDecisionByAccessRequestId(accessRequestId); if (decisions.size() > 0) { String decisionId = decisions.get(0).getDecisionId(); List<DecisionTrustvalues> trustValues = dbManager.findDecisionTrustValuesByDecisionId(decisionId); if (trustValues.size() > 0) { trustValue = trustValues.get(0).getUsertrustvalue(); } } return trustValue; } /** * obtainingDeviceTrust - This method gathers the user trust value associated to the device, at the time of the decision. * * @param accessRequestId Is the access request number associated to an event. * * @return trustValue * */ public double obtainingDeviceTrust(String accessRequestId){ double trustValue = Double.NaN; List<Decision> decisions = dbManager.findDecisionByAccessRequestId(accessRequestId); if (decisions.size() > 0) { String decisionId = decisions.get(0).getDecisionId(); List<DecisionTrustvalues> trustValues = dbManager.findDecisionTrustValuesByDecisionId(decisionId); if (trustValues.size() > 0) { trustValue = trustValues.get(0).getDevicetrustvalue(); } } return trustValue; } /** * obtainUserRole - This method obtains the role of the user who made the event. * * @param user The user as a User object. * * @return role * */ public String obtainUserRole(Users user){ int userRoleId = user.getRoleId(); Roles userRole = dbManager.getRoleById(userRoleId); String userRoleName = null; if (userRole != null) { userRoleName = userRole.getName(); } return userRoleName; } /** * obtainTimestamp - This method obtains the detection time of the event. * * @param event The event as a Simple Events object. * * @return eventDetection * */ public Date obtainTimestamp(SimpleEvents event){ Date eventDate = event.getDate(); Time eventTime = event.getTime(); Date eventDetection = new Date(eventDate.getYear(), eventDate.getMonth(), eventDate.getDate(), eventTime.getHours(), eventTime.getMinutes(), eventTime.getSeconds()); return eventDetection; } /** * silentModeTrials1 - This method checks if the device was in silent mode or verbose mode during first trials. It returns 1 if it was * in silent mode, and 0 if it was in verbose mode. * * @param event The event as a Simple Events object. * * @return silentMode * */ public int silentModeTrials1(SimpleEvents event){ Date eventDate = event.getDate(); Time eventTime = event.getTime(); Date eventDetection = new Date(eventDate.getYear(), eventDate.getMonth(), eventDate.getDate(), eventTime.getHours(), eventTime.getMinutes(), eventTime.getSeconds()); if (eventDetection.getDay() <= 16 && eventDetection.getMonth() <= 3) { return 1; } else { return 0; } } /** * silentModeTrials2 - This method checks if the device was in silent mode or verbose mode during second trials. It returns 1 if it was * in silent mode, and 0 if it was in verbose mode. * * @param event The event as a Simple Events object. * * @return silentMode * */ public int silentModeTrials2(SimpleEvents event){ Date eventDate = event.getDate(); Time eventTime = event.getTime(); Date eventDetection = new Date(eventDate.getYear(), eventDate.getMonth(), eventDate.getDate(), eventTime.getHours(), eventTime.getMinutes(), eventTime.getSeconds()); if (eventDetection.getDay() <= 2 && eventDetection.getMonth() <= 7) { return 1; } else { return 0; } } /** * obtainDeviceModel - This method obtains the device model. * * @param event The event as a Simple Events object. * * @return deviceModel * */ public String obtainDeviceModel(SimpleEvents event){ Devices userDeviceId = event.getDevice(); String deviceModel = null; if (userDeviceId != null) { deviceModel = userDeviceId.getDeviceModel(); } return deviceModel; } /** * obtainDeviceOS - This method obtains the OS of the device. It returns a string made from the name of the OS and the version. * * @param event The event as a Simple Events object. * * @return deviceOS * */ public String obtainDeviceOS(SimpleEvents event){ Devices userDeviceId = event.getDevice(); String deviceOS = null; if (userDeviceId.getOS_name()!=null && userDeviceId.getOS_version() != null){ deviceOS = userDeviceId.getOS_name().concat(userDeviceId.getOS_version()); } return deviceOS; } /** * obtainDeviceCertificate - This method for the certificate of the device. It returns 1 if it finds a certificate in the DB, and 0 if * it does not. * * @param event The event as a Simple Events object. * * @return validCertificate * */ public int obtainDeviceCertificate(SimpleEvents event){ Devices userDeviceId = event.getDevice(); byte[] deviceCertificate = userDeviceId.getCertificate(); if ((deviceCertificate != null) && (deviceCertificate.length > 0)) { return 1; } else { return 0; } } /** * obtainDeviceOwner - This method looks for the certificate of the device. It returns 1 if it finds a certificate in the DB, and 0 if * it does not. * * @param event The event as a Simple Events object. * * @return deviceOwner * */ public String obtainDeviceOwner(SimpleEvents event){ Devices userDeviceId = event.getDevice(); String deviceOwner = null; if (userDeviceId != null) { deviceOwner = userDeviceId.getOwnerType(); } return deviceOwner; } /** * obtainAppName - This method gathers characteristics of the application which the user was using at the time of the event. * * @param event The event as a Simple Events object. * * @return appName * */ public String obtainAppName(SimpleEvents event){ Applications eventApp = event.getApplication(); String appName = null; if (eventApp.getName() != null && eventApp.getVersion() != null) { appName = eventApp.getName().concat(eventApp.getVersion()); } return appName; } /** * obtainAppVendor - This method gathers characteristics of the application which the user was using at the time of the event. * * @param event The event as a Simple Events object. * * @return appVendor * */ public String obtainAppVendor(SimpleEvents event){ Applications eventApp = event.getApplication(); String appVendor = null; appVendor = eventApp.getVendor(); return appVendor; } /** * obtainMusesAwareness - This method checks if the application is MUSES aware or not. * * @param event The event as a Simple Events object. * * @return appMusesAware * */ public int obtainMusesAwareness(SimpleEvents event){ Applications eventApp = event.getApplication(); int appMusesAware = 0; if (eventApp != null) { appMusesAware = eventApp.getIs_MUSES_aware(); } return appMusesAware; } /** * obtainAssetName - This method gathers characteristics of the asset that the event is trying to access to. * * @param event The event as a Simple Events object. * * @return assetName * */ public String obtainAssetName(SimpleEvents event){ Assets eventAsset = event.getAsset(); String assetName = null; if (eventAsset != null) { assetName = eventAsset.getTitle(); } return assetName; } public double obtainAssetValue(SimpleEvents event){ Assets eventAsset = event.getAsset(); double assetValue = Double.NaN; if (eventAsset != null) { assetValue = eventAsset.getValue(); } return assetValue; } /** * obtainAssetConfidentiality - This method gathers characteristics of the asset that the event is trying to access to. * * @param event The event as a Simple Events object. * * @return assetConf * */ public String obtainAssetConfidentiality(SimpleEvents event){ Assets eventAsset = event.getAsset(); String assetConf = null; if (eventAsset != null) { assetConf = eventAsset.getConfidentialLevel(); } return assetConf; } /** * obtainAssetLocation - This method gathers characteristics of the asset that the event is trying to access to. * * @param event The event as a Simple Events object. * * @return assetLocation * */ public String obtainAssetLocation(SimpleEvents event){ Assets eventAsset = event.getAsset(); String assetLocation = null; if (eventAsset != null) { assetLocation = eventAsset.getLocation(); } return assetLocation; } /** * readConfigurationJSON - This method extracts information about the last known configuration of the device. * * @param event The event as a Simple Events object. * * @return List<Integer> configValues * */ public List<Integer> readConfigurationJSON(SimpleEvents event){ List<Integer> configValues = new ArrayList<Integer>(); Devices userDeviceId = event.getDevice(); Date eventDate = event.getDate(); SimpleEvents configEvent = dbManager.findDeviceConfigurationBySimpleEvent(Integer.parseInt(userDeviceId.getDeviceId()), eventDate.toString()); String configData = configEvent.getData(); // configData format is like: // {event=security_property_changed, properties={"id":"1", // "ispasswordprotected":"true","isrootpermissiongiven":"false", // "screentimeoutinseconds":"300","musesdatabaseexists":"true", // "isrooted":"false","accessibilityenabled":"false", // "istrustedantivirusinstalled":"false","ipaddress":"172.17.1.52"}} String configFormat = "\\\"?(\\w+)\\\"?[\\:\\=]\\\"?(\\w+)\\\"?"; Pattern configPattern = Pattern.compile(configFormat); Matcher configMatcher = configPattern.matcher(configData); while (configMatcher.find()) { if (configMatcher.group(1).equalsIgnoreCase("ispasswordprotected")) { if (configMatcher.group(2).equalsIgnoreCase("true")) { configValues.add(1); } else { configValues.add(0); } } else if (configMatcher.group(1).equalsIgnoreCase("screentimeoutinseconds")) { BigInteger time = BigInteger.valueOf(Integer.parseInt(configMatcher.group(2))); configValues.add(Integer.parseInt(configMatcher.group(2))); } else if (configMatcher.group(1).equalsIgnoreCase("isscreanlocked")) { configValues.add(0); } else if (configMatcher.group(1).equalsIgnoreCase("isrooted")) { if (configMatcher.group(2).equalsIgnoreCase("true")) { configValues.add(1);; } else { configValues.add(0); } } else if (configMatcher.group(1).equalsIgnoreCase("accessibilityenabled")) { if (configMatcher.group(2).equalsIgnoreCase("true")) { configValues.add(1); } else { configValues.add(0); } } else if (configMatcher.group(1).equalsIgnoreCase("istrustedantivirusinstalled")) { if (configMatcher.group(2).equalsIgnoreCase("true")) { configValues.add(1); } else { configValues.add(0); } } } return configValues; } /** * readMailJSON - This method extracts information about the characteristics of a mail being sent. * * @param event The event as a Simple Events object. * * @return List<Integer> mailValues * */ public List<Integer> readMailJSON(SimpleEvents event){ List<Integer> mailValues = new ArrayList<Integer>(); EventType eventTypeId = event.getEventType(); /* Data in event_type_if = 11 * {event=ACTION_SEND_MAIL, properties={"to":"the.reiceiver@generic.com, * another.direct.receiver@generic.com","noAttachments":"1", * "subject":"MUSES sensor status subject","bcc":"hidden.reiceiver@generic.com", * "from":"max.mustermann@generic.com","attachmentInfo":"pdf", * "cc":"other.listener@generic.com, 2other.listener@generic.com"}} */ if ((eventTypeId!=null)&&(eventTypeId.getEventTypeId() == 11)) { String mailJSON = "\\\"(\\w+)\\\"\\:\\\"?([\\w\\@\\.\\_\\-\\,\\s]+)"; String mailFormat = "[\\w\\.\\_]+\\@([\\w\\.\\_]+)"; Pattern mailPattern = Pattern.compile(mailJSON); Pattern mailFormatPattern = Pattern.compile(mailFormat); Matcher matcherMail = mailPattern.matcher(event.getData()); if (matcherMail.find()) { Matcher matcherMailFormat = mailFormatPattern.matcher(matcherMail.group(2)); if (matcherMail.group(1).equalsIgnoreCase("bcc")) { while (matcherMailFormat.find()) { if (this.isRecipientAllowed(matcherMailFormat.group(1))) { mailValues.add(1); } else { mailValues.add(0); } } } else if (matcherMail.group(1).equalsIgnoreCase("cc")) { while (matcherMailFormat.find()) { if (this.isRecipientAllowed(matcherMailFormat.group(1))) { mailValues.add(1); } else { mailValues.add(0); } } } else if (matcherMail.group(1).equalsIgnoreCase("to")) { while (matcherMailFormat.find()) { if (this.isRecipientAllowed(matcherMailFormat.group(1))) { mailValues.add(1); } else { mailValues.add(0); } } } else if (matcherMail.group(1).equalsIgnoreCase("noAttachments")) { Pattern attachmentP = Pattern.compile("(\\d+)\\,"); Matcher matcherAttachment = attachmentP.matcher(matcherMail.group(2)); if (matcherAttachment.find()) { mailValues.add(Integer.parseInt(matcherAttachment.group(1))); } } } } return mailValues; } /** * Method isRecipientAllowed, which checks if the mail address server is allowed by the company. * * @param server Server of the mail address like in name@server.com. * * * @return boolean True if it is allowed, false if not. * */ public boolean isRecipientAllowed(String server) { if (server.equalsIgnoreCase("generic.com")) { return true; } else { return false; } } /** * readAssetJSON - This method extracts information about the characteristics of a mail being sent. * * @param event The event as a Simple Events object. * * @return List<String> wifiValues * */ public List<String> readAssetJSON(SimpleEvents event){ List<String> wifiValues = new ArrayList<String>(); EventType eventTypeId = event.getEventType(); /* {id=3, wifiencryption=[WPA2-PSK-TKIP+CCMP][ESS], bssid=24:a4:3c:04:ae:09, * bluetoothconnected=FALSE, wifienabled=true, wifineighbors=6, hiddenssid=false, * networkid=1, wificonnected=true, airplanemode=false} */ if ((eventTypeId!=null)&&(eventTypeId.getEventTypeId() == 8)) { String wifiJSON = "(\\w+)\\=([\\w\\[\\]\\-\\+\\:\\d]+)"; Pattern wifiPattern = Pattern.compile(wifiJSON); Matcher matcherWifi = wifiPattern.matcher(event.getData()); while (matcherWifi.find()) { if(matcherWifi.group(1).equalsIgnoreCase("wifiencryption")) { wifiValues.add(matcherWifi.group(2)); } else if (matcherWifi.group(1).equalsIgnoreCase("bluetoothconnected")) { if(matcherWifi.group(2).equalsIgnoreCase("true")) { wifiValues.add("1"); } else { wifiValues.add("0"); } } else if (matcherWifi.group(1).equalsIgnoreCase("wifienabled")) { if(matcherWifi.group(2).contentEquals("true")) { wifiValues.add("1"); } else { wifiValues.add("0"); } } else if (matcherWifi.group(1).equalsIgnoreCase("wificonnected")) { if(matcherWifi.group(2).contentEquals("true")) { wifiValues.add("1"); } else { wifiValues.add("0"); } } } } return wifiValues; } public void printPattern (PatternsKrs pattern) { System.out.println("ActivatedAccount "+pattern.getActivatedAccount()); System.out.println("MusesAware "+pattern.getAppMUSESAware()); System.out.println("AppName "+pattern.getAppName()); System.out.println("AppVendor "+pattern.getAppVendor()); System.out.println("AssetConf "+pattern.getAssetConfidentialLevel()); System.out.println("AssetLoc "+pattern.getAssetLocation()); System.out.println("AssetName "+pattern.getAssetName()); System.out.println("AssetValue "+pattern.getAssetValue()); System.out.println("Btooth "+pattern.getBluetoothConnected()); System.out.println("DecisionCause "+pattern.getDecisionCause()); System.out.println("Accessibility "+pattern.getDeviceHasAccessibility()); System.out.println("Antivirus "+pattern.getDeviceHasAntivirus()); System.out.println("Cert "+pattern.getDeviceHasCertificate()); System.out.println("Passwd "+pattern.getDeviceHasPassword()); System.out.println("Rooted "+pattern.getDeviceIsRooted()); System.out.println("OS "+pattern.getDeviceOS()); System.out.println("Owner "+pattern.getDeviceOwnedBy()); System.out.println("DevTrust "+pattern.getDeviceTrustValue()); System.out.println("DevType "+pattern.getDeviceType()); System.out.println("EventLevel "+pattern.getEventLevel()); System.out.println("EventTime "+pattern.getEventTime()); System.out.println("EventType "+pattern.getEventType()); System.out.println("Label "+pattern.getLabel()); System.out.println("PasswdLetters "+pattern.getLettersInPassword()); System.out.println("MailBCC "+pattern.getMailContainsBCC()); System.out.println("MailCC "+pattern.getMailContainsCC()); System.out.println("MailAttach "+pattern.getMailHasAttachment()); System.out.println("MailTo "+pattern.getMailRecipientAllowed()); System.out.println("PasswdCaps "+pattern.getPasswdHasCapitalLetters()); System.out.println("PasswdLength "+pattern.getPasswordLength()); System.out.println("SilentM "+pattern.getSilentMode()); System.out.println("User "+pattern.getUsername()); System.out.println("Role "+pattern.getUserRole()); System.out.println("UserTrust "+pattern.getUserTrustValue()); System.out.println("WifiConn "+pattern.getWifiConnected()); System.out.println("WifiEnabled "+pattern.getWifiEnabled()); System.out.println("WifiEncryp "+pattern.getWifiEncryption()); } }