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.apache.commons.io.FilenameUtils;
40 import org.openide.modules.InstalledFileLocator;
41 import org.openide.util.NbBundle;
49 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
50 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
51 import org.w3c.dom.Document;
52 import org.w3c.dom.Element;
53 import org.w3c.dom.Node;
54 import org.w3c.dom.NodeList;
55 import org.xml.sax.InputSource;
56 import org.xml.sax.SAXException;
57 import java.nio.file.Path;
58 import java.util.AbstractMap;
59 import java.util.ArrayList;
60 import java.util.Arrays;
61 import java.util.List;
62 import java.util.Collection;
63 import java.util.Date;
64 import java.util.HashMap;
66 import java.util.Scanner;
68 import java.util.HashSet;
69 import static java.util.Locale.US;
70 import static java.util.TimeZone.getTimeZone;
71 import org.openide.util.Lookup;
81 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
82 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_ACCOUNT;
84 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
85 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT;
86 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
87 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED;
88 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED;
89 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED;
90 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID;
91 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME;
92 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH;
93 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_ID;
94 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME;
96 import org.
sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
108 "RegRipperNotFound=Autopsy RegRipper executable not found.",
109 "RegRipperFullNotFound=Full version RegRipper executable not found.",
110 "Progress_Message_Analyze_Registry=Analyzing Registry Files",
111 "Shellbag_Artifact_Display_Name=Shell Bags",
112 "Shellbag_Key_Attribute_Display_Name=Key",
113 "Shellbag_Last_Write_Attribute_Display_Name=Last Write",
114 "Recently_Used_Artifacts_Office_Trustrecords=Stored in TrustRecords because Office security exception was granted",
115 "Recently_Used_Artifacts_ArcHistory=Recently opened by 7Zip",
116 "Recently_Used_Artifacts_Applets=Recently opened according to Applets registry key",
117 "Recently_Used_Artifacts_Mmc=Recently opened according to Windows Management Console MRU",
118 "Recently_Used_Artifacts_Winrar=Recently opened according to WinRAR MRU",
119 "Recently_Used_Artifacts_Officedocs=Recently opened according to Office MRU",
120 "Recently_Used_Artifacts_Adobe=Recently opened according to Adobe MRU",
121 "Recently_Used_Artifacts_Mediaplayer=Recently opened according to Media Player MRU",
122 "Registry_System_Bam=Recently Executed according to Background Activity Moderator (BAM)"
124 class ExtractRegistry extends Extract {
126 private static final String USERNAME_KEY =
"Username";
127 private static final String SID_KEY =
"SID";
128 private static final String RID_KEY =
"RID";
129 private static final String ACCOUNT_CREATED_KEY =
"Account Created";
130 private static final String LAST_LOGIN_KEY =
"Last Login Date";
131 private static final String LOGIN_COUNT_KEY =
"Login Count";
132 private static final String FULL_NAME_KEY =
"Full Name";
133 private static final String USER_COMMENT_KEY =
"User Comment";
134 private static final String ACCOUNT_TYPE_KEY =
"Account Type";
135 private static final String NAME_KEY =
"Name";
136 private static final String PWD_RESET_KEY =
"Pwd Rest Date";
137 private static final String PWD_FAILE_KEY =
"Pwd Fail Date";
138 private static final String INTERNET_NAME_KEY =
"InternetName";
139 private static final String PWD_DOES_NOT_EXPIRE_KEY =
"Password does not expire";
140 private static final String ACCOUNT_DISABLED_KEY =
"Account Disabled";
141 private static final String PWD_NOT_REQUIRED_KEY =
"Password not required";
142 private static final String NORMAL_ACCOUNT_KEY =
"Normal user account";
143 private static final String HOME_DIRECTORY_REQUIRED_KEY =
"Home directory required";
144 private static final String TEMPORARY_DUPLICATE_ACCOUNT =
"Temporary duplicate account";
145 private static final String MNS_LOGON_ACCOUNT_KEY =
"MNS logon user account";
146 private static final String INTERDOMAIN_TRUST_ACCOUNT_KEY =
"Interdomain trust account";
147 private static final String WORKSTATION_TRUST_ACCOUNT =
"Workstation trust account";
148 private static final String SERVER_TRUST_ACCOUNT =
"Server trust account";
149 private static final String ACCOUNT_AUTO_LOCKED =
"Account auto locked";
150 private static final String PASSWORD_HINT =
"Password Hint";
152 private static final String[] PASSWORD_SETTINGS_FLAGS = {PWD_DOES_NOT_EXPIRE_KEY, PWD_NOT_REQUIRED_KEY};
153 private static final String[] ACCOUNT_SETTINGS_FLAGS = {ACCOUNT_AUTO_LOCKED, HOME_DIRECTORY_REQUIRED_KEY, ACCOUNT_DISABLED_KEY};
154 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};
156 final private static UsbDeviceIdMapper USB_MAPPER =
new UsbDeviceIdMapper();
157 final private static String RIP_EXE =
"rip.exe";
158 final private static String RIP_PL =
"rip.pl";
159 final private static String RIP_PL_INCLUDE_FLAG =
"-I";
160 final private static int MS_IN_SEC = 1000;
161 final private static String NEVER_DATE =
"Never";
162 final private static String SECTION_DIVIDER =
"-------------------------";
163 final private static Logger logger = Logger.getLogger(ExtractRegistry.class.getName());
164 private final List<String> rrCmd =
new ArrayList<>();
165 private final List<String> rrFullCmd =
new ArrayList<>();
166 private final Path rrHome;
167 private final Path rrFullHome;
168 private Content dataSource;
169 private IngestJobContext context;
170 private Map<String, String> userNameMap;
172 private static final String SHELLBAG_ARTIFACT_NAME =
"RA_SHELL_BAG";
173 private static final String SHELLBAG_ATTRIBUTE_LAST_WRITE =
"RA_SHELL_BAG_LAST_WRITE";
174 private static final String SHELLBAG_ATTRIBUTE_KEY =
"RA_SHELL_BAG_KEY";
176 BlackboardArtifact.Type shellBagArtifactType = null;
177 BlackboardAttribute.Type shellBagKeyAttributeType = null;
178 BlackboardAttribute.Type shellBagLastWriteAttributeType = null;
180 ExtractRegistry() throws IngestModuleException {
181 moduleName = NbBundle.getMessage(ExtractIE.class,
"ExtractRegistry.moduleName.text");
183 final File rrRoot = InstalledFileLocator.getDefault().locate(
"rr", ExtractRegistry.class.getPackage().getName(),
false);
184 if (rrRoot == null) {
185 throw new IngestModuleException(Bundle.RegRipperNotFound());
188 final File rrFullRoot = InstalledFileLocator.getDefault().locate(
"rr-full", ExtractRegistry.class.getPackage().getName(),
false);
189 if (rrFullRoot == null) {
190 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
193 String executableToRun = RIP_EXE;
194 if (!PlatformUtil.isWindowsOS()) {
195 executableToRun = RIP_PL;
197 rrHome = rrRoot.toPath();
198 String rrPath = rrHome.resolve(executableToRun).toString();
199 rrFullHome = rrFullRoot.toPath();
201 if (!(
new File(rrPath).exists())) {
202 throw new IngestModuleException(Bundle.RegRipperNotFound());
204 String rrFullPath = rrFullHome.resolve(executableToRun).toString();
205 if (!(
new File(rrFullPath).exists())) {
206 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
208 if (PlatformUtil.isWindowsOS()) {
210 rrFullCmd.add(rrFullPath);
213 File usrBin =
new File(
"/usr/bin/perl");
214 File usrLocalBin =
new File(
"/usr/local/bin/perl");
215 if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
216 perl =
"/usr/bin/perl";
217 }
else if (usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()) {
218 perl =
"/usr/local/bin/perl";
220 throw new IngestModuleException(
"perl not found in your system");
223 rrCmd.add(RIP_PL_INCLUDE_FLAG);
224 rrCmd.add(rrHome.toString());
227 rrFullCmd.add(RIP_PL_INCLUDE_FLAG);
228 rrFullCmd.add(rrFullHome.toString());
229 rrFullCmd.add(rrFullPath);
236 private List<AbstractFile> findRegistryFiles() {
237 List<AbstractFile> allRegistryFiles =
new ArrayList<>();
242 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"sam",
"/system32/config"));
243 }
catch (TskCoreException ex) {
244 String msg = NbBundle.getMessage(this.getClass(),
245 "ExtractRegistry.findRegFiles.errMsg.errReadingFile",
"sam");
246 logger.log(Level.WARNING, msg, ex);
247 this.addErrorMessage(this.getName() +
": " + msg);
252 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"ntuser.dat"));
253 }
catch (TskCoreException ex) {
254 logger.log(Level.WARNING,
"Error fetching 'ntuser.dat' file.");
259 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"usrclass.dat"));
260 }
catch (TskCoreException ex) {
261 logger.log(Level.WARNING, String.format(
"Error finding 'usrclass.dat' files."), ex);
265 String[] regFileNames =
new String[]{
"system",
"software",
"security"};
266 for (String regFileName : regFileNames) {
268 allRegistryFiles.addAll(fileManager.findFiles(dataSource, regFileName,
"/system32/config"));
269 }
catch (TskCoreException ex) {
270 String msg = NbBundle.getMessage(this.getClass(),
271 "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName);
272 logger.log(Level.WARNING, msg, ex);
273 this.addErrorMessage(this.getName() +
": " + msg);
276 return allRegistryFiles;
283 private void analyzeRegistryFiles() {
284 List<AbstractFile> allRegistryFiles = findRegistryFiles();
287 FileWriter logFile = null;
289 logFile =
new FileWriter(RAImageIngestModule.getRAOutputPath(currentCase,
"reg") + File.separator +
"regripper-info.txt");
290 }
catch (IOException ex) {
291 logger.log(Level.SEVERE, null, ex);
294 for (AbstractFile regFile : allRegistryFiles) {
295 String regFileName = regFile.getName();
296 long regFileId = regFile.getId();
297 String regFileNameLocal = RAImageIngestModule.getRATempPath(currentCase,
"reg") + File.separator + regFileName;
298 String outputPathBase = RAImageIngestModule.getRAOutputPath(currentCase,
"reg") + File.separator + regFileName +
"-regripper-" + Long.toString(regFileId);
299 File regFileNameLocalFile =
new File(regFileNameLocal);
301 ContentUtils.writeToFile(regFile, regFileNameLocalFile, context::dataSourceIngestIsCancelled);
302 }
catch (ReadContentInputStreamException ex) {
303 logger.log(Level.WARNING, String.format(
"Error reading registry file '%s' (id=%d).",
304 regFile.getName(), regFileId), ex);
305 this.addErrorMessage(
306 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
307 this.getName(), regFileName));
309 }
catch (IOException ex) {
310 logger.log(Level.SEVERE, String.format(
"Error writing temp registry file '%s' for registry file '%s' (id=%d).",
311 regFileNameLocal, regFile.getName(), regFileId), ex);
312 this.addErrorMessage(
313 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
314 this.getName(), regFileName));
318 if (context.dataSourceIngestIsCancelled()) {
323 if (logFile != null) {
324 logFile.write(Long.toString(regFileId) +
"\t" + regFile.getUniquePath() +
"\n");
326 }
catch (TskCoreException | IOException ex) {
327 logger.log(Level.SEVERE, null, ex);
330 logger.log(Level.INFO,
"{0}- Now getting registry information from {1}",
new Object[]{moduleName, regFileNameLocal});
331 RegOutputFiles regOutputFiles = ripRegistryFile(regFileNameLocal, outputPathBase);
332 if (context.dataSourceIngestIsCancelled()) {
337 if (regOutputFiles.autopsyPlugins.isEmpty() ==
false && parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) ==
false) {
338 this.addErrorMessage(
339 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
340 this.getName(), regFileName));
344 if (!regOutputFiles.fullPlugins.isEmpty()) {
346 if (regFileNameLocal.toLowerCase().contains(
"sam") && parseSamPluginOutput(regOutputFiles.fullPlugins, regFile) ==
false) {
347 this.addErrorMessage(
348 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
349 this.getName(), regFileName));
350 }
else if (regFileNameLocal.toLowerCase().contains(
"ntuser") || regFileNameLocal.toLowerCase().contains(
"usrclass")) {
352 List<ShellBag> shellbags = ShellBagParser.parseShellbagOutput(regOutputFiles.fullPlugins);
353 createShellBagArtifacts(regFile, shellbags);
354 createRecentlyUsedArtifacts(regOutputFiles.fullPlugins, regFile);
355 }
catch (IOException | TskCoreException ex) {
356 logger.log(Level.WARNING, String.format(
"Unable to get shell bags from file %s", regOutputFiles.fullPlugins), ex);
358 }
else if (regFileNameLocal.toLowerCase().contains(
"system") && parseSystemPluginOutput(regOutputFiles.fullPlugins, regFile) ==
false) {
359 this.addErrorMessage(
360 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
361 this.getName(), regFileName));
364 Report report = currentCase.addReport(regOutputFiles.fullPlugins,
365 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.parentModuleName.noSpace"),
366 "RegRipper " + regFile.getUniquePath(), regFile);
369 KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class);
370 if (null == searchService) {
371 logger.log(Level.WARNING,
"Keyword search service not found. Report will not be indexed");
373 searchService.index(report);
376 }
catch (TskCoreException e) {
377 this.addErrorMessage(
"Error adding regripper output as Autopsy report: " + e.getLocalizedMessage());
381 regFileNameLocalFile.delete();
385 if (logFile != null) {
388 }
catch (IOException ex) {
389 logger.log(Level.SEVERE, null, ex);
400 private RegOutputFiles ripRegistryFile(String regFilePath, String outFilePathBase) {
401 String autopsyType =
"";
404 RegOutputFiles regOutputFiles =
new RegOutputFiles();
406 if (regFilePath.toLowerCase().contains(
"system")) {
407 autopsyType =
"autopsysystem";
409 }
else if (regFilePath.toLowerCase().contains(
"software")) {
410 autopsyType =
"autopsysoftware";
411 fullType =
"software";
412 }
else if (regFilePath.toLowerCase().contains(
"ntuser")) {
413 autopsyType =
"autopsyntuser";
415 }
else if (regFilePath.toLowerCase().contains(
"sam")) {
418 }
else if (regFilePath.toLowerCase().contains(
"security")) {
419 fullType =
"security";
420 }
else if (regFilePath.toLowerCase().contains(
"usrclass")) {
421 fullType =
"usrclass";
423 return regOutputFiles;
427 if (!autopsyType.isEmpty()) {
428 regOutputFiles.autopsyPlugins = outFilePathBase +
"-autopsy.txt";
429 String errFilePath = outFilePathBase +
"-autopsy.err.txt";
430 logger.log(Level.INFO,
"Writing RegRipper results to: {0}", regOutputFiles.autopsyPlugins);
431 executeRegRipper(rrCmd, rrHome, regFilePath, autopsyType, regOutputFiles.autopsyPlugins, errFilePath);
433 if (context.dataSourceIngestIsCancelled()) {
434 return regOutputFiles;
438 if (!fullType.isEmpty()) {
439 regOutputFiles.fullPlugins = outFilePathBase +
"-full.txt";
440 String errFilePath = outFilePathBase +
"-full.err.txt";
441 logger.log(Level.INFO,
"Writing Full RegRipper results to: {0}", regOutputFiles.fullPlugins);
442 executeRegRipper(rrFullCmd, rrFullHome, regFilePath, fullType, regOutputFiles.fullPlugins, errFilePath);
444 scanErrorLogs(errFilePath);
445 }
catch (IOException ex) {
446 logger.log(Level.SEVERE, String.format(
"Unable to run RegRipper on %s", regFilePath), ex);
447 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getName(), regFilePath));
450 return regOutputFiles;
453 private void scanErrorLogs(String errFilePath)
throws IOException {
454 File regfile =
new File(errFilePath);
455 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
456 String line = reader.readLine();
457 while (line != null) {
459 if (line.toLowerCase().contains(
"error") || line.toLowerCase().contains(
"@inc")) {
460 logger.log(Level.WARNING,
"Regripper file {0} contains errors from run", errFilePath);
463 line = reader.readLine();
468 private void executeRegRipper(List<String> regRipperPath, Path regRipperHomeDir, String hiveFilePath, String hiveFileType, String outputFile, String errFile) {
470 List<String> commandLine =
new ArrayList<>();
471 for (String cmd : regRipperPath) {
472 commandLine.add(cmd);
474 commandLine.add(
"-r");
475 commandLine.add(hiveFilePath);
476 commandLine.add(
"-f");
477 commandLine.add(hiveFileType);
479 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
480 processBuilder.directory(regRipperHomeDir.toFile());
481 processBuilder.redirectOutput(
new File(outputFile));
482 processBuilder.redirectError(
new File(errFile));
483 ExecUtil.execute(processBuilder,
new DataSourceIngestModuleProcessTerminator(context,
true));
484 }
catch (IOException ex) {
485 logger.log(Level.SEVERE, String.format(
"Error running RegRipper on %s", hiveFilePath), ex);
486 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getName(), hiveFilePath));
499 private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) {
500 FileInputStream fstream = null;
501 List<BlackboardArtifact> newArtifacts =
new ArrayList<>();
504 File regfile =
new File(regFilePath);
505 fstream =
new FileInputStream(regfile);
506 String regString =
new Scanner(fstream,
"UTF-8").useDelimiter(
"\\Z").next();
507 String startdoc =
"<?xml version=\"1.0\"?><document>";
508 String result = regString.replaceAll(
"----------------------------------------",
"");
509 result = result.replaceAll(
"\\n",
"");
510 result = result.replaceAll(
"\\r",
"");
511 result = result.replaceAll(
"'",
"'");
512 result = result.replaceAll(
"&",
"&");
513 result = result.replace(
'\0',
' ');
514 String enddoc =
"</document>";
515 String stringdoc = startdoc + result + enddoc;
516 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
517 Document doc = builder.parse(
new InputSource(
new StringReader(stringdoc)));
520 Element oroot = doc.getDocumentElement();
521 NodeList children = oroot.getChildNodes();
522 int len = children.getLength();
523 for (
int i = 0; i < len; i++) {
525 if (context.dataSourceIngestIsCancelled()) {
529 Element tempnode = (Element) children.item(i);
531 String dataType = tempnode.getNodeName();
532 NodeList timenodes = tempnode.getElementsByTagName(
"mtime");
534 if (timenodes.getLength() > 0) {
535 Element timenode = (Element) timenodes.item(0);
536 String etime = timenode.getTextContent();
538 if (etime != null && !etime.isEmpty()) {
540 mtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(etime).getTime();
541 String Tempdate = mtime.toString();
542 mtime = Long.valueOf(Tempdate) / MS_IN_SEC;
543 }
catch (ParseException ex) {
544 logger.log(Level.WARNING,
"Failed to parse epoch time when parsing the registry.", ex);
549 NodeList artroots = tempnode.getElementsByTagName(
"artifacts");
550 if (artroots.getLength() == 0) {
555 Element artroot = (Element) artroots.item(0);
556 NodeList myartlist = artroot.getChildNodes();
557 String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName();
563 String systemRoot =
"";
564 String productId =
"";
565 String regOwner =
"";
567 Long installtime = null;
568 for (
int j = 0; j < myartlist.getLength(); j++) {
569 Node artchild = myartlist.item(j);
571 if (artchild.hasAttributes()) {
572 Element artnode = (Element) artchild;
574 String value = artnode.getTextContent();
576 value = value.trim();
578 String name = artnode.getAttribute(
"name");
588 version = version +
" " + value;
596 case "RegisteredOwner":
599 case "RegisteredOrganization":
603 if (value != null && !value.isEmpty()) {
605 installtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(value).getTime();
606 String Tempdate = installtime.toString();
607 installtime = Long.valueOf(Tempdate) / MS_IN_SEC;
608 }
catch (ParseException e) {
609 logger.log(Level.WARNING,
"RegRipper::Conversion on DateTime -> ", e);
619 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
620 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, version));
621 if (installtime != null) {
622 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, installtime));
624 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, parentModuleName, systemRoot));
625 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID, parentModuleName, productId));
626 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER, parentModuleName, regOwner));
627 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION, parentModuleName, regOrg));
630 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
631 if (results.isEmpty()) {
632 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
633 bbart.addAttributes(bbattributes);
635 newArtifacts.add(bbart);
637 results.get(0).addAttributes(bbattributes);
640 }
catch (TskCoreException ex) {
641 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.");
646 String procArch =
"";
648 for (
int j = 0; j < myartlist.getLength(); j++) {
649 Node artchild = myartlist.item(j);
651 if (artchild.hasAttributes()) {
652 Element artnode = (Element) artchild;
654 String value = artnode.getTextContent().trim();
655 String name = artnode.getAttribute(
"name");
660 case "PROCESSOR_ARCHITECTURE":
663 case "PROCESSOR_IDENTIFIER":
674 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
675 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VERSION, parentModuleName, os));
676 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE, parentModuleName, procArch));
677 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR, parentModuleName, tempDir));
680 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
681 if (results.isEmpty()) {
682 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
683 bbart.addAttributes(bbattributes);
685 newArtifacts.add(bbart);
687 results.get(0).addAttributes(bbattributes);
689 }
catch (TskCoreException ex) {
690 logger.log(Level.SEVERE,
"Error adding os info artifact to blackboard.");
694 String compName =
"";
696 for (
int j = 0; j < myartlist.getLength(); j++) {
697 Node artchild = myartlist.item(j);
699 if (artchild.hasAttributes()) {
700 Element artnode = (Element) artchild;
702 String value = artnode.getTextContent().trim();
703 String name = artnode.getAttribute(
"name");
705 if (name.equals(
"ComputerName")) {
707 }
else if (name.equals(
"Domain")) {
713 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
714 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, compName));
715 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN, parentModuleName, domain));
718 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
719 if (results.isEmpty()) {
720 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_INFO);
721 bbart.addAttributes(bbattributes);
723 newArtifacts.add(bbart);
725 results.get(0).addAttributes(bbattributes);
727 }
catch (TskCoreException ex) {
728 logger.log(Level.SEVERE,
"Error adding os info artifact to blackboard.", ex);
732 for (
int j = 0; j < myartlist.getLength(); j++) {
733 Node artchild = myartlist.item(j);
735 if (artchild.hasAttributes()) {
736 Element artnode = (Element) artchild;
738 String value = artnode.getTextContent().trim();
739 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
752 Long usbMtime = Long.parseLong(artnode.getAttribute(
"mtime"));
753 usbMtime = Long.valueOf(usbMtime.toString());
755 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED);
756 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, usbMtime));
757 String dev = artnode.getAttribute(
"dev");
760 if (dev.toLowerCase().contains(
"vid")) {
761 USBInfo info = USB_MAPPER.parseAndLookup(dev);
762 if (info.getVendor() != null) {
763 make = info.getVendor();
765 if (info.getProduct() != null) {
766 model = info.getProduct();
769 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE, parentModuleName, make));
770 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL, parentModuleName, model));
771 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, value));
772 bbart.addAttributes(bbattributes);
774 newArtifacts.add(bbart);
775 }
catch (TskCoreException ex) {
776 logger.log(Level.SEVERE,
"Error adding device attached artifact to blackboard.", ex);
780 Long itemMtime = null;
782 String mTimeAttr = artnode.getAttribute(
"mtime");
783 if (mTimeAttr != null && !mTimeAttr.isEmpty()) {
784 itemMtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy").parse(mTimeAttr).getTime();
785 itemMtime /= MS_IN_SEC;
787 }
catch (ParseException ex) {
788 logger.log(Level.SEVERE,
"Failed to parse epoch time for installed program artifact.", ex);
792 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value));
793 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime));
794 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_INSTALLED_PROG);
795 bbart.addAttributes(bbattributes);
797 newArtifacts.add(bbart);
798 }
catch (TskCoreException ex) {
799 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.", ex);
803 String officeName = artnode.getAttribute(
"name");
806 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
809 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, parentModuleName, mtime));
811 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, officeName));
812 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, parentModuleName, value));
813 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, artnode.getNodeName()));
814 bbart.addAttributes(bbattributes);
816 newArtifacts.add(bbart);
817 }
catch (TskCoreException ex) {
818 logger.log(Level.SEVERE,
"Error adding recent object artifact to blackboard.", ex);
822 case "ProcessorArchitecture":
839 String homeDir = value;
840 String sid = artnode.getAttribute(
"sid");
841 String username = artnode.getAttribute(
"username");
842 BlackboardArtifact bbart = null;
845 ArrayList<BlackboardArtifact> existingArtifacts = currentCase.getSleuthkitCase().getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
846 for (BlackboardArtifact artifact : existingArtifacts) {
847 if (artifact.getDataSource().getId() == regFile.getDataSourceObjectId()) {
848 BlackboardAttribute attribute = artifact.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID));
849 if (attribute != null && attribute.getValueString().equals(sid)) {
855 }
catch (TskCoreException ex) {
856 logger.log(Level.SEVERE,
"Error getting existing os account artifact", ex);
860 bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
861 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
862 parentModuleName, username));
863 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
864 parentModuleName, sid));
865 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
866 parentModuleName, homeDir));
869 BlackboardAttribute bbattr = bbart.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_NAME));
871 if (bbattr == null) {
872 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
873 parentModuleName, username));
875 bbattr = bbart.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_PATH));
876 if (bbattr == null) {
877 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH,
878 parentModuleName, homeDir));
881 bbart.addAttributes(bbattributes);
882 newArtifacts.add(bbart);
883 }
catch (TskCoreException ex) {
884 logger.log(Level.SEVERE,
"Error adding account artifact to blackboard.", ex);
888 case "NtuserNetwork":
890 String localPath = artnode.getAttribute(
"localPath");
891 String remoteName = value;
892 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_REMOTE_DRIVE);
893 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH,
894 parentModuleName, localPath));
895 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH,
896 parentModuleName, remoteName));
897 bbart.addAttributes(bbattributes);
898 newArtifacts.add(bbart);
899 }
catch (TskCoreException ex) {
900 logger.log(Level.SEVERE,
"Error adding network artifact to blackboard.", ex);
904 String adapter = artnode.getAttribute(
"adapter");
906 Long lastWriteTime = Long.parseLong(artnode.getAttribute(
"writeTime"));
907 lastWriteTime = Long.valueOf(lastWriteTime.toString());
908 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SSID, parentModuleName, value));
909 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, lastWriteTime));
910 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, adapter));
911 BlackboardArtifact bbart = regFile.newArtifact(ARTIFACT_TYPE.TSK_WIFI_NETWORK);
912 bbart.addAttributes(bbattributes);
913 newArtifacts.add(bbart);
914 }
catch (TskCoreException ex) {
915 logger.log(Level.SEVERE,
"Error adding SSID artifact to blackboard.", ex);
925 logger.log(Level.SEVERE,
"Unrecognized node name: {0}", dataType);
934 }
catch (FileNotFoundException ex) {
935 logger.log(Level.WARNING, String.format(
"Error finding the registry file: %s", regFilePath), ex);
936 }
catch (SAXException ex) {
937 logger.log(Level.WARNING, String.format(
"Error parsing the registry XML: %s", regFilePath), ex);
938 }
catch (IOException ex) {
939 logger.log(Level.WARNING, String.format(
"Error building the document parser: %s", regFilePath), ex);
940 }
catch (ParserConfigurationException ex) {
941 logger.log(Level.WARNING, String.format(
"Error configuring the registry parser: %s", regFilePath), ex);
944 if (fstream != null) {
947 }
catch (IOException ex) {
950 postArtifacts(newArtifacts);
955 private boolean parseSystemPluginOutput(String regfilePath, AbstractFile regAbstractFile) {
956 File regfile =
new File(regfilePath);
957 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
958 String line = reader.readLine();
959 while (line != null) {
962 if (line.toLowerCase().matches(
"^bam v.*")) {
963 parseBamKey(regAbstractFile, reader, Bundle.Registry_System_Bam());
964 }
else if (line.toLowerCase().matches(
"^bthport v..*")) {
965 parseBlueToothDevices(regAbstractFile, reader);
967 line = reader.readLine();
970 }
catch (FileNotFoundException ex) {
971 logger.log(Level.WARNING,
"Error finding the registry file.", ex);
972 }
catch (IOException ex) {
973 logger.log(Level.WARNING,
"Error reading the system hive: {0}", ex);
992 private void parseBlueToothDevices(AbstractFile regFile, BufferedReader reader)
throws FileNotFoundException, IOException {
993 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
994 String line = reader.readLine();
995 while ((line != null) && (!line.contains(SECTION_DIVIDER))) {
996 line = reader.readLine();
1002 if ((line != null) && (line.toLowerCase().contains(
"device unique id"))) {
1006 while (line != null && !line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.toLowerCase().contains(
"radio support not found")) {
1007 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1008 addBlueToothAttribute(line, attributes, TSK_DEVICE_ID);
1009 line = reader.readLine();
1011 if ((line != null) && (line.toLowerCase().contains(
"name"))) {
1012 addBlueToothAttribute(line, attributes, TSK_NAME);
1013 line = reader.readLine();
1015 addBlueToothAttribute(line, attributes, TSK_DATETIME);
1016 line = reader.readLine();
1017 addBlueToothAttribute(line, attributes, TSK_DATETIME_ACCESSED);
1018 BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING, regFile, attributes);
1020 bbartifacts.add(bba);
1024 line = reader.readLine();
1032 if (!bbartifacts.isEmpty()) {
1033 postArtifacts(bbartifacts);
1037 private void addBlueToothAttribute(String line, Collection<BlackboardAttribute> attributes, ATTRIBUTE_TYPE attributeType) {
1042 String tokens[] = line.split(
": ");
1043 if (tokens.length > 1 && !tokens[1].isEmpty()) {
1044 String tokenString = tokens[1];
1045 if (attributeType.getDisplayName().toLowerCase().contains(
"date")) {
1046 String dateString = tokenString.toLowerCase().replace(
" z",
"");
1048 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy", US);
1049 Long dateLong = Long.valueOf(0);
1051 Date newDate = dateFormat.parse(dateString);
1052 dateLong = newDate.getTime() / 1000;
1053 }
catch (ParseException ex) {
1056 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for Bluetooth Last Seen attribute.", dateString), ex);
1058 attributes.add(
new BlackboardAttribute(attributeType, getName(), dateLong));
1060 attributes.add(
new BlackboardAttribute(attributeType, getName(), tokenString));
1074 private boolean parseSamPluginOutput(String regFilePath, AbstractFile regAbstractFile) {
1075 File regfile =
new File(regFilePath);
1076 List<BlackboardArtifact> newArtifacts =
new ArrayList<>();
1077 try (BufferedReader bufferedReader =
new BufferedReader(
new FileReader(regfile))) {
1079 String userInfoSection =
"User Information";
1080 String previousLine = null;
1081 String line = bufferedReader.readLine();
1082 Set<Map<String, String>> userSet =
new HashSet<>();
1083 Map<String, List<String>> groupMap = null;
1084 while (line != null) {
1085 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(userInfoSection)) {
1086 readUsers(bufferedReader, userSet);
1089 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(
"Group Membership Information")) {
1090 groupMap = readGroups(bufferedReader);
1093 previousLine = line;
1094 line = bufferedReader.readLine();
1096 Map<String, Map<String, String>> userInfoMap =
new HashMap<>();
1098 for (Map<String, String> userInfo : userSet) {
1099 userInfoMap.put(userInfo.get(SID_KEY), userInfo);
1102 List<BlackboardArtifact> existingOsAccounts = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
1103 for (BlackboardArtifact osAccount : existingOsAccounts) {
1105 if (osAccount.getDataSource().getId() == regAbstractFile.getDataSourceObjectId()) {
1106 BlackboardAttribute existingUserId = osAccount.getAttribute(
new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_USER_ID));
1107 if (existingUserId != null) {
1108 String userID = existingUserId.getValueString().trim();
1109 Map<String, String> userInfo = userInfoMap.remove(userID);
1111 if (userInfo != null) {
1112 osAccount.addAttributes(getAttributesForAccount(userInfo, groupMap.get(userID),
true, regAbstractFile));
1119 for (Map<String, String> userInfo : userInfoMap.values()) {
1120 BlackboardArtifact bbart = regAbstractFile.newArtifact(ARTIFACT_TYPE.TSK_OS_ACCOUNT);
1121 bbart.addAttributes(getAttributesForAccount(userInfo, groupMap.get(userInfo.get(SID_KEY)),
false, regAbstractFile));
1123 newArtifacts.add(bbart);
1128 userNameMap = makeUserNameMap(dataSource);
1129 }
catch (TskCoreException ex) {
1130 logger.log(Level.WARNING,
"Unable to create OS Account user name map", ex);
1133 userNameMap =
new HashMap<>();
1136 }
catch (FileNotFoundException ex) {
1137 logger.log(Level.WARNING,
"Error finding the registry file.", ex);
1138 }
catch (IOException ex) {
1139 logger.log(Level.WARNING,
"Error building the document parser: {0}", ex);
1140 }
catch (ParseException ex) {
1141 logger.log(Level.WARNING,
"Error parsing the the date from the registry file", ex);
1142 }
catch (TskCoreException ex) {
1143 logger.log(Level.WARNING,
"Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex);
1145 postArtifacts(newArtifacts);
1161 Collection<BlackboardAttribute> getAttributesForAccount(Map<String, String> userInfo, List<String> groupList,
boolean existingUser, AbstractFile regAbstractFile)
throws ParseException {
1162 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
1164 SimpleDateFormat regRipperTimeFormat =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'");
1165 regRipperTimeFormat.setTimeZone(getTimeZone(
"GMT"));
1167 if (!existingUser) {
1168 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_ID,
1169 getRAModuleName(), userInfo.get(SID_KEY)));
1171 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME,
1172 this.moduleName, userInfo.get(USERNAME_KEY)));
1175 String value = userInfo.get(ACCOUNT_CREATED_KEY);
1176 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
1177 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_CREATED,
1178 getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
1181 value = userInfo.get(LAST_LOGIN_KEY);
1182 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
1183 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED,
1184 getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
1187 value = userInfo.get(LOGIN_COUNT_KEY);
1188 if (value != null && !value.isEmpty()) {
1189 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
1190 getRAModuleName(), Integer.parseInt(value)));
1193 value = userInfo.get(ACCOUNT_TYPE_KEY);
1194 if (value != null && !value.isEmpty()) {
1195 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE,
1196 getRAModuleName(), value));
1199 value = userInfo.get(USER_COMMENT_KEY);
1200 if (value != null && !value.isEmpty()) {
1201 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DESCRIPTION,
1202 getRAModuleName(), value));
1205 value = userInfo.get(NAME_KEY);
1206 if (value != null && !value.isEmpty()) {
1207 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME,
1208 getRAModuleName(), value));
1211 value = userInfo.get(INTERNET_NAME_KEY);
1212 if (value != null && !value.isEmpty()) {
1215 Case.getCurrentCaseThrows()
1217 .getCommunicationsManager()
1218 .createAccountFileInstance(Account.Type.EMAIL,
1219 value, getRAModuleName(), regAbstractFile);
1220 }
catch (NoCurrentCaseException | TskCoreException ex) {
1221 logger.log(Level.SEVERE,
1222 String.format(
"Error adding email account with value "
1223 +
"%s, to the case database for file %s [objId=%d]",
1224 value, regAbstractFile.getName(), regAbstractFile.getId()), ex);
1227 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_EMAIL,
1228 getRAModuleName(), value));
1231 value = userInfo.get(FULL_NAME_KEY);
1232 if (value != null && !value.isEmpty()) {
1233 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DISPLAY_NAME,
1234 getRAModuleName(), value));
1237 value = userInfo.get(PWD_RESET_KEY);
1238 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
1239 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_RESET,
1240 getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
1243 value = userInfo.get(PASSWORD_HINT);
1244 if (value != null && !value.isEmpty()) {
1245 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_HINT,
1246 getRAModuleName(), value));
1249 value = userInfo.get(PWD_FAILE_KEY);
1250 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
1251 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_FAIL,
1252 getRAModuleName(), regRipperTimeFormat.parse(value).getTime() / MS_IN_SEC));
1255 String settingString =
"";
1256 for (String setting : PASSWORD_SETTINGS_FLAGS) {
1257 if (userInfo.containsKey(setting)) {
1258 settingString += setting +
", ";
1262 if (!settingString.isEmpty()) {
1263 settingString = settingString.substring(0, settingString.length() - 2);
1264 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_SETTINGS,
1265 getRAModuleName(), settingString));
1269 for (String setting : ACCOUNT_SETTINGS_FLAGS) {
1270 if (userInfo.containsKey(setting)) {
1271 settingString += setting +
", ";
1275 if (!settingString.isEmpty()) {
1276 settingString = settingString.substring(0, settingString.length() - 2);
1277 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_SETTINGS,
1278 getRAModuleName(), settingString));
1282 for (String setting : ACCOUNT_TYPE_FLAGS) {
1283 if (userInfo.containsKey(setting)) {
1284 settingString += setting +
", ";
1288 if (!settingString.isEmpty()) {
1289 settingString = settingString.substring(0, settingString.length() - 2);
1290 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_FLAG,
1291 getRAModuleName(), settingString));
1294 if (groupList != null && groupList.isEmpty()) {
1296 for (String group : groupList) {
1297 groups += group +
", ";
1300 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GROUPS,
1301 getRAModuleName(), groups.substring(0, groups.length() - 2)));
1304 return bbattributes;
1318 private void readUsers(BufferedReader bufferedReader, Set<Map<String, String>> users) throws IOException {
1319 String line = bufferedReader.readLine();
1321 String userName =
"";
1322 String user_rid =
"";
1323 while (line != null && !line.contains(SECTION_DIVIDER)) {
1325 if (line.contains(USERNAME_KEY)) {
1326 String regx = USERNAME_KEY +
"\\s*?:";
1327 String userNameAndIdString = line.replaceAll(regx,
"");
1328 userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf(
'[')).trim();
1329 user_rid = userNameAndIdString.substring(userNameAndIdString.lastIndexOf(
'['), userNameAndIdString.lastIndexOf(
']'));
1330 }
else if (line.contains(SID_KEY) && !userName.isEmpty()) {
1331 Map.Entry<String, String> entry = getSAMKeyValue(line);
1333 HashMap<String, String> userInfo =
new HashMap<>();
1334 userInfo.put(USERNAME_KEY, userName);
1335 userInfo.put(RID_KEY, user_rid);
1336 userInfo.put(entry.getKey(), entry.getValue());
1339 line = bufferedReader.readLine();
1340 while (line != null && !line.isEmpty()) {
1341 entry = getSAMKeyValue(line);
1342 if (entry != null) {
1343 userInfo.put(entry.getKey(), entry.getValue());
1345 line = bufferedReader.readLine();
1347 users.add(userInfo);
1351 line = bufferedReader.readLine();
1364 private void createRecentlyUsedArtifacts(String regFileName, AbstractFile regFile)
throws FileNotFoundException, IOException {
1365 File regfile =
new File(regFileName);
1366 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
1367 String line = reader.readLine();
1368 while (line != null) {
1371 if (line.matches(
"^adoberdr v.*")) {
1372 parseAdobeMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Adobe());
1373 }
else if (line.matches(
"^mpmru v.*")) {
1374 parseMediaPlayerMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Mediaplayer());
1375 }
else if (line.matches(
"^trustrecords v.*")) {
1376 parseOfficeTrustRecords(regFile, reader, Bundle.Recently_Used_Artifacts_Office_Trustrecords());
1377 }
else if (line.matches(
"^ArcHistory:")) {
1378 parse7ZipMRU(regFile, reader, Bundle.Recently_Used_Artifacts_ArcHistory());
1379 }
else if (line.matches(
"^applets v.*")) {
1380 parseGenericMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Applets());
1381 }
else if (line.matches(
"^mmc v.*")) {
1382 parseGenericMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Mmc());
1383 }
else if (line.matches(
"^winrar v.*")) {
1384 parseWinRARMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Winrar());
1385 }
else if (line.matches(
"^officedocs2010 v.*")) {
1386 parseOfficeDocs2010MRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Officedocs());
1388 line = reader.readLine();
1404 private void parseBamKey(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1405 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1406 String line = reader.readLine();
1408 while (!line.contains(SECTION_DIVIDER)) {
1409 line = reader.readLine();
1412 line = reader.readLine();
1414 while (!line.contains(SECTION_DIVIDER)) {
1417 String tokens[] = line.split(
"\\|");
1418 Long progRunDateTime = Long.valueOf(tokens[0]);
1421 String fileNameSid[] = tokens[4].split(
"\\s+\\(S-");
1422 String userSid =
"S-" + fileNameSid[1].substring(0, fileNameSid[1].length() - 1);
1423 String userName = userNameMap.get(userSid);
1424 if (userName == null) {
1427 String fileName = fileNameSid[0];
1428 if (fileName.startsWith(
"\\Device\\HarddiskVolume")) {
1430 int fileNameStart = fileName.indexOf(
'\\', 16);
1431 fileName = fileName.substring(fileNameStart, fileName.length());
1434 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1435 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(), fileName));
1436 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, getName(), userName));
1437 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, getName(), progRunDateTime));
1438 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, getName(), comment));
1439 BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_PROG_RUN, regFile, attributes);
1441 bbartifacts.add(bba);
1442 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1444 bbartifacts.add(bba);
1447 line = reader.readLine();
1449 if (!bbartifacts.isEmpty()) {
1450 postArtifacts(bbartifacts);
1465 private void parseAdobeMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1466 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1467 String line = reader.readLine();
1468 SimpleDateFormat adobePluginDateFormat =
new SimpleDateFormat(
"yyyyMMddHHmmssZ", US);
1469 Long adobeUsedTime = Long.valueOf(0);
1470 while (!line.contains(SECTION_DIVIDER)) {
1471 line = reader.readLine();
1473 if (line.matches(
"^Key name,file name,sDate,uFileSize,uPageCount")) {
1474 line = reader.readLine();
1477 while (!line.contains(SECTION_DIVIDER)) {
1480 String tokens[] = line.split(
",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
1481 String fileName = tokens[1].substring(0, tokens[1].length() - 1);
1482 fileName = fileName.replace(
"\"",
"");
1483 if (fileName.charAt(0) ==
'/') {
1484 fileName = fileName.substring(1, fileName.length() - 1);
1485 fileName = fileName.replaceFirst(
"/",
":/");
1488 if (tokens.length > 2) {
1491 String fileUsedTime = tokens[2].replaceAll(
"'",
"");
1492 Date usedDate = adobePluginDateFormat.parse(fileUsedTime);
1493 adobeUsedTime = usedDate.getTime() / 1000;
1494 }
catch (ParseException ex) {
1497 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for adobe file artifact.", tokens[2]), ex);
1500 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1501 attributes.add(
new BlackboardAttribute(TSK_PATH, getName(), fileName));
1502 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, getName(), adobeUsedTime));
1503 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getName(), comment));
1504 BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_RECENT_OBJECT, regFile, attributes);
1506 bbartifacts.add(bba);
1507 fileName = fileName.replace(
"\0",
"");
1508 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1510 bbartifacts.add(bba);
1513 line = reader.readLine();
1518 if (!bbartifacts.isEmpty()) {
1519 postArtifacts(bbartifacts);
1535 private void parseMediaPlayerMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1536 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1537 String line = reader.readLine();
1538 while (!line.contains(SECTION_DIVIDER)) {
1539 line = reader.readLine();
1541 if (line.contains(
"LastWrite")) {
1542 line = reader.readLine();
1545 while (!line.contains(SECTION_DIVIDER) && !line.contains(
"RecentFileList has no values.")) {
1547 String tokens[] = line.split(
"> ");
1548 String fileName = tokens[1];
1549 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1550 attributes.add(
new BlackboardAttribute(TSK_PATH, getName(), fileName));
1551 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getName(), comment));
1552 BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_RECENT_OBJECT, regFile, attributes);
1554 bbartifacts.add(bba);
1555 bba = createAssociatedArtifact(fileName, bba);
1557 bbartifacts.add(bba);
1558 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1560 bbartifacts.add(bba);
1564 line = reader.readLine();
1569 if (!bbartifacts.isEmpty()) {
1570 postArtifacts(bbartifacts);
1586 private void parseGenericMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1587 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1588 String line = reader.readLine();
1589 while (!line.contains(SECTION_DIVIDER)) {
1590 line = reader.readLine();
1592 if (line.contains(
"LastWrite")) {
1593 line = reader.readLine();
1596 while (!line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains(
"Applets")
1597 && !line.contains((
"Recent File List"))) {
1599 String tokens[] = line.split(
"> ");
1600 String fileName = tokens[1];
1601 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1602 attributes.add(
new BlackboardAttribute(TSK_PATH, getName(), fileName));
1603 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getName(), comment));
1604 BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_RECENT_OBJECT, regFile, attributes);
1606 bbartifacts.add(bba);
1607 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1609 bbartifacts.add(bba);
1612 line = reader.readLine();
1617 if (!bbartifacts.isEmpty()) {
1618 postArtifacts(bbartifacts);
1634 private void parseWinRARMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1635 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1636 String line = reader.readLine();
1637 while (!line.contains(SECTION_DIVIDER)) {
1638 line = reader.readLine();
1640 if (line.contains(
"LastWrite")) {
1641 line = reader.readLine();
1644 if (!line.isEmpty()) {
1645 while (!line.contains(SECTION_DIVIDER)) {
1647 String tokens[] = line.split(
"> ");
1648 String fileName = tokens[1];
1649 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1650 attributes.add(
new BlackboardAttribute(TSK_PATH, getName(), fileName));
1651 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getName(), comment));
1652 BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_RECENT_OBJECT, regFile, attributes);
1654 bbartifacts.add(bba);
1655 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1657 bbartifacts.add(bba);
1660 line = reader.readLine();
1666 if (!bbartifacts.isEmpty()) {
1667 postArtifacts(bbartifacts);
1683 private void parse7ZipMRU(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1684 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1685 String line = reader.readLine();
1687 if (!line.contains(
"PathHistory:")) {
1688 while (!line.contains(
"PathHistory:") && !line.isEmpty()) {
1691 String fileName = line;
1692 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1693 attributes.add(
new BlackboardAttribute(TSK_PATH, getName(), fileName));
1694 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getName(), comment));
1695 BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_RECENT_OBJECT, regFile, attributes);
1697 bbartifacts.add(bba);
1698 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1700 bbartifacts.add(bba);
1703 line = reader.readLine();
1707 if (!bbartifacts.isEmpty()) {
1708 postArtifacts(bbartifacts);
1724 private void parseOfficeDocs2010MRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1725 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1726 String line = reader.readLine();
1730 while (!line.contains(SECTION_DIVIDER)) {
1731 line = reader.readLine();
1733 line = reader.readLine();
1734 while (!line.contains(SECTION_DIVIDER)) {
1737 String tokens[] = line.split(
"\\|");
1738 Long docDate = Long.valueOf(tokens[0]);
1739 String fileNameTokens[] = tokens[4].split(
" - ");
1740 String fileName = fileNameTokens[1];
1741 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1742 attributes.add(
new BlackboardAttribute(TSK_PATH, getName(), fileName));
1743 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, getName(), docDate));
1744 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getName(), comment));
1745 BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_RECENT_OBJECT, regFile, attributes);
1747 bbartifacts.add(bba);
1748 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1750 bbartifacts.add(bba);
1753 line = reader.readLine();
1756 if (!bbartifacts.isEmpty()) {
1757 postArtifacts(bbartifacts);
1773 private void parseOfficeTrustRecords(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1774 String userProfile = regFile.getParentPath();
1775 userProfile = userProfile.substring(0, userProfile.length() - 1);
1776 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1777 SimpleDateFormat pluginDateFormat =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy", US);
1778 Long usedTime = Long.valueOf(0);
1779 String line = reader.readLine();
1780 while (!line.contains(SECTION_DIVIDER)) {
1781 line = reader.readLine();
1783 usedTime = Long.valueOf(0);
1784 if (!line.contains(
"**") && !line.contains(
"----------") && !line.contains(
"LastWrite")
1785 && !line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains(
"TrustRecords")) {
1789 String fileName = null;
1790 String tokens[] = line.split(
" : ");
1791 fileName = tokens[1];
1792 fileName = fileName.replace(
"%USERPROFILE%", userProfile);
1795 String fileUsedTime = tokens[0].replaceAll(
" Z",
"");
1796 Date usedDate = pluginDateFormat.parse(fileUsedTime);
1797 usedTime = usedDate.getTime() / 1000;
1798 }
catch (ParseException ex) {
1801 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for TrustRecords artifact.", tokens[0]), ex);
1803 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1804 attributes.add(
new BlackboardAttribute(TSK_PATH, getName(), fileName));
1805 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, getName(), usedTime));
1806 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getName(), comment));
1807 BlackboardArtifact bba = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_RECENT_OBJECT, regFile, attributes);
1809 bbartifacts.add(bba);
1810 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1812 bbartifacts.add(bba);
1818 if (!bbartifacts.isEmpty()) {
1819 postArtifacts(bbartifacts);
1833 private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) {
1835 String fileName = FilenameUtils.getName(filePathName);
1836 String filePath = FilenameUtils.getPath(filePathName);
1837 List<AbstractFile> sourceFiles;
1839 sourceFiles = fileManager.
findFiles(dataSource, fileName, filePath);
1840 if (!sourceFiles.isEmpty()) {
1841 for (AbstractFile sourceFile : sourceFiles) {
1842 if (sourceFile.getParentPath().endsWith(filePath)) {
1843 Collection<BlackboardAttribute> bbattributes2 =
new ArrayList<>();
1844 bbattributes2.addAll(Arrays.asList(
1845 new BlackboardAttribute(TSK_ASSOCIATED_ARTIFACT, this.getName(),
1846 bba.getArtifactID())));
1848 BlackboardArtifact associatedObjectBba = createArtifactWithAttributes(TSK_ASSOCIATED_OBJECT, sourceFile, bbattributes2);
1849 if (associatedObjectBba != null) {
1850 return associatedObjectBba;
1855 }
catch (TskCoreException ex) {
1858 logger.log(Level.WARNING, String.format(
"Error finding actual file %s. file may not exist", filePathName));
1873 private Map<String, String> makeUserNameMap(Content dataSource)
throws TskCoreException {
1874 Map<String, String> userNameMap =
new HashMap<>();
1876 List<BlackboardArtifact> accounts = blackboard.getArtifacts(TSK_OS_ACCOUNT.getTypeID(), dataSource.getId());
1878 for (BlackboardArtifact account : accounts) {
1879 BlackboardAttribute nameAttribute = getAttributeForArtifact(account, TSK_USER_NAME);
1880 BlackboardAttribute idAttribute = getAttributeForArtifact(account, TSK_USER_ID);
1882 String userName = nameAttribute != null ? nameAttribute.getDisplayString() :
"";
1883 String userID = idAttribute != null ? idAttribute.getDisplayString() :
"";
1885 if (!userID.isEmpty()) {
1886 userNameMap.put(userID, userName);
1903 private BlackboardAttribute getAttributeForArtifact(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type) throws TskCoreException {
1904 return artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(type.getTypeID())));
1915 void createShellBagArtifacts(AbstractFile regFile, List<ShellBag> shellbags)
throws TskCoreException {
1916 List<BlackboardArtifact> artifacts =
new ArrayList<>();
1918 for (ShellBag bag : shellbags) {
1919 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1920 BlackboardArtifact artifact = regFile.newArtifact(getShellBagArtifact().getTypeID());
1921 attributes.add(
new BlackboardAttribute(TSK_PATH, getName(), bag.getResource()));
1922 attributes.add(
new BlackboardAttribute(getKeyAttribute(), getName(), bag.getKey()));
1925 time = bag.getLastWrite();
1927 attributes.add(
new BlackboardAttribute(getLastWriteAttribute(), getName(), time));
1930 time = bag.getModified();
1932 attributes.add(
new BlackboardAttribute(TSK_DATETIME_MODIFIED, getName(), time));
1935 time = bag.getCreated();
1937 attributes.add(
new BlackboardAttribute(TSK_DATETIME_CREATED, getName(), time));
1940 time = bag.getAccessed();
1942 attributes.add(
new BlackboardAttribute(TSK_DATETIME_ACCESSED, getName(), time));
1945 artifact.addAttributes(attributes);
1947 artifacts.add(artifact);
1950 postArtifacts(artifacts);
1962 private BlackboardArtifact.Type getShellBagArtifact() throws TskCoreException {
1963 if (shellBagArtifactType == null) {
1964 shellBagArtifactType = tskCase.getArtifactType(SHELLBAG_ARTIFACT_NAME);
1966 if (shellBagArtifactType == null) {
1968 tskCase.addBlackboardArtifactType(SHELLBAG_ARTIFACT_NAME, Bundle.Shellbag_Artifact_Display_Name());
1969 }
catch (TskDataException ex) {
1971 logger.log(Level.INFO, String.format(
"%s may have already been defined for this case", SHELLBAG_ARTIFACT_NAME));
1974 shellBagArtifactType = tskCase.getArtifactType(SHELLBAG_ARTIFACT_NAME);
1978 return shellBagArtifactType;
1989 private BlackboardAttribute.Type getLastWriteAttribute() throws TskCoreException {
1990 if (shellBagLastWriteAttributeType == null) {
1992 shellBagLastWriteAttributeType = tskCase.addArtifactAttributeType(SHELLBAG_ATTRIBUTE_LAST_WRITE,
1993 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME,
1994 Bundle.Shellbag_Last_Write_Attribute_Display_Name());
1995 }
catch (TskDataException ex) {
1997 shellBagLastWriteAttributeType = tskCase.getAttributeType(SHELLBAG_ATTRIBUTE_LAST_WRITE);
2000 return shellBagLastWriteAttributeType;
2011 private BlackboardAttribute.Type getKeyAttribute() throws TskCoreException {
2012 if (shellBagKeyAttributeType == null) {
2014 shellBagKeyAttributeType = tskCase.addArtifactAttributeType(SHELLBAG_ATTRIBUTE_KEY,
2015 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2016 Bundle.Shellbag_Key_Attribute_Display_Name());
2017 }
catch (TskDataException ex) {
2019 shellBagKeyAttributeType = tskCase.getAttributeType(SHELLBAG_ATTRIBUTE_KEY);
2022 return shellBagKeyAttributeType;
2034 Map<String, List<String>> readGroups(BufferedReader bufferedReader)
throws IOException {
2035 Map<String, List<String>> groupMap =
new HashMap<>();
2037 String line = bufferedReader.readLine();
2040 String groupName = null;
2042 while (line != null && !line.contains(SECTION_DIVIDER)) {
2044 if (line.contains(
"Group Name")) {
2045 String value = line.replaceAll(
"Group Name\\s*?:",
"").trim();
2046 groupName = (value.replaceAll(
"\\[\\d*?\\]",
"")).trim();
2047 int startIndex = value.indexOf(
" [") + 1;
2048 int endIndex = value.indexOf(
']');
2050 if (startIndex != -1 && endIndex != -1) {
2051 String countStr = value.substring(startIndex + 1, endIndex);
2052 userCount = Integer.parseInt(countStr);
2054 }
else if (line.matches(
"Users\\s*?:")) {
2055 for (
int i = 0; i < userCount; i++) {
2056 line = bufferedReader.readLine();
2058 String sid = line.trim();
2059 List<String> groupList = groupMap.get(sid);
2060 if (groupList == null) {
2061 groupList =
new ArrayList<>();
2062 groupMap.put(sid, groupList);
2064 groupList.add(groupName);
2069 line = bufferedReader.readLine();
2082 private Map.Entry<String, String> getSAMKeyValue(String line) {
2083 int index = line.indexOf(
':');
2084 Map.Entry<String, String> returnValue = null;
2086 String value = null;
2089 key = line.substring(0, index).trim();
2090 if (index + 1 < line.length()) {
2091 value = line.substring(index + 1).trim();
2096 }
else if (line.contains(
"-->")) {
2097 key = line.replace(
"-->",
"").trim();
2102 returnValue =
new AbstractMap.SimpleEntry<>(key, value);
2109 public void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
2110 this.dataSource = dataSource;
2111 this.context = context;
2113 progressBar.progress(Bundle.Progress_Message_Analyze_Registry());
2114 analyzeRegistryFiles();
2123 public String autopsyPlugins =
"";
2124 public String fullPlugins =
"";
synchronized List< AbstractFile > findFiles(String fileName)