23 package org.sleuthkit.autopsy.recentactivity;
27 import java.text.ParseException;
28 import java.text.SimpleDateFormat;
30 import java.util.logging.Level;
31 import javax.xml.parsers.DocumentBuilder;
32 import javax.xml.parsers.DocumentBuilderFactory;
33 import javax.xml.parsers.ParserConfigurationException;
34 import org.openide.modules.InstalledFileLocator;
35 import org.openide.util.NbBundle;
44 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
45 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
46 import org.w3c.dom.Document;
47 import org.w3c.dom.Element;
48 import org.w3c.dom.Node;
49 import org.w3c.dom.NodeList;
50 import org.xml.sax.InputSource;
51 import org.xml.sax.SAXException;
52 import java.nio.file.Path;
53 import static java.util.TimeZone.getTimeZone;
54 import org.openide.util.Lookup;
60 import org.
sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
69 "RegRipperNotFound=Autopsy RegRipper executable not found.",
70 "RegRipperFullNotFound=Full version RegRipper executable not found.",
71 "Progress_Message_Analyze_Registry=Analyzing Registry Files"
73 class ExtractRegistry extends Extract {
75 private final Logger logger = Logger.getLogger(this.getClass().getName());
76 private String RR_PATH;
77 private String RR_FULL_PATH;
79 private Path rrFullHome;
80 private Content dataSource;
81 private IngestJobContext context;
82 final private static UsbDeviceIdMapper USB_MAPPER =
new UsbDeviceIdMapper();
83 final private static String RIP_EXE =
"rip.exe";
84 final private static String RIP_PL =
"rip.pl";
85 final private static int MS_IN_SEC = 1000;
86 final private static String NEVER_DATE =
"Never";
87 final private static String SECTION_DIVIDER =
"-------------------------";
88 private final List<String> rrCmd =
new ArrayList<>();
89 private final List<String> rrFullCmd =
new ArrayList<>();
91 ExtractRegistry() throws IngestModuleException {
92 moduleName = NbBundle.getMessage(ExtractIE.class,
"ExtractRegistry.moduleName.text");
94 final File rrRoot = InstalledFileLocator.getDefault().locate(
"rr", ExtractRegistry.class.getPackage().getName(),
false);
96 throw new IngestModuleException(Bundle.RegRipperNotFound());
99 final File rrFullRoot = InstalledFileLocator.getDefault().locate(
"rr-full", ExtractRegistry.class.getPackage().getName(),
false);
100 if (rrFullRoot == null) {
101 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
104 String executableToRun = RIP_EXE;
105 if (!PlatformUtil.isWindowsOS()) {
106 executableToRun = RIP_PL;
108 rrHome = rrRoot.toPath();
109 RR_PATH = rrHome.resolve(executableToRun).toString();
110 rrFullHome = rrFullRoot.toPath();
111 RR_FULL_PATH = rrFullHome.resolve(executableToRun).toString();
113 if (!(
new File(RR_PATH).exists())) {
114 throw new IngestModuleException(Bundle.RegRipperNotFound());
116 if (!(
new File(RR_FULL_PATH).exists())) {
117 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
119 if (PlatformUtil.isWindowsOS()) {
121 rrFullCmd.add(RR_FULL_PATH);
124 File usrBin =
new File(
"/usr/bin/perl");
125 File usrLocalBin =
new File(
"/usr/local/bin/perl");
126 if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
127 perl =
"/usr/bin/perl";
128 }
else if (usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()) {
129 perl =
"/usr/local/bin/perl";
131 throw new IngestModuleException(
"perl not found in your system");
136 rrFullCmd.add(RR_FULL_PATH);
143 private List<AbstractFile> findRegistryFiles() {
144 List<AbstractFile> allRegistryFiles =
new ArrayList<>();
149 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"ntuser.dat"));
150 }
catch (TskCoreException ex) {
151 logger.log(Level.WARNING,
"Error fetching 'ntuser.dat' file.");
155 String[] regFileNames =
new String[]{
"system",
"software",
"security",
"sam"};
156 for (String regFileName : regFileNames) {
158 allRegistryFiles.addAll(fileManager.findFiles(dataSource, regFileName,
"/system32/config"));
159 }
catch (TskCoreException ex) {
160 String msg = NbBundle.getMessage(this.getClass(),
161 "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName);
162 logger.log(Level.WARNING, msg);
163 this.addErrorMessage(this.getName() +
": " + msg);
166 return allRegistryFiles;
173 private void analyzeRegistryFiles() {
174 List<AbstractFile> allRegistryFiles = findRegistryFiles();
177 FileWriter logFile = null;
179 logFile =
new FileWriter(RAImageIngestModule.getRAOutputPath(currentCase,
"reg") + File.separator +
"regripper-info.txt");
180 }
catch (IOException ex) {
181 logger.log(Level.SEVERE, null, ex);
184 for (AbstractFile regFile : allRegistryFiles) {
185 String regFileName = regFile.getName();
186 long regFileId = regFile.getId();
187 String regFileNameLocal = RAImageIngestModule.getRATempPath(currentCase,
"reg") + File.separator + regFileName;
188 String outputPathBase = RAImageIngestModule.getRAOutputPath(currentCase,
"reg") + File.separator + regFileName +
"-regripper-" + Long.toString(regFileId);
189 File regFileNameLocalFile =
new File(regFileNameLocal);
191 ContentUtils.writeToFile(regFile, regFileNameLocalFile, context::dataSourceIngestIsCancelled);
192 }
catch (ReadContentInputStreamException ex) {
193 logger.log(Level.WARNING, String.format(
"Error reading registry file '%s' (id=%d).",
194 regFile.getName(), regFileId), ex);
195 this.addErrorMessage(
196 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
197 this.getName(), regFileName));
199 }
catch (IOException ex) {
200 logger.log(Level.SEVERE, String.format(
"Error writing temp registry file '%s' for registry file '%s' (id=%d).",
201 regFileNameLocal, regFile.getName(), regFileId), ex);
202 this.addErrorMessage(
203 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
204 this.getName(), regFileName));
208 if (context.dataSourceIngestIsCancelled()) {
213 if (logFile != null) {
214 logFile.write(Long.toString(regFileId) +
"\t" + regFile.getUniquePath() +
"\n");
216 }
catch (TskCoreException | IOException ex) {
217 logger.log(Level.SEVERE, null, ex);
220 logger.log(Level.INFO,
"{0}- Now getting registry information from {1}",
new Object[]{moduleName, regFileNameLocal});
221 RegOutputFiles regOutputFiles = ripRegistryFile(regFileNameLocal, outputPathBase);
222 if (context.dataSourceIngestIsCancelled()) {
227 if (regOutputFiles.autopsyPlugins.isEmpty() ==
false) {
228 if (parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) ==
false) {
229 this.addErrorMessage(
230 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
231 this.getName(), regFileName));
236 if (!regOutputFiles.fullPlugins.isEmpty()) {
238 if (regFileNameLocal.toLowerCase().contains(
"sam")) {
239 if (parseSamPluginOutput(regOutputFiles.fullPlugins, regFile) ==
false) {
240 this.addErrorMessage(
241 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
242 this.getName(), regFileName));
246 Report report = currentCase.addReport(regOutputFiles.fullPlugins,
247 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.parentModuleName.noSpace"),
248 "RegRipper " + regFile.getUniquePath(), regFile);
251 KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class);
252 if (null == searchService) {
253 logger.log(Level.WARNING,
"Keyword search service not found. Report will not be indexed");
255 searchService.index(report);
257 }
catch (TskCoreException e) {
258 this.addErrorMessage(
"Error adding regripper output as Autopsy report: " + e.getLocalizedMessage());
263 regFileNameLocalFile.delete();
267 if (logFile != null) {
270 }
catch (IOException ex) {
271 logger.log(Level.SEVERE, null, ex);
277 public String autopsyPlugins =
"";
278 public String fullPlugins =
"";
288 private RegOutputFiles ripRegistryFile(String regFilePath, String outFilePathBase) {
289 String autopsyType =
"";
294 if (regFilePath.toLowerCase().contains(
"system")) {
295 autopsyType =
"autopsysystem";
297 }
else if (regFilePath.toLowerCase().contains(
"software")) {
298 autopsyType =
"autopsysoftware";
299 fullType =
"software";
300 }
else if (regFilePath.toLowerCase().contains(
"ntuser")) {
301 autopsyType =
"autopsyntuser";
303 }
else if (regFilePath.toLowerCase().contains(
"sam")) {
306 }
else if (regFilePath.toLowerCase().contains(
"security")) {
307 fullType =
"security";
309 return regOutputFiles;
313 if (!autopsyType.isEmpty()) {
315 String errFilePath = outFilePathBase +
"-autopsy.err.txt";
316 logger.log(Level.INFO,
"Writing RegRipper results to: {0}", regOutputFiles.
autopsyPlugins);
317 executeRegRipper(rrCmd, rrHome, regFilePath, autopsyType, regOutputFiles.
autopsyPlugins, errFilePath);
319 if (context.dataSourceIngestIsCancelled()) {
320 return regOutputFiles;
324 if (!fullType.isEmpty()) {
325 regOutputFiles.
fullPlugins = outFilePathBase +
"-full.txt";
326 String errFilePath = outFilePathBase +
"-full.err.txt";
327 logger.log(Level.INFO,
"Writing Full RegRipper results to: {0}", regOutputFiles.
fullPlugins);
328 executeRegRipper(rrFullCmd, rrFullHome, regFilePath, fullType, regOutputFiles.
fullPlugins, errFilePath);
330 return regOutputFiles;
333 private void executeRegRipper(List<String> regRipperPath, Path regRipperHomeDir, String hiveFilePath, String hiveFileType, String outputFile, String errFile) {
335 List<String> commandLine =
new ArrayList<>();
336 for (String cmd : regRipperPath) {
337 commandLine.add(cmd);
339 commandLine.add(
"-r");
340 commandLine.add(hiveFilePath);
341 commandLine.add(
"-f");
342 commandLine.add(hiveFileType);
344 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
345 processBuilder.directory(regRipperHomeDir.toFile());
346 processBuilder.redirectOutput(
new File(outputFile));
347 processBuilder.redirectError(
new File(errFile));
348 ExecUtil.execute(processBuilder,
new DataSourceIngestModuleProcessTerminator(context));
349 }
catch (IOException ex) {
350 logger.log(Level.SEVERE,
"Unable to run RegRipper", ex);
351 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getName()));
364 private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) {
365 FileInputStream fstream = null;
368 File regfile =
new File(regFilePath);
369 fstream =
new FileInputStream(regfile);
370 String regString =
new Scanner(fstream,
"UTF-8").useDelimiter(
"\\Z").next();
371 String startdoc =
"<?xml version=\"1.0\"?><document>";
372 String result = regString.replaceAll(
"----------------------------------------",
"");
373 result = result.replaceAll(
"\\n",
"");
374 result = result.replaceAll(
"\\r",
"");
375 result = result.replaceAll(
"'",
"'");
376 result = result.replaceAll(
"&",
"&");
377 result = result.replace(
'\0',
' ');
378 String enddoc =
"</document>";
379 String stringdoc = startdoc + result + enddoc;
380 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
381 Document doc = builder.parse(
new InputSource(
new StringReader(stringdoc)));
384 Element oroot = doc.getDocumentElement();
385 NodeList children = oroot.getChildNodes();
386 int len = children.getLength();
389 Collection<BlackboardArtifact> usbBBartifacts =
new ArrayList<>();
392 Collection<BlackboardArtifact> wifiBBartifacts =
new ArrayList<>();
393 for (
int i = 0; i < len; i++) {
394 Element tempnode = (Element) children.item(i);
396 String dataType = tempnode.getNodeName();
397 NodeList timenodes = tempnode.getElementsByTagName(
"mtime");
399 if (timenodes.getLength() > 0) {
400 Element timenode = (Element) timenodes.item(0);
401 String etime = timenode.getTextContent();
403 Long epochtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(etime).getTime();
405 String Tempdate = mtime.toString();
406 mtime = Long.valueOf(Tempdate) / MS_IN_SEC;
407 }
catch (ParseException ex) {
408 logger.log(Level.WARNING,
"Failed to parse epoch time when parsing the registry.");
412 NodeList artroots = tempnode.getElementsByTagName(
"artifacts");
413 if (artroots.getLength() == 0) {
418 Element artroot = (Element) artroots.item(0);
419 NodeList myartlist = artroot.getChildNodes();
420 String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName();
427 String systemRoot =
"";
428 String productId =
"";
429 String regOwner =
"";
431 Long installtime = null;
432 for (
int j = 0; j < myartlist.getLength(); j++) {
433 Node artchild = myartlist.item(j);
435 if (artchild.hasAttributes()) {
436 Element artnode = (Element) artchild;
438 String value = artnode.getTextContent().trim();
439 String name = artnode.getAttribute(
"name");
446 version = version +
" " + value;
454 case "RegisteredOwner":
457 case "RegisteredOrganization":
462 Long epochtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(value).getTime();
463 installtime = epochtime;
464 String Tempdate = installtime.toString();
465 installtime = Long.valueOf(Tempdate) / MS_IN_SEC;
466 }
catch (ParseException e) {
467 logger.log(Level.SEVERE,
"RegRipper::Conversion on DateTime -> ", e);
476 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
477 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, version));
478 if (installtime != null) {
479 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, installtime));
481 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, parentModuleName, systemRoot));
482 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID, parentModuleName, productId));
483 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER, parentModuleName, regOwner));
484 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION, parentModuleName, regOrg));
487 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
488 if (results.isEmpty()) {
489 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
490 bbart.addAttributes(bbattributes);
493 this.indexArtifact(bbart);
495 results.get(0).addAttributes(bbattributes);
498 }
catch (TskCoreException ex) {
499 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.");
504 String procArch =
"";
507 for (
int j = 0; j < myartlist.getLength(); j++) {
508 Node artchild = myartlist.item(j);
510 if (artchild.hasAttributes()) {
511 Element artnode = (Element) artchild;
513 String value = artnode.getTextContent().trim();
514 String name = artnode.getAttribute(
"name");
519 case "PROCESSOR_ARCHITECTURE":
522 case "PROCESSOR_IDENTIFIER":
534 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
535 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VERSION, parentModuleName, os));
536 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE, parentModuleName, procArch));
537 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR, parentModuleName, tempDir));
540 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
541 if (results.isEmpty()) {
542 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
543 bbart.addAttributes(bbattributes);
546 this.indexArtifact(bbart);
548 results.get(0).addAttributes(bbattributes);
550 }
catch (TskCoreException ex) {
551 logger.log(Level.SEVERE,
"Error adding os info artifact to blackboard.");
555 String compName =
"";
557 for (
int j = 0; j < myartlist.getLength(); j++) {
558 Node artchild = myartlist.item(j);
560 if (artchild.hasAttributes()) {
561 Element artnode = (Element) artchild;
563 String value = artnode.getTextContent().trim();
564 String name = artnode.getAttribute(
"name");
566 if (name.equals(
"ComputerName")) {
568 }
else if (name.equals(
"Domain")) {
574 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
575 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, compName));
576 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN, parentModuleName, domain));
579 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
580 if (results.isEmpty()) {
581 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
582 bbart.addAttributes(bbattributes);
585 this.indexArtifact(bbart);
587 results.get(0).addAttributes(bbattributes);
589 }
catch (TskCoreException ex) {
590 logger.log(Level.SEVERE,
"Error adding os info artifact to blackboard.");
594 for (
int j = 0; j < myartlist.getLength(); j++) {
595 Node artchild = myartlist.item(j);
597 if (artchild.hasAttributes()) {
598 Element artnode = (Element) artchild;
600 String value = artnode.getTextContent().trim();
601 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
614 Long usbMtime = Long.parseLong(artnode.getAttribute(
"mtime"));
615 usbMtime = Long.valueOf(usbMtime.toString());
617 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED);
618 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, usbMtime));
619 String dev = artnode.getAttribute(
"dev");
622 if (dev.toLowerCase().contains(
"vid")) {
623 USBInfo info = USB_MAPPER.parseAndLookup(dev);
624 if (info.getVendor() != null) {
625 make = info.getVendor();
627 if (info.getProduct() != null) {
628 model = info.getProduct();
631 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE, parentModuleName, make));
632 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL, parentModuleName, model));
633 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, value));
634 bbart.addAttributes(bbattributes);
637 this.indexArtifact(bbart);
639 usbBBartifacts.add(bbart);
640 }
catch (TskCoreException ex) {
641 logger.log(Level.SEVERE,
"Error adding device attached artifact to blackboard.");
645 Long itemMtime = null;
647 Long epochtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(artnode.getAttribute(
"mtime")).getTime();
648 itemMtime = epochtime;
649 itemMtime = itemMtime / MS_IN_SEC;
650 }
catch (ParseException e) {
651 logger.log(Level.WARNING,
"Failed to parse epoch time for installed program artifact.");
655 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value));
656 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime));
657 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_INSTALLED_PROG);
658 bbart.addAttributes(bbattributes);
661 this.indexArtifact(bbart);
662 }
catch (TskCoreException ex) {
663 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.");
667 String officeName = artnode.getAttribute(
"name");
670 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
673 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, parentModuleName, mtime));
675 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, officeName));
676 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, parentModuleName, value));
677 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, artnode.getNodeName()));
678 bbart.addAttributes(bbattributes);
681 this.indexArtifact(bbart);
682 }
catch (TskCoreException ex) {
683 logger.log(Level.SEVERE,
"Error adding recent object artifact to blackboard.");
687 case "ProcessorArchitecture":
704 String homeDir = value;
705 String sid = artnode.getAttribute(
"sid");
706 String username = artnode.getAttribute(
"username");
707 BlackboardArtifact bbart = null;
710 ArrayList<BlackboardArtifact> existingArtifacts = currentCase.getSleuthkitCase().getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
711 for (BlackboardArtifact artifact : existingArtifacts) {
712 if (artifact.getDataSource().getId() == regFile.getDataSourceObjectId()) {
713 BlackboardAttribute attribute = artifact.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID));
714 if (attribute != null && attribute.getValueString().equals(sid)) {
720 }
catch (TskCoreException ex) {
721 logger.log(Level.WARNING,
"Error getting existing os account artifact", ex);
725 bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
726 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
727 parentModuleName, username));
728 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
729 parentModuleName, sid));
730 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
731 parentModuleName, homeDir));
734 BlackboardAttribute bbattr = bbart.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_NAME));
736 if (bbattr == null) {
737 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
738 parentModuleName, username));
740 bbattr = bbart.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH));
741 if (bbattr == null) {
742 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
743 parentModuleName, homeDir));
746 bbart.addAttributes(bbattributes);
748 this.indexArtifact(bbart);
749 }
catch (TskCoreException ex) {
750 logger.log(Level.SEVERE,
"Error adding account artifact to blackboard.");
754 case "NtuserNetwork":
756 String localPath = artnode.getAttribute(
"localPath");
757 String remoteName = value;
758 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_REMOTE_DRIVE);
759 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH,
760 parentModuleName, localPath));
761 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH,
762 parentModuleName, remoteName));
763 bbart.addAttributes(bbattributes);
765 this.indexArtifact(bbart);
766 }
catch (TskCoreException ex) {
767 logger.log(Level.SEVERE,
"Error adding network artifact to blackboard.");
771 String adapter = artnode.getAttribute(
"adapter");
773 Long lastWriteTime = Long.parseLong(artnode.getAttribute(
"writeTime"));
774 lastWriteTime = Long.valueOf(lastWriteTime.toString());
775 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SSID, parentModuleName, value));
776 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, lastWriteTime));
777 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, adapter));
778 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_WIFI_NETWORK);
779 bbart.addAttributes(bbattributes);
781 this.indexArtifact(bbart);
782 wifiBBartifacts.add(bbart);
783 }
catch (TskCoreException ex) {
784 logger.log(Level.SEVERE,
"Error adding SSID artifact to blackboard.");
794 logger.log(Level.WARNING,
"Unrecognized node name: {0}", dataType);
802 if (!usbBBartifacts.isEmpty()) {
803 IngestServices.getInstance().fireModuleDataEvent(
new ModuleDataEvent(moduleName, BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED, usbBBartifacts));
805 if (!wifiBBartifacts.isEmpty()) {
806 IngestServices.getInstance().fireModuleDataEvent(
new ModuleDataEvent(moduleName, BlackboardArtifact.ARTIFACT_TYPE.TSK_WIFI_NETWORK, wifiBBartifacts));
809 }
catch (FileNotFoundException ex) {
810 logger.log(Level.SEVERE,
"Error finding the registry file.", ex);
811 }
catch (SAXException ex) {
812 logger.log(Level.SEVERE,
"Error parsing the registry XML: {0}", ex);
813 }
catch (IOException ex) {
814 logger.log(Level.SEVERE,
"Error building the document parser: {0}", ex);
815 }
catch (ParserConfigurationException ex) {
816 logger.log(Level.SEVERE,
"Error configuring the registry parser: {0}", ex);
819 if (fstream != null) {
822 }
catch (IOException ex) {
837 private boolean parseSamPluginOutput(String regFilePath, AbstractFile regAbstractFile) {
838 File regfile =
new File(regFilePath);
839 String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName();
840 SimpleDateFormat regRipperTimeFormat =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'");
841 regRipperTimeFormat.setTimeZone(getTimeZone(
"GMT"));
842 try (BufferedReader bufferedReader =
new BufferedReader(
new FileReader(regfile))) {
844 String userInfoSection =
"User Information";
845 String previousLine = null;
846 String line = bufferedReader.readLine();
847 Set<UserInfo> userSet =
new HashSet<>();
848 while (line != null) {
849 if (line.contains(SECTION_DIVIDER) && previousLine != null) {
850 if (previousLine.contains(userInfoSection)) {
851 readUsers(bufferedReader, userSet);
855 line = bufferedReader.readLine();
857 Map<String, UserInfo> userInfoMap =
new HashMap<>();
859 for (UserInfo userInfo : userSet) {
860 userInfoMap.put(userInfo.getUserSid(), userInfo);
863 List<BlackboardArtifact> existingOsAccounts = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
864 for (BlackboardArtifact osAccount : existingOsAccounts) {
866 if (osAccount.getDataSource().getId() == regAbstractFile.getDataSourceObjectId()) {
867 BlackboardAttribute existingUserId = osAccount.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID));
868 if (existingUserId != null) {
869 UserInfo userInfo = userInfoMap.remove(existingUserId.getValueString().trim());
871 if (userInfo != null) {
872 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
873 if (userInfo.getAccountCreatedDate() != null && !userInfo.getAccountCreatedDate().equals(NEVER_DATE)) {
874 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
875 parentModuleName, regRipperTimeFormat.parse(userInfo.getAccountCreatedDate()).getTime() / MS_IN_SEC));
877 if (userInfo.getLastLoginDate() != null && !userInfo.getLastLoginDate().equals(NEVER_DATE)) {
878 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
879 parentModuleName, regRipperTimeFormat.parse(userInfo.getLastLoginDate()).getTime() / MS_IN_SEC));
881 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
882 parentModuleName, userInfo.getLoginCount()));
883 osAccount.addAttributes(bbattributes);
889 for (String userId : userInfoMap.keySet()) {
890 UserInfo userInfo = userInfoMap.get(userId);
891 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
892 BlackboardArtifact bbart = regAbstractFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
893 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
894 parentModuleName, userInfo.getUserName()));
895 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
896 parentModuleName, userId));
897 if (userInfo.getAccountCreatedDate() != null && !userInfo.getAccountCreatedDate().equals(NEVER_DATE)) {
898 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
899 parentModuleName, regRipperTimeFormat.parse(userInfo.getAccountCreatedDate()).getTime() / MS_IN_SEC));
901 if (userInfo.getLastLoginDate() != null && !userInfo.getLastLoginDate().equals(NEVER_DATE)) {
902 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
903 parentModuleName, regRipperTimeFormat.parse(userInfo.getLastLoginDate()).getTime() / MS_IN_SEC));
905 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
906 parentModuleName, userInfo.getLoginCount()));
907 bbart.addAttributes(bbattributes);
909 this.indexArtifact(bbart);
913 }
catch (FileNotFoundException ex) {
914 logger.log(Level.SEVERE,
"Error finding the registry file.", ex);
915 }
catch (IOException ex) {
916 logger.log(Level.SEVERE,
"Error building the document parser: {0}", ex);
917 }
catch (ParseException ex) {
918 logger.log(Level.SEVERE,
"Error parsing the the date from the registry file", ex);
919 }
catch (TskCoreException ex) {
920 logger.log(Level.SEVERE,
"Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex);
936 private void readUsers(BufferedReader bufferedReader, Set<UserInfo> users)
throws IOException {
937 String userNameLabel =
"Username :";
938 String sidLabel =
"SID :";
939 String accountCreatedLabel =
"Account Created :";
940 String loginCountLabel =
"Login Count :";
941 String lastLoginLabel =
"Last Login Date :";
942 String line = bufferedReader.readLine();
944 String userName =
"";
945 while (line != null && !line.contains(SECTION_DIVIDER)) {
947 if (line.contains(userNameLabel)) {
948 String userNameAndIdString = line.replace(userNameLabel,
"");
949 userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf(
'[')).trim();
951 else if (line.contains(sidLabel) && !userName.isEmpty()){
952 String sid = line.replace(sidLabel,
"").trim();
953 UserInfo userInfo =
new UserInfo(userName, sid);
955 line = bufferedReader.readLine();
956 while (line != null && !line.isEmpty()) {
957 if (line.contains(accountCreatedLabel)) {
958 userInfo.setAccountCreatedDate(line.replace(accountCreatedLabel,
"").trim());
959 }
else if (line.contains(loginCountLabel)) {
960 userInfo.setLoginCount(Integer.parseInt(line.replace(loginCountLabel,
"").trim()));
961 }
else if (line.contains(lastLoginLabel)) {
962 userInfo.setLastLoginDate(line.replace(lastLoginLabel,
"").trim());
964 line = bufferedReader.readLine();
969 line = bufferedReader.readLine();
974 public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
975 this.dataSource = dataSource;
976 this.context = context;
978 progressBar.progress(Bundle.Progress_Message_Analyze_Registry());
979 analyzeRegistryFiles();
993 private int loginCount = 0;
1003 userSid = userSidString;
1011 String getUserName() {
1020 String getUserSid() {
1029 String getLastLoginDate() {
1030 return lastLoginDate;
1038 void setLastLoginDate(String lastLoginDate) {
1039 this.lastLoginDate = lastLoginDate;
1047 String getAccountCreatedDate() {
1048 return accountCreatedDate;
1056 void setAccountCreatedDate(String accountCreatedDate) {
1057 this.accountCreatedDate = accountCreatedDate;
1065 int getLoginCount() {
1074 void setLoginCount(
int loginCount) {
1075 this.loginCount = loginCount;