diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java index ce5b066d1e..8a57dd71ed 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/LeappFileProcessor.java @@ -77,6 +77,11 @@ import org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper; import org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper.CallMediaType; import org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper.CommunicationDirection; import org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper.MessageReadStatus; +import org.sleuthkit.datamodel.blackboardutils.GeoArtifactsHelper; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints.TrackPoint; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints.Waypoint; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments; import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments.FileAttachment; import org.w3c.dom.Document; @@ -149,24 +154,41 @@ public final class LeappFileProcessor { .build(); private static final Map ACCOUNT_RELATIONSHIPS = ImmutableMap.builder() - .put("Zapya.tsv", "message") + .put("zapya.tsv", "message") .put("sms messages.tsv", "message") .put("mms messages.tsv", "message") - .put("Viber - Messages.tsv", "message") - .put("Viber - Contacts.tsv", "contact") - .put("Viber - Call Logs.tsv", "calllog") - .put("Xender file transfer - Messages.tsv", "message") - .put("Whatsapp - Contacts.tsv", "contact") - .put("Whatsapp - Group Call Logs.tsv", "calllog") - .put("Whatsapp - Single Call Logs.tsv", "calllog") - .put("Whatsapp - Messages Logs.tsv", "message") - .put("Shareit file transfer.tsv", "message") + .put("viber - messages.tsv", "message") + .put("viber - contacts.tsv", "contact") + .put("viber - call logs.tsv", "calllog") + .put("xender file transfer - messages.tsv", "message") + .put("xender file transfer - contacts.tsv", "contact") + .put("whatsapp - contacts.tsv", "contact") + .put("whatsapp - group call logs.tsv", "calllog") + .put("whatsapp - single call logs.tsv", "calllog") + .put("whatsapp - messages logs.tsv", "message") + .put("shareit file transfer.tsv", "message") .put("tangomessages messages.tsv", "message") + .put("contacts.tsv", "contact") + .put("imo - accountid.tsv", "contact") + .put("imo - messages.tsv", "message") + .put("textnow - contacts.tsv", "contact") + .put("textnow - messages.tsv", "message") + .put("line - messages.tsv", "message") + .put("line - contacts.tsv", "contact") + .put("line - calllogs.tsv", "calllog") + .put("skype - messages logs.tsv", "message") + .put("skype - contacts.tsv", "contact") + .put("skype - call logs.tsv", "calllog") + .put("facebook messenger - chats.tsv", "message") + .put("facebook messenger - contacts.tsv", "contact") + .put("facebook messenger - calls.tsv", "calllog") + .put("call logs2.tsv", "calllog") + .put("call logs.tsv", "calllog") + .put("oruxmaps tracks.tsv", "trackpoint") + .put("google map locations.tsv", "route") .put("Contacts.tsv", "contact") - .put("IMO - AccountId.tsv", "contact") - .put("IMO - messages.tsv", "message") - .put("SMS - iMessage.tsv", "message") - .put("Call History.tsv", "calllog") + .put("sms - imessage.tsv", "message") + .put("call history.tsv", "calllog") .build(); Blackboard blkBoard; @@ -319,6 +341,10 @@ public final class LeappFileProcessor { List bbartifacts, Content dataSource) throws FileNotFoundException, IOException, IngestModuleException, TskCoreException { + String trackpointSegmentName = null; + GeoTrackPoints pointList = new GeoTrackPoints(); + AbstractFile geoAbstractFile = null; + if (LeappFile == null || !LeappFile.exists() || fileName == null) { logger.log(Level.WARNING, String.format("Leap file: %s is null or does not exist", LeappFile == null ? LeappFile.toString() : "")); return; @@ -349,7 +375,7 @@ public final class LeappFileProcessor { Collection bbattributes = processReadLine(columnItems, columnIndexes, attrList, fileName, lineNum); if (!bbattributes.isEmpty()) { - switch (ACCOUNT_RELATIONSHIPS.getOrDefault(fileName, "norelationship").toLowerCase()) { + switch (ACCOUNT_RELATIONSHIPS.getOrDefault(fileName.toLowerCase(), "norelationship").toLowerCase()) { case "message": createMessageRelationship(bbattributes, dataSource, fileName); break; @@ -359,6 +385,12 @@ public final class LeappFileProcessor { case "calllog": createCalllogRelationship(bbattributes, dataSource, fileName); break; + case "route": + createRoute(bbattributes, dataSource, fileName); + break; + case "trackpoint": + geoAbstractFile = createTrackpoint(bbattributes, dataSource, fileName, trackpointSegmentName, pointList); + break; default: // There is no relationship defined so just process the artifact normally BlackboardArtifact bbartifact = createArtifactWithAttributes(artifactType.getTypeID(), dataSource, bbattributes); if (bbartifact != null) { @@ -372,8 +404,158 @@ public final class LeappFileProcessor { } } } + + try { + if (ACCOUNT_RELATIONSHIPS.getOrDefault(fileName.toLowerCase(), "norelationship").toLowerCase() == "trackpoint") { + (new GeoArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, "", geoAbstractFile)).addTrack(trackpointSegmentName, pointList, new ArrayList<>()); + + } + } catch (NoCurrentCaseException | TskCoreException | BlackboardException ex) { + throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_message_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS + } + } + @NbBundle.Messages({ + "LeappFileProcessor.cannot.create.waypoint.relationship=Cannot create TSK_WAYPOINT artifact.", + }) + + private void createRoute (Collection bbattributes, Content dataSource, String fileName) throws IngestModuleException { + + Double startLatitude = Double.valueOf(0); + Double startLongitude = Double.valueOf(0); + Double endLatitude = Double.valueOf(0); + Double endLongitude = Double.valueOf(0); + Double zeroValue = Double.valueOf(0); + String destinationName = ""; + String locationName = ""; + Long dateTime = Long.valueOf(0); + Collection otherAttributes = new ArrayList<>(); + String sourceFile = null; + AbstractFile absFile = null; + String comment = ""; + + try { + for (BlackboardAttribute bba : bbattributes) { + switch (bba.getAttributeType().getTypeName()) { + case "TSK_GEO_LATITUDE_START": + startLatitude = bba.getValueDouble(); + break; + case "TSK_GEO_LONGITUDE_START": + startLongitude = bba.getValueDouble(); + break; + case "TSK_GEO_LATITUDE_END": + startLatitude = bba.getValueDouble(); + break; + case "TSK_GEO_LONGITUDE_END": + startLongitude = bba.getValueDouble(); + break; + case "TSK_DATETIME": + dateTime = bba.getValueLong(); + break; + case "TSK_NAME": + destinationName = bba.getValueString(); + break; + case "TSK_LOCATION": + locationName = bba.getValueString(); + break; + case "TSK_TEXT_FILE": + sourceFile = bba.getValueString(); + break; + case "TSK_COMMENT": + comment = bba.getValueString(); + break; + default: + otherAttributes.add(bba); + break; + } + } + absFile = findAbstractFile(dataSource, sourceFile); + if (absFile == null) { + absFile = (AbstractFile) dataSource; + } + GeoWaypoints waypointList = new GeoWaypoints(); + waypointList.addPoint(new Waypoint(startLatitude, startLongitude, zeroValue, "")); + waypointList.addPoint(new Waypoint(endLatitude, endLongitude, zeroValue, locationName)); + (new GeoArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, comment, absFile)).addRoute(destinationName, dateTime, waypointList, new ArrayList<>()); + + } catch (NoCurrentCaseException | TskCoreException | BlackboardException ex) { + throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_waypoint_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS + } + + + } + + @NbBundle.Messages({ + "LeappFileProcessor.cannot.create.trackpoint.relationship=Cannot create TSK_TRACK_POINT artifact.", + }) + + private AbstractFile createTrackpoint(Collection bbattributes, Content dataSource, String fileName, String trackpointSegmentName, GeoTrackPoints pointList) throws IngestModuleException { + + Double latitude = Double.valueOf(0); + Double longitude = Double.valueOf(0); + Double altitude = Double.valueOf(0); + Double zeroValue = Double.valueOf(0); + String segmentName = null; + Long dateTime = Long.valueOf(0); + Collection otherAttributes = new ArrayList<>(); + String sourceFile = null; + String comment = null; + AbstractFile absFile = null; + + try { + for (BlackboardAttribute bba : bbattributes) { + switch (bba.getAttributeType().getTypeName()) { + case "TSK_GEO_LATITUDE": + latitude = bba.getValueDouble(); + break; + case "TSK_GEO_LONGITUDE": + longitude = bba.getValueDouble(); + break; + case "TSK_GEO_ALTITUDE": + altitude = bba.getValueDouble(); + break; + case "TSK_DATETIME": + dateTime = bba.getValueLong(); + break; + case "TSK_NAME": + segmentName = bba.getValueString(); + break; + case "TSK_TEXT_FILE": + sourceFile = bba.getValueString(); + break; + case "TSK_COMMENT": + comment = bba.getValueString(); + otherAttributes.add(bba); + break; + default: + otherAttributes.add(bba); + break; + } + } + absFile = findAbstractFile(dataSource, sourceFile); + if (absFile == null) { + absFile = (AbstractFile) dataSource; + } + if ((trackpointSegmentName == null) || (trackpointSegmentName == segmentName)) { + trackpointSegmentName = segmentName; + pointList.addPoint(new TrackPoint(latitude, longitude, altitude, segmentName, zeroValue, zeroValue, zeroValue, dateTime)); + } else { + (new GeoArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, comment, absFile)).addTrack(segmentName, pointList, new ArrayList<>()); + trackpointSegmentName = segmentName; + pointList = new GeoTrackPoints(); + pointList.addPoint(new TrackPoint(latitude, longitude, altitude, segmentName, zeroValue, zeroValue, zeroValue, dateTime)); + + } + } catch (NoCurrentCaseException | TskCoreException | BlackboardException ex) { + throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_trackpoint_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS + } + + return absFile; + + } + + @NbBundle.Messages({ "LeappFileProcessor.cannot.create.message.relationship=Cannot create TSK_MESSAGE Relationship.", }) @@ -381,6 +563,7 @@ public final class LeappFileProcessor { private void createMessageRelationship(Collection bbattributes, Content dataSource, String fileName) throws IngestModuleException { String messageType = null; + String alternateId = null; CommunicationDirection communicationDirection = CommunicationDirection.UNKNOWN; String senderId = null; String receipentId = null; @@ -442,6 +625,10 @@ public final class LeappFileProcessor { case "TSK_SUBJECT": subject = bba.getValueString(); break; + case "TSK_ID": + alternateId = bba.getValueString(); + otherAttributes.add(bba); + break; default: otherAttributes.add(bba); break; @@ -450,11 +637,16 @@ public final class LeappFileProcessor { AbstractFile absFile = findAbstractFile(dataSource, sourceFile); if (absFile == null) { absFile = (AbstractFile) dataSource; - } Account.Type accountType = getAccountType(fileName); + } + Account.Type accountType = getAccountType(fileName); if ((absFile != null) || (accountType != null)) { CommunicationArtifactsHelper accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), moduleName, absFile, accountType); - BlackboardArtifact messageArtifact = accountArtifact.addMessage(messageType, communicationDirection, senderId, + } else { + accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), + moduleName, absFile, accountType, accountType, alternateId); + } + BlackboardArtifact messageArtifact = accountArtifact.addMessage(messageType, communicationDirection, senderId, receipentId, dateTime, messageStatus, subject, messageText, threadId, otherAttributes); if (!fileAttachments.isEmpty()) { @@ -468,6 +660,9 @@ public final class LeappFileProcessor { } + @NbBundle.Messages({ + "LeappFileProcessor.cannot.create.contact.relationship=Cannot create TSK_CONTACT Relationship.", + }) private void createContactRelationship(Collection bbattributes, Content dataSource, String fileName) throws IngestModuleException { String alternateId = null; @@ -506,6 +701,7 @@ public final class LeappFileProcessor { break; case "TSK_ID": alternateId = bba.getValueString(); + otherAttributes.add(bba); break; default: otherAttributes.add(bba); @@ -513,8 +709,11 @@ public final class LeappFileProcessor { } } AbstractFile absFile = findAbstractFile(dataSource, sourceFile); + if (absFile == null) { + absFile = (AbstractFile) dataSource; + } Account.Type accountType = getAccountType(fileName); - if ((absFile != null) || (accountType != null)) { + if (accountType != null) { CommunicationArtifactsHelper accountArtifact; if (alternateId == null) { @@ -527,14 +726,18 @@ public final class LeappFileProcessor { BlackboardArtifact messageArtifact = accountArtifact.addContact(contactName, phoneNumber, homePhoneNumber, mobilePhoneNumber, emailAddr, otherAttributes); } } catch (NoCurrentCaseException | TskCoreException | BlackboardException ex) { - throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_message_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS + throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_contact_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS } - } + @NbBundle.Messages({ + "LeappFileProcessor.cannot.create.calllog.relationship=Cannot create TSK_CALLLOG Relationship.", + }) + private void createCalllogRelationship(Collection bbattributes, Content dataSource, String fileName) throws IngestModuleException { String callerId = null; + String alternateId = null; List calleeId = Arrays.asList(); CommunicationDirection communicationDirection = CommunicationDirection.UNKNOWN; Long startDateTime = Long.valueOf(0); @@ -573,6 +776,10 @@ public final class LeappFileProcessor { calleeId = Arrays.asList(calleeTempList); } break; + case "TSK_ID": + alternateId = bba.getValueString(); + otherAttributes.add(bba); + break; default: otherAttributes.add(bba); break; @@ -585,14 +792,21 @@ public final class LeappFileProcessor { callerId = null; } AbstractFile absFile = findAbstractFile(dataSource, sourceFile); - Account.Type accountType = getAccountType(fileName); - if ((absFile != null) || (accountType != null)) { - CommunicationArtifactsHelper accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), - moduleName, absFile, accountType); - BlackboardArtifact callLogArtifact = accountArtifact.addCalllog(communicationDirection, callerId, calleeId, startDateTime, endDateTime, mediaType, otherAttributes); + if (absFile == null) { + absFile = (AbstractFile) dataSource; } + Account.Type accountType = getAccountType(fileName); + CommunicationArtifactsHelper accountArtifact; + if (accountType != null) { + accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), + moduleName, absFile, accountType); + } else { + accountArtifact = new CommunicationArtifactsHelper(Case.getCurrentCaseThrows().getSleuthkitCase(), + moduleName, absFile, accountType, accountType, alternateId); + } + BlackboardArtifact callLogArtifact = accountArtifact.addCalllog(communicationDirection, callerId, calleeId, startDateTime, endDateTime, mediaType, otherAttributes); } catch (NoCurrentCaseException | TskCoreException | BlackboardException ex) { - throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_message_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS + throw new IngestModuleException(Bundle.LeappFileProcessor_cannot_create_calllog_relationship() + ex.getLocalizedMessage(), ex); //NON-NLS } } @@ -609,6 +823,10 @@ public final class LeappFileProcessor { return Account.Type.IMO; case "imo - messages.tsv": return Account.Type.IMO; + case "textnow - contacts.tsv": + return Account.Type.TEXTNOW; + case "textnow - messages.tsv": + return Account.Type.TEXTNOW; case "mms messages.tsv": return Account.Type.PHONE; case "viber - call logs.tsv": @@ -619,6 +837,8 @@ public final class LeappFileProcessor { return Account.Type.VIBER; case "xender file transfer - messages.tsv": return Account.Type.XENDER; + case "xender file transfer - contacts.tsv": + return Account.Type.XENDER; case "whatsapp - single call logs.tsv": return Account.Type.WHATSAPP; case "whatsapp - messages logs.tsv": @@ -630,7 +850,29 @@ public final class LeappFileProcessor { case "tangomessages messages.tsv": return Account.Type.TANGO; case "shareit file transfer.tsv": - return Account.Type.SHAREIT; + return Account.Type.SHAREIT; + case "line - calllogs.tsv": + return Account.Type.LINE; + case "line - contacts.tsv": + return Account.Type.LINE; + case "line - messages.tsv": + return Account.Type.LINE; + case "skype - call logs.tsv": + return Account.Type.SKYPE; + case "skype - contacts.tsv": + return Account.Type.SKYPE; + case "skype - messages logs.tsv": + return Account.Type.SKYPE; + case "facebook messenger - calls.tsv": + return Account.Type.FACEBOOK; + case "facebook messenger - contacts.tsv": + return Account.Type.FACEBOOK; + case "facebook messenger - chats.tsv": + return Account.Type.FACEBOOK; + case "call logs2.tsv": + return Account.Type.PHONE; + case "call logs.tsv": + return Account.Type.PHONE; case "sms - imessage.tsv": return Account.Type.PHONE; default: diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/aleap-artifact-attribute-reference.xml b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/aleap-artifact-attribute-reference.xml index 27d3bc7263..e8f1ac3eb7 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/aleap-artifact-attribute-reference.xml +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/aleap-artifact-attribute-reference.xml @@ -396,8 +396,8 @@ - - + + @@ -405,7 +405,7 @@ - + @@ -447,45 +447,56 @@ - - - - - + + + + + - - - - - - + + + + + + + + + + + + + + + + + + - - + + - + - - - - - - - - + + + + + + + @@ -501,4 +512,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/aLeapp/aleapp.exe b/thirdparty/aLeapp/aleapp.exe index 71106090c0..3f47725616 100644 Binary files a/thirdparty/aLeapp/aleapp.exe and b/thirdparty/aLeapp/aleapp.exe differ