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.AbstractMap;
58 import java.util.ArrayList;
59 import java.util.List;
60 import java.util.Collection;
61 import java.util.HashMap;
63 import java.util.Scanner;
65 import java.util.HashSet;
66 import static java.util.TimeZone.getTimeZone;
67 import org.openide.util.Lookup;
75 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED;
76 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED;
77 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED;
78 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH;
80 import org.
sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
92 "RegRipperNotFound=Autopsy RegRipper executable not found.",
93 "RegRipperFullNotFound=Full version RegRipper executable not found.",
94 "Progress_Message_Analyze_Registry=Analyzing Registry Files",
95 "Shellbag_Artifact_Display_Name=Shell Bags",
96 "Shellbag_Key_Attribute_Display_Name=Key",
97 "Shellbag_Last_Write_Attribute_Display_Name=Last Write"
99 class ExtractRegistry extends Extract {
101 private static final String USERNAME_KEY =
"Username";
102 private static final String SID_KEY =
"SID";
103 private static final String RID_KEY =
"RID";
104 private static final String ACCOUNT_CREATED_KEY =
"Account Created";
105 private static final String LAST_LOGIN_KEY =
"Last Login Date";
106 private static final String LOGIN_COUNT_KEY =
"Login Count";
107 private static final String FULL_NAME_KEY =
"Full Name";
108 private static final String USER_COMMENT_KEY =
"User Comment";
109 private static final String ACCOUNT_TYPE_KEY =
"Account Type";
110 private static final String NAME_KEY =
"Name";
111 private static final String PWD_RESET_KEY =
"Pwd Rest Date";
112 private static final String PWD_FAILE_KEY =
"Pwd Fail Date";
113 private static final String INTERNET_NAME_KEY =
"InternetName";
114 private static final String PWD_DOES_NOT_EXPIRE_KEY =
"Password does not expire";
115 private static final String ACCOUNT_DISABLED_KEY =
"Account Disabled";
116 private static final String PWD_NOT_REQUIRED_KEY =
"Password not required";
117 private static final String NORMAL_ACCOUNT_KEY =
"Normal user account";
118 private static final String HOME_DIRECTORY_REQUIRED_KEY =
"Home directory required";
119 private static final String TEMPORARY_DUPLICATE_ACCOUNT =
"Temporary duplicate account";
120 private static final String MNS_LOGON_ACCOUNT_KEY =
"MNS logon user account";
121 private static final String INTERDOMAIN_TRUST_ACCOUNT_KEY =
"Interdomain trust account";
122 private static final String WORKSTATION_TRUST_ACCOUNT =
"Workstation trust account";
123 private static final String SERVER_TRUST_ACCOUNT =
"Server trust account";
124 private static final String ACCOUNT_AUTO_LOCKED =
"Account auto locked";
125 private static final String PASSWORD_HINT =
"Password Hint";
127 private static final String[] PASSWORD_SETTINGS_FLAGS = {PWD_DOES_NOT_EXPIRE_KEY, PWD_NOT_REQUIRED_KEY};
128 private static final String[] ACCOUNT_SETTINGS_FLAGS = {ACCOUNT_AUTO_LOCKED, HOME_DIRECTORY_REQUIRED_KEY, ACCOUNT_DISABLED_KEY};
129 private static final String[] ACCOUNT_TYPE_FLAGS = {NORMAL_ACCOUNT_KEY, SERVER_TRUST_ACCOUNT, WORKSTATION_TRUST_ACCOUNT, INTERDOMAIN_TRUST_ACCOUNT_KEY, MNS_LOGON_ACCOUNT_KEY, TEMPORARY_DUPLICATE_ACCOUNT};
131 final private static UsbDeviceIdMapper USB_MAPPER =
new UsbDeviceIdMapper();
132 final private static String RIP_EXE =
"rip.exe";
133 final private static String RIP_PL =
"rip.pl";
134 final private static int MS_IN_SEC = 1000;
135 final private static String NEVER_DATE =
"Never";
136 final private static String SECTION_DIVIDER =
"-------------------------";
137 final private static Logger logger = Logger.getLogger(ExtractRegistry.class.getName());
138 private final List<String> rrCmd =
new ArrayList<>();
139 private final List<String> rrFullCmd =
new ArrayList<>();
140 private final Path rrHome;
141 private final Path rrFullHome;
142 private Content dataSource;
143 private IngestJobContext context;
145 private static final String SHELLBAG_ARTIFACT_NAME =
"RA_SHELL_BAG";
146 private static final String SHELLBAG_ATTRIBUTE_LAST_WRITE =
"RA_SHELL_BAG_LAST_WRITE";
147 private static final String SHELLBAG_ATTRIBUTE_KEY=
"RA_SHELL_BAG_KEY";
149 BlackboardArtifact.Type shellBagArtifactType = null;
150 BlackboardAttribute.Type shellBagKeyAttributeType = null;
151 BlackboardAttribute.Type shellBagLastWriteAttributeType = null;
153 ExtractRegistry() throws IngestModuleException {
154 moduleName = NbBundle.getMessage(ExtractIE.class,
"ExtractRegistry.moduleName.text");
156 final File rrRoot = InstalledFileLocator.getDefault().locate(
"rr", ExtractRegistry.class.getPackage().getName(),
false);
157 if (rrRoot == null) {
158 throw new IngestModuleException(Bundle.RegRipperNotFound());
161 final File rrFullRoot = InstalledFileLocator.getDefault().locate(
"rr-full", ExtractRegistry.class.getPackage().getName(),
false);
162 if (rrFullRoot == null) {
163 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
166 String executableToRun = RIP_EXE;
167 if (!PlatformUtil.isWindowsOS()) {
168 executableToRun = RIP_PL;
170 rrHome = rrRoot.toPath();
171 String rrPath = rrHome.resolve(executableToRun).toString();
172 rrFullHome = rrFullRoot.toPath();
174 if (!(
new File(rrPath).exists())) {
175 throw new IngestModuleException(Bundle.RegRipperNotFound());
177 String rrFullPath = rrFullHome.resolve(executableToRun).toString();
178 if (!(
new File(rrFullPath).exists())) {
179 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
181 if (PlatformUtil.isWindowsOS()) {
183 rrFullCmd.add(rrFullPath);
186 File usrBin =
new File(
"/usr/bin/perl");
187 File usrLocalBin =
new File(
"/usr/local/bin/perl");
188 if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
189 perl =
"/usr/bin/perl";
190 }
else if (usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()) {
191 perl =
"/usr/local/bin/perl";
193 throw new IngestModuleException(
"perl not found in your system");
198 rrFullCmd.add(rrFullPath);
205 private List<AbstractFile> findRegistryFiles() {
206 List<AbstractFile> allRegistryFiles =
new ArrayList<>();
211 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"ntuser.dat"));
212 }
catch (TskCoreException ex) {
213 logger.log(Level.WARNING,
"Error fetching 'ntuser.dat' file.");
218 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"usrclass.dat"));
219 }
catch (TskCoreException ex) {
220 logger.log(Level.WARNING, String.format(
"Error finding 'usrclass.dat' files."), ex);
224 String[] regFileNames =
new String[]{
"system",
"software",
"security",
"sam"};
225 for (String regFileName : regFileNames) {
227 allRegistryFiles.addAll(fileManager.findFiles(dataSource, regFileName,
"/system32/config"));
228 }
catch (TskCoreException ex) {
229 String msg = NbBundle.getMessage(this.getClass(),
230 "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName);
231 logger.log(Level.WARNING, msg, ex);
232 this.addErrorMessage(this.getName() +
": " + msg);
235 return allRegistryFiles;
242 private void analyzeRegistryFiles() {
243 List<AbstractFile> allRegistryFiles = findRegistryFiles();
246 FileWriter logFile = null;
248 logFile =
new FileWriter(RAImageIngestModule.getRAOutputPath(currentCase,
"reg") + File.separator +
"regripper-info.txt");
249 }
catch (IOException ex) {
250 logger.log(Level.SEVERE, null, ex);
253 for (AbstractFile regFile : allRegistryFiles) {
254 String regFileName = regFile.getName();
255 long regFileId = regFile.getId();
256 String regFileNameLocal = RAImageIngestModule.getRATempPath(currentCase,
"reg") + File.separator + regFileName;
257 String outputPathBase = RAImageIngestModule.getRAOutputPath(currentCase,
"reg") + File.separator + regFileName +
"-regripper-" + Long.toString(regFileId);
258 File regFileNameLocalFile =
new File(regFileNameLocal);
260 ContentUtils.writeToFile(regFile, regFileNameLocalFile, context::dataSourceIngestIsCancelled);
261 }
catch (ReadContentInputStreamException ex) {
262 logger.log(Level.WARNING, String.format(
"Error reading registry file '%s' (id=%d).",
263 regFile.getName(), regFileId), ex);
264 this.addErrorMessage(
265 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
266 this.getName(), regFileName));
268 }
catch (IOException ex) {
269 logger.log(Level.SEVERE, String.format(
"Error writing temp registry file '%s' for registry file '%s' (id=%d).",
270 regFileNameLocal, regFile.getName(), regFileId), ex);
271 this.addErrorMessage(
272 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
273 this.getName(), regFileName));
277 if (context.dataSourceIngestIsCancelled()) {
282 if (logFile != null) {
283 logFile.write(Long.toString(regFileId) +
"\t" + regFile.getUniquePath() +
"\n");
285 }
catch (TskCoreException | IOException ex) {
286 logger.log(Level.SEVERE, null, ex);
289 logger.log(Level.INFO,
"{0}- Now getting registry information from {1}",
new Object[]{moduleName, regFileNameLocal});
290 RegOutputFiles regOutputFiles = ripRegistryFile(regFileNameLocal, outputPathBase);
291 if (context.dataSourceIngestIsCancelled()) {
296 if (regOutputFiles.autopsyPlugins.isEmpty() ==
false && parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) ==
false) {
297 this.addErrorMessage(
298 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
299 this.getName(), regFileName));
303 if (!regOutputFiles.fullPlugins.isEmpty()) {
305 if (regFileNameLocal.toLowerCase().contains(
"sam") && parseSamPluginOutput(regOutputFiles.fullPlugins, regFile) ==
false) {
306 this.addErrorMessage(
307 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
308 this.getName(), regFileName));
309 }
else if (regFileNameLocal.toLowerCase().contains(
"ntuser") || regFileNameLocal.toLowerCase().contains(
"usrclass")) {
311 List<ShellBag> shellbags = ShellBagParser.parseShellbagOutput(regOutputFiles.fullPlugins);
312 createShellBagArtifacts(regFile, shellbags);
313 }
catch (IOException | TskCoreException ex) {
314 logger.log(Level.WARNING, String.format(
"Unable to get shell bags from file %s", regOutputFiles.fullPlugins), ex);
318 Report report = currentCase.addReport(regOutputFiles.fullPlugins,
319 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.parentModuleName.noSpace"),
320 "RegRipper " + regFile.getUniquePath(), regFile);
323 KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class);
324 if (null == searchService) {
325 logger.log(Level.WARNING,
"Keyword search service not found. Report will not be indexed");
327 searchService.index(report);
330 }
catch (TskCoreException e) {
331 this.addErrorMessage(
"Error adding regripper output as Autopsy report: " + e.getLocalizedMessage());
335 regFileNameLocalFile.delete();
339 if (logFile != null) {
342 }
catch (IOException ex) {
343 logger.log(Level.SEVERE, null, ex);
354 private RegOutputFiles ripRegistryFile(String regFilePath, String outFilePathBase) {
355 String autopsyType =
"";
358 RegOutputFiles regOutputFiles =
new RegOutputFiles();
360 if (regFilePath.toLowerCase().contains(
"system")) {
361 autopsyType =
"autopsysystem";
363 }
else if (regFilePath.toLowerCase().contains(
"software")) {
364 autopsyType =
"autopsysoftware";
365 fullType =
"software";
366 }
else if (regFilePath.toLowerCase().contains(
"ntuser")) {
367 autopsyType =
"autopsyntuser";
369 }
else if (regFilePath.toLowerCase().contains(
"sam")) {
372 }
else if (regFilePath.toLowerCase().contains(
"security")) {
373 fullType =
"security";
374 }
else if (regFilePath.toLowerCase().contains(
"usrclass")) {
375 fullType =
"usrclass";
377 return regOutputFiles;
381 if (!autopsyType.isEmpty()) {
382 regOutputFiles.autopsyPlugins = outFilePathBase +
"-autopsy.txt";
383 String errFilePath = outFilePathBase +
"-autopsy.err.txt";
384 logger.log(Level.INFO,
"Writing RegRipper results to: {0}", regOutputFiles.autopsyPlugins);
385 executeRegRipper(rrCmd, rrHome, regFilePath, autopsyType, regOutputFiles.autopsyPlugins, errFilePath);
387 if (context.dataSourceIngestIsCancelled()) {
388 return regOutputFiles;
392 if (!fullType.isEmpty()) {
393 regOutputFiles.fullPlugins = outFilePathBase +
"-full.txt";
394 String errFilePath = outFilePathBase +
"-full.err.txt";
395 logger.log(Level.INFO,
"Writing Full RegRipper results to: {0}", regOutputFiles.fullPlugins);
396 executeRegRipper(rrFullCmd, rrFullHome, regFilePath, fullType, regOutputFiles.fullPlugins, errFilePath);
398 return regOutputFiles;
401 private void executeRegRipper(List<String> regRipperPath, Path regRipperHomeDir, String hiveFilePath, String hiveFileType, String outputFile, String errFile) {
403 List<String> commandLine =
new ArrayList<>();
404 for (String cmd : regRipperPath) {
405 commandLine.add(cmd);
407 commandLine.add(
"-r");
408 commandLine.add(hiveFilePath);
409 commandLine.add(
"-f");
410 commandLine.add(hiveFileType);
412 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
413 processBuilder.directory(regRipperHomeDir.toFile());
414 processBuilder.redirectOutput(
new File(outputFile));
415 processBuilder.redirectError(
new File(errFile));
416 ExecUtil.execute(processBuilder,
new DataSourceIngestModuleProcessTerminator(context));
417 }
catch (IOException ex) {
418 logger.log(Level.SEVERE,
"Unable to run RegRipper", ex);
419 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getName()));
432 private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) {
433 FileInputStream fstream = null;
434 List<BlackboardArtifact> newArtifacts =
new ArrayList<>();
437 File regfile =
new File(regFilePath);
438 fstream =
new FileInputStream(regfile);
439 String regString =
new Scanner(fstream,
"UTF-8").useDelimiter(
"\\Z").next();
440 String startdoc =
"<?xml version=\"1.0\"?><document>";
441 String result = regString.replaceAll(
"----------------------------------------",
"");
442 result = result.replaceAll(
"\\n",
"");
443 result = result.replaceAll(
"\\r",
"");
444 result = result.replaceAll(
"'",
"'");
445 result = result.replaceAll(
"&",
"&");
446 result = result.replace(
'\0',
' ');
447 String enddoc =
"</document>";
448 String stringdoc = startdoc + result + enddoc;
449 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
450 Document doc = builder.parse(
new InputSource(
new StringReader(stringdoc)));
453 Element oroot = doc.getDocumentElement();
454 NodeList children = oroot.getChildNodes();
455 int len = children.getLength();
456 for (
int i = 0; i < len; i++) {
458 if (context.dataSourceIngestIsCancelled()) {
462 Element tempnode = (Element) children.item(i);
464 String dataType = tempnode.getNodeName();
465 NodeList timenodes = tempnode.getElementsByTagName(
"mtime");
467 if (timenodes.getLength() > 0) {
468 Element timenode = (Element) timenodes.item(0);
469 String etime = timenode.getTextContent();
471 if (etime != null && !etime.isEmpty()) {
473 mtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(etime).getTime();
474 String Tempdate = mtime.toString();
475 mtime = Long.valueOf(Tempdate) / MS_IN_SEC;
476 }
catch (ParseException ex) {
477 logger.log(Level.WARNING,
"Failed to parse epoch time when parsing the registry.", ex);
482 NodeList artroots = tempnode.getElementsByTagName(
"artifacts");
483 if (artroots.getLength() == 0) {
488 Element artroot = (Element) artroots.item(0);
489 NodeList myartlist = artroot.getChildNodes();
490 String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName();
496 String systemRoot =
"";
497 String productId =
"";
498 String regOwner =
"";
500 Long installtime = null;
501 for (
int j = 0; j < myartlist.getLength(); j++) {
502 Node artchild = myartlist.item(j);
504 if (artchild.hasAttributes()) {
505 Element artnode = (Element) artchild;
507 String value = artnode.getTextContent();
509 value = value.trim();
511 String name = artnode.getAttribute(
"name");
521 version = version +
" " + value;
529 case "RegisteredOwner":
532 case "RegisteredOrganization":
536 if (value != null && !value.isEmpty()) {
538 installtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(value).getTime();
539 String Tempdate = installtime.toString();
540 installtime = Long.valueOf(Tempdate) / MS_IN_SEC;
541 }
catch (ParseException e) {
542 logger.log(Level.WARNING,
"RegRipper::Conversion on DateTime -> ", e);
552 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
553 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, version));
554 if (installtime != null) {
555 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, installtime));
557 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, parentModuleName, systemRoot));
558 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID, parentModuleName, productId));
559 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER, parentModuleName, regOwner));
560 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION, parentModuleName, regOrg));
563 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
564 if (results.isEmpty()) {
565 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
566 bbart.addAttributes(bbattributes);
568 newArtifacts.add(bbart);
570 results.get(0).addAttributes(bbattributes);
573 }
catch (TskCoreException ex) {
574 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.");
579 String procArch =
"";
581 for (
int j = 0; j < myartlist.getLength(); j++) {
582 Node artchild = myartlist.item(j);
584 if (artchild.hasAttributes()) {
585 Element artnode = (Element) artchild;
587 String value = artnode.getTextContent().trim();
588 String name = artnode.getAttribute(
"name");
593 case "PROCESSOR_ARCHITECTURE":
596 case "PROCESSOR_IDENTIFIER":
607 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
608 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VERSION, parentModuleName, os));
609 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE, parentModuleName, procArch));
610 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR, parentModuleName, tempDir));
613 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
614 if (results.isEmpty()) {
615 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
616 bbart.addAttributes(bbattributes);
618 newArtifacts.add(bbart);
620 results.get(0).addAttributes(bbattributes);
622 }
catch (TskCoreException ex) {
623 logger.log(Level.SEVERE,
"Error adding os info artifact to blackboard.");
627 String compName =
"";
629 for (
int j = 0; j < myartlist.getLength(); j++) {
630 Node artchild = myartlist.item(j);
632 if (artchild.hasAttributes()) {
633 Element artnode = (Element) artchild;
635 String value = artnode.getTextContent().trim();
636 String name = artnode.getAttribute(
"name");
638 if (name.equals(
"ComputerName")) {
640 }
else if (name.equals(
"Domain")) {
646 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
647 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, compName));
648 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN, parentModuleName, domain));
651 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
652 if (results.isEmpty()) {
653 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
654 bbart.addAttributes(bbattributes);
656 newArtifacts.add(bbart);
658 results.get(0).addAttributes(bbattributes);
660 }
catch (TskCoreException ex) {
661 logger.log(Level.SEVERE,
"Error adding os info artifact to blackboard.", ex);
665 for (
int j = 0; j < myartlist.getLength(); j++) {
666 Node artchild = myartlist.item(j);
668 if (artchild.hasAttributes()) {
669 Element artnode = (Element) artchild;
671 String value = artnode.getTextContent().trim();
672 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
685 Long usbMtime = Long.parseLong(artnode.getAttribute(
"mtime"));
686 usbMtime = Long.valueOf(usbMtime.toString());
688 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED);
689 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, usbMtime));
690 String dev = artnode.getAttribute(
"dev");
693 if (dev.toLowerCase().contains(
"vid")) {
694 USBInfo info = USB_MAPPER.parseAndLookup(dev);
695 if (info.getVendor() != null) {
696 make = info.getVendor();
698 if (info.getProduct() != null) {
699 model = info.getProduct();
702 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE, parentModuleName, make));
703 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL, parentModuleName, model));
704 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, value));
705 bbart.addAttributes(bbattributes);
707 newArtifacts.add(bbart);
708 }
catch (TskCoreException ex) {
709 logger.log(Level.SEVERE,
"Error adding device attached artifact to blackboard.", ex);
713 Long itemMtime = null;
715 String mTimeAttr = artnode.getAttribute(
"mtime");
716 if (mTimeAttr != null && !mTimeAttr.isEmpty()) {
717 itemMtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(mTimeAttr).getTime();
718 itemMtime /= MS_IN_SEC;
720 }
catch (ParseException ex) {
721 logger.log(Level.SEVERE,
"Failed to parse epoch time for installed program artifact.", ex);
725 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value));
726 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime));
727 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_INSTALLED_PROG);
728 bbart.addAttributes(bbattributes);
730 newArtifacts.add(bbart);
731 }
catch (TskCoreException ex) {
732 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.", ex);
736 String officeName = artnode.getAttribute(
"name");
739 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
742 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, parentModuleName, mtime));
744 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, officeName));
745 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, parentModuleName, value));
746 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, artnode.getNodeName()));
747 bbart.addAttributes(bbattributes);
749 newArtifacts.add(bbart);
750 }
catch (TskCoreException ex) {
751 logger.log(Level.SEVERE,
"Error adding recent object artifact to blackboard.", ex);
755 case "ProcessorArchitecture":
772 String homeDir = value;
773 String sid = artnode.getAttribute(
"sid");
774 String username = artnode.getAttribute(
"username");
775 BlackboardArtifact bbart = null;
778 ArrayList<BlackboardArtifact> existingArtifacts = currentCase.getSleuthkitCase().getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
779 for (BlackboardArtifact artifact : existingArtifacts) {
780 if (artifact.getDataSource().getId() == regFile.getDataSourceObjectId()) {
781 BlackboardAttribute attribute = artifact.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID));
782 if (attribute != null && attribute.getValueString().equals(sid)) {
788 }
catch (TskCoreException ex) {
789 logger.log(Level.SEVERE,
"Error getting existing os account artifact", ex);
793 bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
794 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
795 parentModuleName, username));
796 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
797 parentModuleName, sid));
798 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
799 parentModuleName, homeDir));
802 BlackboardAttribute bbattr = bbart.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_NAME));
804 if (bbattr == null) {
805 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
806 parentModuleName, username));
808 bbattr = bbart.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH));
809 if (bbattr == null) {
810 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
811 parentModuleName, homeDir));
814 bbart.addAttributes(bbattributes);
815 newArtifacts.add(bbart);
816 }
catch (TskCoreException ex) {
817 logger.log(Level.SEVERE,
"Error adding account artifact to blackboard.", ex);
821 case "NtuserNetwork":
823 String localPath = artnode.getAttribute(
"localPath");
824 String remoteName = value;
825 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_REMOTE_DRIVE);
826 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH,
827 parentModuleName, localPath));
828 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH,
829 parentModuleName, remoteName));
830 bbart.addAttributes(bbattributes);
831 newArtifacts.add(bbart);
832 }
catch (TskCoreException ex) {
833 logger.log(Level.SEVERE,
"Error adding network artifact to blackboard.", ex);
837 String adapter = artnode.getAttribute(
"adapter");
839 Long lastWriteTime = Long.parseLong(artnode.getAttribute(
"writeTime"));
840 lastWriteTime = Long.valueOf(lastWriteTime.toString());
841 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SSID, parentModuleName, value));
842 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, lastWriteTime));
843 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, adapter));
844 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_WIFI_NETWORK);
845 bbart.addAttributes(bbattributes);
846 newArtifacts.add(bbart);
847 }
catch (TskCoreException ex) {
848 logger.log(Level.SEVERE,
"Error adding SSID artifact to blackboard.", ex);
858 logger.log(Level.SEVERE,
"Unrecognized node name: {0}", dataType);
867 }
catch (FileNotFoundException ex) {
868 logger.log(Level.WARNING, String.format(
"Error finding the registry file: %s", regFilePath), ex);
869 }
catch (SAXException ex) {
870 logger.log(Level.WARNING, String.format(
"Error parsing the registry XML: %s", regFilePath), ex);
871 }
catch (IOException ex) {
872 logger.log(Level.WARNING, String.format(
"Error building the document parser: %s", regFilePath), ex);
873 }
catch (ParserConfigurationException ex) {
874 logger.log(Level.WARNING, String.format(
"Error configuring the registry parser: %s", regFilePath), ex);
877 if (fstream != null) {
880 }
catch (IOException ex) {
883 postArtifacts(newArtifacts);
897 private boolean parseSamPluginOutput(String regFilePath, AbstractFile regAbstractFile) {
898 File regfile =
new File(regFilePath);
899 List<BlackboardArtifact> newArtifacts =
new ArrayList<>();
900 try (BufferedReader bufferedReader =
new BufferedReader(
new FileReader(regfile))) {
902 String userInfoSection =
"User Information";
903 String previousLine = null;
904 String line = bufferedReader.readLine();
905 Set<Map<String, String>> userSet =
new HashSet<>();
906 Map<String, List<String>> groupMap = null;
907 while (line != null) {
908 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(userInfoSection)) {
909 readUsers(bufferedReader, userSet);
912 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(
"Group Membership Information")) {
913 groupMap = readGroups(bufferedReader);
917 line = bufferedReader.readLine();
919 Map<String, Map<String, String>> userInfoMap =
new HashMap<>();
921 for (Map<String, String> userInfo : userSet) {
922 userInfoMap.put(userInfo.get(SID_KEY), userInfo);
925 List<BlackboardArtifact> existingOsAccounts = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
926 for (BlackboardArtifact osAccount : existingOsAccounts) {
928 if (osAccount.getDataSource().getId() == regAbstractFile.getDataSourceObjectId()) {
929 BlackboardAttribute existingUserId = osAccount.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID));
930 if (existingUserId != null) {
931 String userID = existingUserId.getValueString().trim();
932 Map<String, String> userInfo = userInfoMap.remove(userID);
934 if (userInfo != null) {
935 osAccount.addAttributes(getAttributesForAccount(userInfo, groupMap.get(userID),
true));
942 for (Map<String, String> userInfo : userInfoMap.values()) {
943 BlackboardArtifact bbart = regAbstractFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
944 bbart.addAttributes(getAttributesForAccount(userInfo, groupMap.get(userInfo.get(SID_KEY)),
false));
946 newArtifacts.add(bbart);
949 }
catch (FileNotFoundException ex) {
950 logger.log(Level.WARNING,
"Error finding the registry file.", ex);
951 }
catch (IOException ex) {
952 logger.log(Level.WARNING,
"Error building the document parser: {0}", ex);
953 }
catch (ParseException ex) {
954 logger.log(Level.WARNING,
"Error parsing the the date from the registry file", ex);
955 }
catch (TskCoreException ex) {
956 logger.log(Level.WARNING,
"Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex);
958 postArtifacts(newArtifacts);
974 Collection<BlackboardAttribute> getAttributesForAccount(Map<String, String> userInfo, List<String> groupList,
boolean existingUser)
throws ParseException {
975 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
977 SimpleDateFormat regRipperTimeFormat =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'");
978 regRipperTimeFormat.setTimeZone(getTimeZone(
"GMT"));
981 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
982 getRAModuleName(), userInfo.get(SID_KEY)));
984 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
985 this.moduleName, userInfo.get(USERNAME_KEY)));
988 String value = userInfo.get(ACCOUNT_CREATED_KEY);
989 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
990 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
991 getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
994 value = userInfo.get(LAST_LOGIN_KEY);
995 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
996 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
997 getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
1000 value = userInfo.get(LOGIN_COUNT_KEY);
1001 if (value != null && !value.isEmpty()) {
1002 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
1003 getRAModuleName(), Integer.parseInt(value)));
1006 value = userInfo.get(ACCOUNT_TYPE_KEY);
1007 if (value != null && !value.isEmpty()) {
1008 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE,
1009 getRAModuleName(), value));
1012 value = userInfo.get(USER_COMMENT_KEY);
1013 if (value != null && !value.isEmpty()) {
1014 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DESCRIPTION,
1015 getRAModuleName(), value));
1018 value = userInfo.get(NAME_KEY);
1019 if (value != null && !value.isEmpty()) {
1020 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
1021 getRAModuleName(), value));
1024 value = userInfo.get(INTERNET_NAME_KEY);
1025 if (value != null && !value.isEmpty()) {
1026 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL,
1027 getRAModuleName(), value));
1030 value = userInfo.get(FULL_NAME_KEY);
1031 if (value != null && !value.isEmpty()) {
1032 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DISPLAY_NAME,
1033 getRAModuleName(), value));
1036 value = userInfo.get(PWD_RESET_KEY);
1037 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
1038 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_RESET,
1039 getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
1042 value = userInfo.get(PASSWORD_HINT);
1043 if (value != null && !value.isEmpty()) {
1044 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_HINT,
1045 getRAModuleName(), value));
1048 value = userInfo.get(PWD_FAILE_KEY);
1049 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
1050 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_FAIL,
1051 getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
1054 String settingString =
"";
1055 for (String setting : PASSWORD_SETTINGS_FLAGS) {
1056 if (userInfo.containsKey(setting)) {
1057 settingString += setting +
", ";
1061 if (!settingString.isEmpty()) {
1062 settingString = settingString.substring(0, settingString.length() - 2);
1063 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_SETTINGS,
1064 getRAModuleName(), settingString));
1068 for (String setting : ACCOUNT_SETTINGS_FLAGS) {
1069 if (userInfo.containsKey(setting)) {
1070 settingString += setting +
", ";
1074 if (!settingString.isEmpty()) {
1075 settingString = settingString.substring(0, settingString.length() - 2);
1076 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_SETTINGS,
1077 getRAModuleName(), settingString));
1081 for (String setting : ACCOUNT_TYPE_FLAGS) {
1082 if (userInfo.containsKey(setting)) {
1083 settingString += setting +
", ";
1087 if (!settingString.isEmpty()) {
1088 settingString = settingString.substring(0, settingString.length() - 2);
1089 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_FLAG,
1090 getRAModuleName(), settingString));
1093 if (groupList != null && groupList.isEmpty()) {
1095 for (String group : groupList) {
1096 groups += group +
", ";
1099 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GROUPS,
1100 getRAModuleName(), groups.substring(0, groups.length() - 2)));
1103 return bbattributes;
1117 private void readUsers(BufferedReader bufferedReader, Set<Map<String, String>> users) throws IOException {
1118 String line = bufferedReader.readLine();
1120 String userName =
"";
1121 String user_rid =
"";
1122 while (line != null && !line.contains(SECTION_DIVIDER)) {
1124 if (line.contains(USERNAME_KEY)) {
1125 String regx = USERNAME_KEY +
"\\s*?:";
1126 String userNameAndIdString = line.replaceAll(regx,
"");
1127 userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf(
'[')).trim();
1128 user_rid = userNameAndIdString.substring(userNameAndIdString.lastIndexOf(
'['), userNameAndIdString.lastIndexOf(
']'));
1129 }
else if (line.contains(SID_KEY) && !userName.isEmpty()) {
1130 Map.Entry<String, String> entry = getSAMKeyValue(line);
1132 HashMap<String, String> userInfo =
new HashMap<>();
1133 userInfo.put(USERNAME_KEY, userName);
1134 userInfo.put(RID_KEY, user_rid);
1135 userInfo.put(entry.getKey(), entry.getValue());
1138 line = bufferedReader.readLine();
1139 while (line != null && !line.isEmpty()) {
1140 entry = getSAMKeyValue(line);
1141 if (entry != null) {
1142 userInfo.put(entry.getKey(), entry.getValue());
1144 line = bufferedReader.readLine();
1146 users.add(userInfo);
1150 line = bufferedReader.readLine();
1163 void createShellBagArtifacts(AbstractFile regFile, List<ShellBag> shellbags)
throws TskCoreException {
1164 List<BlackboardArtifact> artifacts =
new ArrayList<>();
1166 for (ShellBag bag : shellbags) {
1167 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1168 BlackboardArtifact artifact = regFile.newArtifact(getShellBagArtifact().getTypeID());
1169 attributes.add(
new BlackboardAttribute(TSK_PATH, getName(), bag.getResource()));
1170 attributes.add(
new BlackboardAttribute(getKeyAttribute(), getName(), bag.getKey()));
1173 time = bag.getLastWrite();
1175 attributes.add(
new BlackboardAttribute(getLastWriteAttribute(), getName(), time));
1178 time = bag.getModified();
1180 attributes.add(
new BlackboardAttribute(TSK_DATETIME_MODIFIED, getName(), time));
1183 time = bag.getCreated();
1185 attributes.add(
new BlackboardAttribute(TSK_DATETIME_CREATED, getName(), time));
1188 time = bag.getAccessed();
1190 attributes.add(
new BlackboardAttribute(TSK_DATETIME_ACCESSED, getName(), time));
1193 artifact.addAttributes(attributes);
1195 artifacts.add(artifact);
1198 postArtifacts(artifacts);
1210 private BlackboardArtifact.Type getShellBagArtifact() throws TskCoreException {
1211 if (shellBagArtifactType == null) {
1212 shellBagArtifactType = tskCase.getArtifactType(SHELLBAG_ARTIFACT_NAME);
1214 if(shellBagArtifactType == null) {
1216 tskCase.addBlackboardArtifactType(SHELLBAG_ARTIFACT_NAME, Bundle.Shellbag_Artifact_Display_Name());
1217 }
catch (TskDataException ex) {
1219 logger.log(Level.INFO, String.format(
"%s may have already been defined for this case", SHELLBAG_ARTIFACT_NAME));
1222 shellBagArtifactType = tskCase.getArtifactType(SHELLBAG_ARTIFACT_NAME);
1226 return shellBagArtifactType;
1237 private BlackboardAttribute.Type getLastWriteAttribute() throws TskCoreException {
1238 if (shellBagLastWriteAttributeType == null) {
1240 shellBagLastWriteAttributeType = tskCase.addArtifactAttributeType(SHELLBAG_ATTRIBUTE_LAST_WRITE,
1241 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME,
1242 Bundle.Shellbag_Last_Write_Attribute_Display_Name());
1243 }
catch (TskDataException ex) {
1245 shellBagLastWriteAttributeType = tskCase.getAttributeType(SHELLBAG_ATTRIBUTE_LAST_WRITE);
1248 return shellBagLastWriteAttributeType;
1259 private BlackboardAttribute.Type getKeyAttribute() throws TskCoreException {
1260 if (shellBagKeyAttributeType == null) {
1262 shellBagKeyAttributeType = tskCase.addArtifactAttributeType(SHELLBAG_ATTRIBUTE_KEY,
1263 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
1264 Bundle.Shellbag_Key_Attribute_Display_Name());
1265 }
catch (TskDataException ex) {
1267 shellBagKeyAttributeType = tskCase.getAttributeType(SHELLBAG_ATTRIBUTE_KEY);
1270 return shellBagKeyAttributeType;
1282 Map<String, List<String>> readGroups(BufferedReader bufferedReader)
throws IOException {
1283 Map<String, List<String>> groupMap =
new HashMap<>();
1285 String line = bufferedReader.readLine();
1288 String groupName = null;
1290 while (line != null && !line.contains(SECTION_DIVIDER)) {
1292 if (line.contains(
"Group Name")) {
1293 String value = line.replaceAll(
"Group Name\\s*?:",
"").trim();
1294 groupName = (value.replaceAll(
"\\[\\d*?\\]",
"")).trim();
1295 int startIndex = value.indexOf(
'[');
1296 int endIndex = value.indexOf(
']');
1298 if (startIndex != -1 && endIndex != -1) {
1299 String countStr = value.substring(startIndex + 1, endIndex);
1300 userCount = Integer.parseInt(countStr);
1302 }
else if (line.matches(
"Users\\s*?:")) {
1303 for (
int i = 0; i < userCount; i++) {
1304 line = bufferedReader.readLine();
1306 String sid = line.trim();
1307 List<String> groupList = groupMap.get(sid);
1308 if (groupList == null) {
1309 groupList =
new ArrayList<>();
1310 groupMap.put(sid, groupList);
1312 groupList.add(groupName);
1317 line = bufferedReader.readLine();
1331 private Map.Entry<String, String> getSAMKeyValue(String line) {
1332 int index = line.indexOf(
':');
1333 Map.Entry<String, String> returnValue = null;
1335 String value = null;
1338 key = line.substring(0, index).trim();
1339 if (index + 1 < line.length()) {
1340 value = line.substring(index + 1).trim();
1345 }
else if (line.contains(
"-->")) {
1346 key = line.replace(
"-->",
"").trim();
1351 returnValue =
new AbstractMap.SimpleEntry<>(key, value);
1358 public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
1359 this.dataSource = dataSource;
1360 this.context = context;
1362 progressBar.progress(Bundle.Progress_Message_Analyze_Registry());
1363 analyzeRegistryFiles();
1372 public String autopsyPlugins =
"";
1373 public String fullPlugins =
"";