23 package org.sleuthkit.autopsy.recentactivity;
25 import java.io.BufferedReader;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.FileReader;
30 import java.io.FileWriter;
31 import java.io.IOException;
32 import java.io.StringReader;
33 import java.text.ParseException;
34 import java.text.SimpleDateFormat;
35 import java.util.logging.Level;
36 import javax.xml.parsers.DocumentBuilder;
37 import javax.xml.parsers.DocumentBuilderFactory;
38 import javax.xml.parsers.ParserConfigurationException;
39 import org.openide.modules.InstalledFileLocator;
40 import org.openide.util.NbBundle;
48 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
49 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
50 import org.w3c.dom.Document;
51 import org.w3c.dom.Element;
52 import org.w3c.dom.Node;
53 import org.w3c.dom.NodeList;
54 import org.xml.sax.InputSource;
55 import org.xml.sax.SAXException;
56 import java.nio.file.Path;
57 import java.util.ArrayList;
58 import java.util.List;
59 import java.util.Collection;
60 import java.util.HashMap;
62 import java.util.Scanner;
64 import java.util.HashSet;
65 import static java.util.TimeZone.getTimeZone;
66 import org.openide.util.Lookup;
76 import org.
sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
87 "RegRipperNotFound=Autopsy RegRipper executable not found.",
88 "RegRipperFullNotFound=Full version RegRipper executable not found.",
89 "Progress_Message_Analyze_Registry=Analyzing Registry Files"
91 class ExtractRegistry extends Extract {
93 final private static UsbDeviceIdMapper USB_MAPPER =
new UsbDeviceIdMapper();
94 final private static String RIP_EXE =
"rip.exe";
95 final private static String RIP_PL =
"rip.pl";
96 final private static int MS_IN_SEC = 1000;
97 final private static String NEVER_DATE =
"Never";
98 final private static String SECTION_DIVIDER =
"-------------------------";
99 final private static Logger logger = Logger.getLogger(ExtractRegistry.class.getName());
100 private final List<String> rrCmd =
new ArrayList<>();
101 private final List<String> rrFullCmd =
new ArrayList<>();
102 private final Path rrHome;
103 private final Path rrFullHome;
104 private Content dataSource;
105 private IngestJobContext context;
107 ExtractRegistry() throws IngestModuleException {
108 moduleName = NbBundle.getMessage(ExtractIE.class,
"ExtractRegistry.moduleName.text");
110 final File rrRoot = InstalledFileLocator.getDefault().locate(
"rr", ExtractRegistry.class.getPackage().getName(),
false);
111 if (rrRoot == null) {
112 throw new IngestModuleException(Bundle.RegRipperNotFound());
115 final File rrFullRoot = InstalledFileLocator.getDefault().locate(
"rr-full", ExtractRegistry.class.getPackage().getName(),
false);
116 if (rrFullRoot == null) {
117 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
120 String executableToRun = RIP_EXE;
121 if (!PlatformUtil.isWindowsOS()) {
122 executableToRun = RIP_PL;
124 rrHome = rrRoot.toPath();
125 String rrPath = rrHome.resolve(executableToRun).toString();
126 rrFullHome = rrFullRoot.toPath();
128 if (!(
new File(rrPath).exists())) {
129 throw new IngestModuleException(Bundle.RegRipperNotFound());
131 String rrFullPath = rrFullHome.resolve(executableToRun).toString();
132 if (!(
new File(rrFullPath).exists())) {
133 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
135 if (PlatformUtil.isWindowsOS()) {
137 rrFullCmd.add(rrFullPath);
140 File usrBin =
new File(
"/usr/bin/perl");
141 File usrLocalBin =
new File(
"/usr/local/bin/perl");
142 if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
143 perl =
"/usr/bin/perl";
144 }
else if (usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()) {
145 perl =
"/usr/local/bin/perl";
147 throw new IngestModuleException(
"perl not found in your system");
152 rrFullCmd.add(rrFullPath);
159 private List<AbstractFile> findRegistryFiles() {
160 List<AbstractFile> allRegistryFiles =
new ArrayList<>();
165 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"ntuser.dat"));
166 }
catch (TskCoreException ex) {
167 logger.log(Level.WARNING,
"Error fetching 'ntuser.dat' file.");
171 String[] regFileNames =
new String[]{
"system",
"software",
"security",
"sam"};
172 for (String regFileName : regFileNames) {
174 allRegistryFiles.addAll(fileManager.findFiles(dataSource, regFileName,
"/system32/config"));
175 }
catch (TskCoreException ex) {
176 String msg = NbBundle.getMessage(this.getClass(),
177 "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName);
178 logger.log(Level.WARNING, msg);
179 this.addErrorMessage(this.getName() +
": " + msg);
182 return allRegistryFiles;
189 private void analyzeRegistryFiles() {
190 List<AbstractFile> allRegistryFiles = findRegistryFiles();
193 FileWriter logFile = null;
195 logFile =
new FileWriter(RAImageIngestModule.getRAOutputPath(currentCase,
"reg") + File.separator +
"regripper-info.txt");
196 }
catch (IOException ex) {
197 logger.log(Level.SEVERE, null, ex);
200 for (AbstractFile regFile : allRegistryFiles) {
201 String regFileName = regFile.getName();
202 long regFileId = regFile.getId();
203 String regFileNameLocal = RAImageIngestModule.getRATempPath(currentCase,
"reg") + File.separator + regFileName;
204 String outputPathBase = RAImageIngestModule.getRAOutputPath(currentCase,
"reg") + File.separator + regFileName +
"-regripper-" + Long.toString(regFileId);
205 File regFileNameLocalFile =
new File(regFileNameLocal);
207 ContentUtils.writeToFile(regFile, regFileNameLocalFile, context::dataSourceIngestIsCancelled);
208 }
catch (ReadContentInputStreamException ex) {
209 logger.log(Level.WARNING, String.format(
"Error reading registry file '%s' (id=%d).",
210 regFile.getName(), regFileId), ex);
211 this.addErrorMessage(
212 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
213 this.getName(), regFileName));
215 }
catch (IOException ex) {
216 logger.log(Level.SEVERE, String.format(
"Error writing temp registry file '%s' for registry file '%s' (id=%d).",
217 regFileNameLocal, regFile.getName(), regFileId), ex);
218 this.addErrorMessage(
219 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
220 this.getName(), regFileName));
224 if (context.dataSourceIngestIsCancelled()) {
229 if (logFile != null) {
230 logFile.write(Long.toString(regFileId) +
"\t" + regFile.getUniquePath() +
"\n");
232 }
catch (TskCoreException | IOException ex) {
233 logger.log(Level.SEVERE, null, ex);
236 logger.log(Level.INFO,
"{0}- Now getting registry information from {1}",
new Object[]{moduleName, regFileNameLocal});
237 RegOutputFiles regOutputFiles = ripRegistryFile(regFileNameLocal, outputPathBase);
238 if (context.dataSourceIngestIsCancelled()) {
243 if (regOutputFiles.autopsyPlugins.isEmpty() ==
false && parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) ==
false) {
244 this.addErrorMessage(
245 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
246 this.getName(), regFileName));
250 if (!regOutputFiles.fullPlugins.isEmpty()) {
252 if (regFileNameLocal.toLowerCase().contains(
"sam") && parseSamPluginOutput(regOutputFiles.fullPlugins, regFile) ==
false) {
253 this.addErrorMessage(
254 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
255 this.getName(), regFileName));
258 Report report = currentCase.addReport(regOutputFiles.fullPlugins,
259 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.parentModuleName.noSpace"),
260 "RegRipper " + regFile.getUniquePath(), regFile);
263 KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class);
264 if (null == searchService) {
265 logger.log(Level.WARNING,
"Keyword search service not found. Report will not be indexed");
267 searchService.index(report);
270 }
catch (TskCoreException e) {
271 this.addErrorMessage(
"Error adding regripper output as Autopsy report: " + e.getLocalizedMessage());
275 regFileNameLocalFile.delete();
279 if (logFile != null) {
282 }
catch (IOException ex) {
283 logger.log(Level.SEVERE, null, ex);
294 private RegOutputFiles ripRegistryFile(String regFilePath, String outFilePathBase) {
295 String autopsyType =
"";
298 RegOutputFiles regOutputFiles =
new RegOutputFiles();
300 if (regFilePath.toLowerCase().contains(
"system")) {
301 autopsyType =
"autopsysystem";
303 }
else if (regFilePath.toLowerCase().contains(
"software")) {
304 autopsyType =
"autopsysoftware";
305 fullType =
"software";
306 }
else if (regFilePath.toLowerCase().contains(
"ntuser")) {
307 autopsyType =
"autopsyntuser";
309 }
else if (regFilePath.toLowerCase().contains(
"sam")) {
312 }
else if (regFilePath.toLowerCase().contains(
"security")) {
313 fullType =
"security";
315 return regOutputFiles;
319 if (!autopsyType.isEmpty()) {
320 regOutputFiles.autopsyPlugins = outFilePathBase +
"-autopsy.txt";
321 String errFilePath = outFilePathBase +
"-autopsy.err.txt";
322 logger.log(Level.INFO,
"Writing RegRipper results to: {0}", regOutputFiles.autopsyPlugins);
323 executeRegRipper(rrCmd, rrHome, regFilePath, autopsyType, regOutputFiles.autopsyPlugins, errFilePath);
325 if (context.dataSourceIngestIsCancelled()) {
326 return regOutputFiles;
330 if (!fullType.isEmpty()) {
331 regOutputFiles.fullPlugins = outFilePathBase +
"-full.txt";
332 String errFilePath = outFilePathBase +
"-full.err.txt";
333 logger.log(Level.INFO,
"Writing Full RegRipper results to: {0}", regOutputFiles.fullPlugins);
334 executeRegRipper(rrFullCmd, rrFullHome, regFilePath, fullType, regOutputFiles.fullPlugins, errFilePath);
336 return regOutputFiles;
339 private void executeRegRipper(List<String> regRipperPath, Path regRipperHomeDir, String hiveFilePath, String hiveFileType, String outputFile, String errFile) {
341 List<String> commandLine =
new ArrayList<>();
342 for (String cmd : regRipperPath) {
343 commandLine.add(cmd);
345 commandLine.add(
"-r");
346 commandLine.add(hiveFilePath);
347 commandLine.add(
"-f");
348 commandLine.add(hiveFileType);
350 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
351 processBuilder.directory(regRipperHomeDir.toFile());
352 processBuilder.redirectOutput(
new File(outputFile));
353 processBuilder.redirectError(
new File(errFile));
354 ExecUtil.execute(processBuilder,
new DataSourceIngestModuleProcessTerminator(context));
355 }
catch (IOException ex) {
356 logger.log(Level.SEVERE,
"Unable to run RegRipper", ex);
357 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getName()));
370 private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) {
371 FileInputStream fstream = null;
374 File regfile =
new File(regFilePath);
375 fstream =
new FileInputStream(regfile);
376 String regString =
new Scanner(fstream,
"UTF-8").useDelimiter(
"\\Z").next();
377 String startdoc =
"<?xml version=\"1.0\"?><document>";
378 String result = regString.replaceAll(
"----------------------------------------",
"");
379 result = result.replaceAll(
"\\n",
"");
380 result = result.replaceAll(
"\\r",
"");
381 result = result.replaceAll(
"'",
"'");
382 result = result.replaceAll(
"&",
"&");
383 result = result.replace(
'\0',
' ');
384 String enddoc =
"</document>";
385 String stringdoc = startdoc + result + enddoc;
386 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
387 Document doc = builder.parse(
new InputSource(
new StringReader(stringdoc)));
390 Element oroot = doc.getDocumentElement();
391 NodeList children = oroot.getChildNodes();
392 int len = children.getLength();
395 Collection<BlackboardArtifact> usbBBartifacts =
new ArrayList<>();
398 Collection<BlackboardArtifact> wifiBBartifacts =
new ArrayList<>();
399 for (
int i = 0; i < len; i++) {
401 if (context.dataSourceIngestIsCancelled()) {
405 Element tempnode = (Element) children.item(i);
407 String dataType = tempnode.getNodeName();
408 NodeList timenodes = tempnode.getElementsByTagName(
"mtime");
410 if (timenodes.getLength() > 0) {
411 Element timenode = (Element) timenodes.item(0);
412 String etime = timenode.getTextContent();
414 if (etime != null && !etime.isEmpty()) {
416 mtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(etime).getTime();
417 String Tempdate = mtime.toString();
418 mtime = Long.valueOf(Tempdate) / MS_IN_SEC;
419 }
catch (ParseException ex) {
420 logger.log(Level.WARNING,
"Failed to parse epoch time when parsing the registry.", ex);
425 NodeList artroots = tempnode.getElementsByTagName(
"artifacts");
426 if (artroots.getLength() == 0) {
431 Element artroot = (Element) artroots.item(0);
432 NodeList myartlist = artroot.getChildNodes();
433 String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName();
439 String systemRoot =
"";
440 String productId =
"";
441 String regOwner =
"";
443 Long installtime = null;
444 for (
int j = 0; j < myartlist.getLength(); j++) {
445 Node artchild = myartlist.item(j);
447 if (artchild.hasAttributes()) {
448 Element artnode = (Element) artchild;
450 String value = artnode.getTextContent();
452 value = value.trim();
454 String name = artnode.getAttribute(
"name");
464 version = version +
" " + value;
472 case "RegisteredOwner":
475 case "RegisteredOrganization":
479 if (value != null && !value.isEmpty()) {
481 installtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(value).getTime();
482 String Tempdate = installtime.toString();
483 installtime = Long.valueOf(Tempdate) / MS_IN_SEC;
484 }
catch (ParseException e) {
485 logger.log(Level.SEVERE,
"RegRipper::Conversion on DateTime -> ", e);
495 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
496 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, version));
497 if (installtime != null) {
498 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, installtime));
500 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, parentModuleName, systemRoot));
501 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID, parentModuleName, productId));
502 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER, parentModuleName, regOwner));
503 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION, parentModuleName, regOrg));
506 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
507 if (results.isEmpty()) {
508 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
509 bbart.addAttributes(bbattributes);
512 this.indexArtifact(bbart);
514 results.get(0).addAttributes(bbattributes);
517 }
catch (TskCoreException ex) {
518 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.");
523 String procArch =
"";
525 for (
int j = 0; j < myartlist.getLength(); j++) {
526 Node artchild = myartlist.item(j);
528 if (artchild.hasAttributes()) {
529 Element artnode = (Element) artchild;
531 String value = artnode.getTextContent().trim();
532 String name = artnode.getAttribute(
"name");
537 case "PROCESSOR_ARCHITECTURE":
540 case "PROCESSOR_IDENTIFIER":
551 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
552 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VERSION, parentModuleName, os));
553 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE, parentModuleName, procArch));
554 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR, parentModuleName, tempDir));
557 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
558 if (results.isEmpty()) {
559 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
560 bbart.addAttributes(bbattributes);
563 this.indexArtifact(bbart);
565 results.get(0).addAttributes(bbattributes);
567 }
catch (TskCoreException ex) {
568 logger.log(Level.SEVERE,
"Error adding os info artifact to blackboard.");
572 String compName =
"";
574 for (
int j = 0; j < myartlist.getLength(); j++) {
575 Node artchild = myartlist.item(j);
577 if (artchild.hasAttributes()) {
578 Element artnode = (Element) artchild;
580 String value = artnode.getTextContent().trim();
581 String name = artnode.getAttribute(
"name");
583 if (name.equals(
"ComputerName")) {
585 }
else if (name.equals(
"Domain")) {
591 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
592 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, compName));
593 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN, parentModuleName, domain));
596 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
597 if (results.isEmpty()) {
598 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
599 bbart.addAttributes(bbattributes);
602 this.indexArtifact(bbart);
604 results.get(0).addAttributes(bbattributes);
606 }
catch (TskCoreException ex) {
607 logger.log(Level.SEVERE,
"Error adding os info artifact to blackboard.");
611 for (
int j = 0; j < myartlist.getLength(); j++) {
612 Node artchild = myartlist.item(j);
614 if (artchild.hasAttributes()) {
615 Element artnode = (Element) artchild;
617 String value = artnode.getTextContent().trim();
618 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
631 Long usbMtime = Long.parseLong(artnode.getAttribute(
"mtime"));
632 usbMtime = Long.valueOf(usbMtime.toString());
634 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED);
635 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, usbMtime));
636 String dev = artnode.getAttribute(
"dev");
639 if (dev.toLowerCase().contains(
"vid")) {
640 USBInfo info = USB_MAPPER.parseAndLookup(dev);
641 if (info.getVendor() != null) {
642 make = info.getVendor();
644 if (info.getProduct() != null) {
645 model = info.getProduct();
648 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE, parentModuleName, make));
649 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL, parentModuleName, model));
650 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, value));
651 bbart.addAttributes(bbattributes);
654 this.indexArtifact(bbart);
656 usbBBartifacts.add(bbart);
657 }
catch (TskCoreException ex) {
658 logger.log(Level.SEVERE,
"Error adding device attached artifact to blackboard.");
662 Long itemMtime = null;
664 String mTimeAttr = artnode.getAttribute(
"mtime");
665 if (mTimeAttr != null && !mTimeAttr.isEmpty()) {
666 itemMtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(mTimeAttr).getTime();
667 itemMtime /= MS_IN_SEC;
669 }
catch (ParseException e) {
670 logger.log(Level.WARNING,
"Failed to parse epoch time for installed program artifact.");
674 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value));
675 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime));
676 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_INSTALLED_PROG);
677 bbart.addAttributes(bbattributes);
680 this.indexArtifact(bbart);
681 }
catch (TskCoreException ex) {
682 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.");
686 String officeName = artnode.getAttribute(
"name");
689 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
692 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, parentModuleName, mtime));
694 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, officeName));
695 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, parentModuleName, value));
696 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, artnode.getNodeName()));
697 bbart.addAttributes(bbattributes);
700 this.indexArtifact(bbart);
701 }
catch (TskCoreException ex) {
702 logger.log(Level.SEVERE,
"Error adding recent object artifact to blackboard.");
706 case "ProcessorArchitecture":
723 String homeDir = value;
724 String sid = artnode.getAttribute(
"sid");
725 String username = artnode.getAttribute(
"username");
726 BlackboardArtifact bbart = null;
729 ArrayList<BlackboardArtifact> existingArtifacts = currentCase.getSleuthkitCase().getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
730 for (BlackboardArtifact artifact : existingArtifacts) {
731 if (artifact.getDataSource().getId() == regFile.getDataSourceObjectId()) {
732 BlackboardAttribute attribute = artifact.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID));
733 if (attribute != null && attribute.getValueString().equals(sid)) {
739 }
catch (TskCoreException ex) {
740 logger.log(Level.WARNING,
"Error getting existing os account artifact", ex);
744 bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
745 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
746 parentModuleName, username));
747 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
748 parentModuleName, sid));
749 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
750 parentModuleName, homeDir));
753 BlackboardAttribute bbattr = bbart.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_NAME));
755 if (bbattr == null) {
756 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
757 parentModuleName, username));
759 bbattr = bbart.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH));
760 if (bbattr == null) {
761 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
762 parentModuleName, homeDir));
765 bbart.addAttributes(bbattributes);
767 this.indexArtifact(bbart);
768 }
catch (TskCoreException ex) {
769 logger.log(Level.SEVERE,
"Error adding account artifact to blackboard.");
773 case "NtuserNetwork":
775 String localPath = artnode.getAttribute(
"localPath");
776 String remoteName = value;
777 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_REMOTE_DRIVE);
778 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH,
779 parentModuleName, localPath));
780 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH,
781 parentModuleName, remoteName));
782 bbart.addAttributes(bbattributes);
784 this.indexArtifact(bbart);
785 }
catch (TskCoreException ex) {
786 logger.log(Level.SEVERE,
"Error adding network artifact to blackboard.");
790 String adapter = artnode.getAttribute(
"adapter");
792 Long lastWriteTime = Long.parseLong(artnode.getAttribute(
"writeTime"));
793 lastWriteTime = Long.valueOf(lastWriteTime.toString());
794 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SSID, parentModuleName, value));
795 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, lastWriteTime));
796 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, adapter));
797 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_WIFI_NETWORK);
798 bbart.addAttributes(bbattributes);
800 this.indexArtifact(bbart);
801 wifiBBartifacts.add(bbart);
802 }
catch (TskCoreException ex) {
803 logger.log(Level.SEVERE,
"Error adding SSID artifact to blackboard.");
813 logger.log(Level.WARNING,
"Unrecognized node name: {0}", dataType);
821 if (!usbBBartifacts.isEmpty()) {
822 IngestServices.getInstance().fireModuleDataEvent(
new ModuleDataEvent(moduleName, BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED, usbBBartifacts));
824 if (!wifiBBartifacts.isEmpty()) {
825 IngestServices.getInstance().fireModuleDataEvent(
new ModuleDataEvent(moduleName, BlackboardArtifact.ARTIFACT_TYPE.TSK_WIFI_NETWORK, wifiBBartifacts));
828 }
catch (FileNotFoundException ex) {
829 logger.log(Level.SEVERE,
"Error finding the registry file.", ex);
830 }
catch (SAXException ex) {
831 logger.log(Level.SEVERE,
"Error parsing the registry XML.", ex);
832 }
catch (IOException ex) {
833 logger.log(Level.SEVERE,
"Error building the document parser.", ex);
834 }
catch (ParserConfigurationException ex) {
835 logger.log(Level.SEVERE,
"Error configuring the registry parser.", ex);
838 if (fstream != null) {
841 }
catch (IOException ex) {
856 private boolean parseSamPluginOutput(String regFilePath, AbstractFile regAbstractFile) {
857 File regfile =
new File(regFilePath);
858 String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName();
859 SimpleDateFormat regRipperTimeFormat =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'");
860 regRipperTimeFormat.setTimeZone(getTimeZone(
"GMT"));
861 try (BufferedReader bufferedReader =
new BufferedReader(
new FileReader(regfile))) {
863 String userInfoSection =
"User Information";
864 String previousLine = null;
865 String line = bufferedReader.readLine();
866 Set<UserInfo> userSet =
new HashSet<>();
867 while (line != null) {
868 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(userInfoSection)) {
869 readUsers(bufferedReader, userSet);
873 line = bufferedReader.readLine();
875 Map<String, UserInfo> userInfoMap =
new HashMap<>();
877 for (UserInfo userInfo : userSet) {
878 userInfoMap.put(userInfo.getUserSid(), userInfo);
881 List<BlackboardArtifact> existingOsAccounts = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
882 for (BlackboardArtifact osAccount : existingOsAccounts) {
884 if (osAccount.getDataSource().getId() == regAbstractFile.getDataSourceObjectId()) {
885 BlackboardAttribute existingUserId = osAccount.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID));
886 if (existingUserId != null) {
887 UserInfo userInfo = userInfoMap.remove(existingUserId.getValueString().trim());
889 if (userInfo != null) {
890 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
891 if (userInfo.getAccountCreatedDate() != null && !userInfo.getAccountCreatedDate().equals(NEVER_DATE)) {
892 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
893 parentModuleName, regRipperTimeFormat.parse(userInfo.getAccountCreatedDate()).getTime() / MS_IN_SEC));
895 if (userInfo.getLastLoginDate() != null && !userInfo.getLastLoginDate().equals(NEVER_DATE)) {
896 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
897 parentModuleName, regRipperTimeFormat.parse(userInfo.getLastLoginDate()).getTime() / MS_IN_SEC));
899 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
900 parentModuleName, userInfo.getLoginCount()));
901 osAccount.addAttributes(bbattributes);
907 for (String userId : userInfoMap.keySet()) {
908 UserInfo userInfo = userInfoMap.get(userId);
909 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
910 BlackboardArtifact bbart = regAbstractFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
911 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
912 parentModuleName, userInfo.getUserName()));
913 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
914 parentModuleName, userId));
915 if (userInfo.getAccountCreatedDate() != null && !userInfo.getAccountCreatedDate().equals(NEVER_DATE)) {
916 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
917 parentModuleName, regRipperTimeFormat.parse(userInfo.getAccountCreatedDate()).getTime() / MS_IN_SEC));
919 if (userInfo.getLastLoginDate() != null && !userInfo.getLastLoginDate().equals(NEVER_DATE)) {
920 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
921 parentModuleName, regRipperTimeFormat.parse(userInfo.getLastLoginDate()).getTime() / MS_IN_SEC));
923 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
924 parentModuleName, userInfo.getLoginCount()));
925 bbart.addAttributes(bbattributes);
927 this.indexArtifact(bbart);
931 }
catch (FileNotFoundException ex) {
932 logger.log(Level.SEVERE,
"Error finding the registry file.", ex);
933 }
catch (IOException ex) {
934 logger.log(Level.SEVERE,
"Error building the document parser: {0}", ex);
935 }
catch (ParseException ex) {
936 logger.log(Level.SEVERE,
"Error parsing the the date from the registry file", ex);
937 }
catch (TskCoreException ex) {
938 logger.log(Level.SEVERE,
"Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex);
954 private void readUsers(BufferedReader bufferedReader, Set<UserInfo> users)
throws IOException {
955 String userNameLabel =
"Username :";
956 String sidLabel =
"SID :";
957 String accountCreatedLabel =
"Account Created :";
958 String loginCountLabel =
"Login Count :";
959 String lastLoginLabel =
"Last Login Date :";
960 String line = bufferedReader.readLine();
962 String userName =
"";
963 while (line != null && !line.contains(SECTION_DIVIDER)) {
965 if (line.contains(userNameLabel)) {
966 String userNameAndIdString = line.replace(userNameLabel,
"");
967 userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf(
'[')).trim();
968 }
else if (line.contains(sidLabel) && !userName.isEmpty()) {
969 String sid = line.replace(sidLabel,
"").trim();
970 UserInfo userInfo =
new UserInfo(userName, sid);
972 line = bufferedReader.readLine();
973 while (line != null && !line.isEmpty()) {
974 if (line.contains(accountCreatedLabel)) {
975 userInfo.setAccountCreatedDate(line.replace(accountCreatedLabel,
"").trim());
976 }
else if (line.contains(loginCountLabel)) {
977 userInfo.setLoginCount(Integer.parseInt(line.replace(loginCountLabel,
"").trim()));
978 }
else if (line.contains(lastLoginLabel)) {
979 userInfo.setLastLoginDate(line.replace(lastLoginLabel,
"").trim());
981 line = bufferedReader.readLine();
986 line = bufferedReader.readLine();
991 public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
992 this.dataSource = dataSource;
993 this.context = context;
995 progressBar.progress(Bundle.Progress_Message_Analyze_Registry());
996 analyzeRegistryFiles();
1005 public String autopsyPlugins =
"";
1006 public String fullPlugins =
"";
1019 private int loginCount = 0;
1029 userSid = userSidString;
1037 String getUserName() {
1046 String getUserSid() {
1055 String getLastLoginDate() {
1056 return lastLoginDate;
1064 void setLastLoginDate(String lastLoginDate) {
1065 this.lastLoginDate = lastLoginDate;
1073 String getAccountCreatedDate() {
1074 return accountCreatedDate;
1082 void setAccountCreatedDate(String accountCreatedDate) {
1083 this.accountCreatedDate = accountCreatedDate;
1091 int getLoginCount() {
1100 void setLoginCount(
int loginCount) {
1101 this.loginCount = loginCount;