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.InputStreamReader;
33 import java.io.StringReader;
34 import java.nio.charset.StandardCharsets;
35 import java.text.ParseException;
36 import java.text.SimpleDateFormat;
37 import java.util.logging.Level;
38 import javax.xml.parsers.DocumentBuilder;
39 import javax.xml.parsers.DocumentBuilderFactory;
40 import javax.xml.parsers.ParserConfigurationException;
41 import org.apache.commons.io.FilenameUtils;
42 import org.openide.modules.InstalledFileLocator;
43 import org.openide.util.NbBundle;
51 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
52 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
53 import org.w3c.dom.Document;
54 import org.w3c.dom.Element;
55 import org.w3c.dom.Node;
56 import org.w3c.dom.NodeList;
57 import org.xml.sax.InputSource;
58 import org.xml.sax.SAXException;
59 import java.nio.file.Path;
60 import java.util.AbstractMap;
61 import java.util.ArrayList;
62 import java.util.List;
63 import java.util.Collection;
64 import java.util.Date;
65 import java.util.HashMap;
67 import java.util.Scanner;
69 import java.util.HashSet;
70 import static java.util.Locale.US;
71 import java.util.Optional;
72 import static java.util.TimeZone.getTimeZone;
73 import java.util.stream.Collectors;
74 import org.openide.util.Lookup;
81 import org.
sleuthkit.datamodel.Blackboard.BlackboardException;
84 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT;
85 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
86 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED;
87 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED;
88 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED;
89 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID;
90 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME;
91 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH;
92 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HOME_DIR;
98 import org.
sleuthkit.datamodel.OsAccount.OsAccountAttribute;
101 import org.
sleuthkit.datamodel.OsAccountManager.NotUserSIDException;
102 import org.
sleuthkit.datamodel.OsAccountManager.OsAccountUpdateResult;
104 import org.
sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
116 "RegRipperNotFound=Autopsy RegRipper executable not found.",
117 "RegRipperFullNotFound=Full version RegRipper executable not found.",
118 "Progress_Message_Analyze_Registry=Analyzing Registry Files",
119 "Shellbag_Artifact_Display_Name=Shell Bags",
120 "Shellbag_Key_Attribute_Display_Name=Key",
121 "Shellbag_Last_Write_Attribute_Display_Name=Last Write",
122 "Recently_Used_Artifacts_Office_Trustrecords=Stored in TrustRecords because Office security exception was granted",
123 "Recently_Used_Artifacts_ArcHistory=Recently opened by 7Zip",
124 "Recently_Used_Artifacts_Applets=Recently opened according to Applets registry key",
125 "Recently_Used_Artifacts_Mmc=Recently opened according to Windows Management Console MRU",
126 "Recently_Used_Artifacts_Winrar=Recently opened according to WinRAR MRU",
127 "Recently_Used_Artifacts_Officedocs=Recently opened according to Office MRU",
128 "Recently_Used_Artifacts_Adobe=Recently opened according to Adobe MRU",
129 "Recently_Used_Artifacts_Mediaplayer=Recently opened according to Media Player MRU",
130 "Registry_System_Bam=Recently Executed according to Background Activity Moderator (BAM)"
132 class ExtractRegistry extends Extract {
134 private static final String USERNAME_KEY =
"Username";
135 private static final String SID_KEY =
"SID";
136 private static final String RID_KEY =
"RID";
137 private static final String ACCOUNT_CREATED_KEY =
"Account Created";
138 private static final String LAST_LOGIN_KEY =
"Last Login Date";
139 private static final String LOGIN_COUNT_KEY =
"Login Count";
140 private static final String FULL_NAME_KEY =
"Full Name";
141 private static final String USER_COMMENT_KEY =
"User Comment";
142 private static final String ACCOUNT_TYPE_KEY =
"Account Type";
143 private static final String NAME_KEY =
"Name";
144 private static final String PWD_RESET_KEY =
"Pwd Rest Date";
145 private static final String PWD_FAILE_KEY =
"Pwd Fail Date";
146 private static final String INTERNET_NAME_KEY =
"InternetName";
147 private static final String PWD_DOES_NOT_EXPIRE_KEY =
"Password does not expire";
148 private static final String ACCOUNT_DISABLED_KEY =
"Account Disabled";
149 private static final String PWD_NOT_REQUIRED_KEY =
"Password not required";
150 private static final String NORMAL_ACCOUNT_KEY =
"Normal user account";
151 private static final String HOME_DIRECTORY_REQUIRED_KEY =
"Home directory required";
152 private static final String TEMPORARY_DUPLICATE_ACCOUNT =
"Temporary duplicate account";
153 private static final String MNS_LOGON_ACCOUNT_KEY =
"MNS logon user account";
154 private static final String INTERDOMAIN_TRUST_ACCOUNT_KEY =
"Interdomain trust account";
155 private static final String WORKSTATION_TRUST_ACCOUNT =
"Workstation trust account";
156 private static final String SERVER_TRUST_ACCOUNT =
"Server trust account";
157 private static final String ACCOUNT_AUTO_LOCKED =
"Account auto locked";
158 private static final String PASSWORD_HINT =
"Password Hint";
160 private static final String[] PASSWORD_SETTINGS_FLAGS = {PWD_DOES_NOT_EXPIRE_KEY, PWD_NOT_REQUIRED_KEY};
161 private static final String[] ACCOUNT_SETTINGS_FLAGS = {ACCOUNT_AUTO_LOCKED, HOME_DIRECTORY_REQUIRED_KEY, ACCOUNT_DISABLED_KEY};
162 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};
164 final private static UsbDeviceIdMapper USB_MAPPER =
new UsbDeviceIdMapper();
165 final private static String RIP_EXE =
"rip.exe";
166 final private static String RIP_PL =
"rip.pl";
167 final private static String RIP_PL_INCLUDE_FLAG =
"-I";
168 final private static int MS_IN_SEC = 1000;
169 final private static String NEVER_DATE =
"Never";
170 final private static String SECTION_DIVIDER =
"-------------------------";
171 final private static Logger logger = Logger.getLogger(ExtractRegistry.class.getName());
172 private final List<String> rrCmd =
new ArrayList<>();
173 private final List<String> rrFullCmd =
new ArrayList<>();
174 private final Path rrHome;
175 private final Path rrFullHome;
176 private Content dataSource;
177 private final IngestJobContext context;
178 private Map<String, String> userNameMap;
179 private final List<String> samDomainIDsList =
new ArrayList<>();
181 private String compName =
"";
182 private String domainName =
"";
184 private static final String SHELLBAG_ARTIFACT_NAME =
"RA_SHELL_BAG";
185 private static final String SHELLBAG_ATTRIBUTE_LAST_WRITE =
"RA_SHELL_BAG_LAST_WRITE";
186 private static final String SHELLBAG_ATTRIBUTE_KEY =
"RA_SHELL_BAG_KEY";
188 private static final SimpleDateFormat REG_RIPPER_TIME_FORMAT =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'", US);
190 private BlackboardArtifact.Type shellBagArtifactType = null;
191 private BlackboardAttribute.Type shellBagKeyAttributeType = null;
192 private BlackboardAttribute.Type shellBagLastWriteAttributeType = null;
195 REG_RIPPER_TIME_FORMAT.setTimeZone(getTimeZone(
"GMT"));
198 ExtractRegistry(IngestJobContext context)
throws IngestModuleException {
199 super(NbBundle.getMessage(ExtractRegistry.class,
"ExtractRegistry.moduleName.text"), context);
200 this.context = context;
202 final File rrRoot = InstalledFileLocator.getDefault().locate(
"rr", ExtractRegistry.class.getPackage().getName(),
false);
203 if (rrRoot == null) {
204 throw new IngestModuleException(Bundle.RegRipperNotFound());
207 final File rrFullRoot = InstalledFileLocator.getDefault().locate(
"rr-full", ExtractRegistry.class.getPackage().getName(),
false);
208 if (rrFullRoot == null) {
209 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
212 String executableToRun = RIP_EXE;
213 if (!PlatformUtil.isWindowsOS()) {
214 executableToRun = RIP_PL;
216 rrHome = rrRoot.toPath();
217 String rrPath = rrHome.resolve(executableToRun).toString();
218 rrFullHome = rrFullRoot.toPath();
220 if (!(
new File(rrPath).exists())) {
221 throw new IngestModuleException(Bundle.RegRipperNotFound());
223 String rrFullPath = rrFullHome.resolve(executableToRun).toString();
224 if (!(
new File(rrFullPath).exists())) {
225 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
227 if (PlatformUtil.isWindowsOS()) {
229 rrFullCmd.add(rrFullPath);
232 File usrBin =
new File(
"/usr/bin/perl");
233 File usrLocalBin =
new File(
"/usr/local/bin/perl");
234 if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
235 perl =
"/usr/bin/perl";
236 }
else if (usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()) {
237 perl =
"/usr/local/bin/perl";
239 throw new IngestModuleException(
"perl not found in your system");
242 rrCmd.add(RIP_PL_INCLUDE_FLAG);
243 rrCmd.add(rrHome.toString());
246 rrFullCmd.add(RIP_PL_INCLUDE_FLAG);
247 rrFullCmd.add(rrFullHome.toString());
248 rrFullCmd.add(rrFullPath);
255 private List<AbstractFile> findRegistryFiles() {
256 List<AbstractFile> allRegistryFiles =
new ArrayList<>();
261 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"sam",
"/system32/config"));
262 }
catch (TskCoreException ex) {
263 String msg = NbBundle.getMessage(this.getClass(),
264 "ExtractRegistry.findRegFiles.errMsg.errReadingFile",
"sam");
265 logger.log(Level.WARNING, msg, ex);
266 this.addErrorMessage(this.getDisplayName() +
": " + msg);
271 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"ntuser.dat"));
272 }
catch (TskCoreException ex) {
273 logger.log(Level.WARNING,
"Error fetching 'ntuser.dat' file.");
278 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"usrclass.dat"));
279 }
catch (TskCoreException ex) {
280 logger.log(Level.WARNING, String.format(
"Error finding 'usrclass.dat' files."), ex);
284 String[] regFileNames =
new String[]{
"system",
"software",
"security"};
285 for (String regFileName : regFileNames) {
287 allRegistryFiles.addAll(fileManager.findFiles(dataSource, regFileName,
"/system32/config"));
288 }
catch (TskCoreException ex) {
289 String msg = NbBundle.getMessage(this.getClass(),
290 "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName);
291 logger.log(Level.WARNING, msg, ex);
292 this.addErrorMessage(this.getDisplayName() +
": " + msg);
295 return allRegistryFiles;
304 private void analyzeRegistryFiles(
long ingestJobId) {
305 List<AbstractFile> allRegistryFiles = findRegistryFiles();
308 FileWriter logFile = null;
310 logFile =
new FileWriter(RAImageIngestModule.getRAOutputPath(currentCase,
"reg", ingestJobId) + File.separator +
"regripper-info.txt");
311 }
catch (IOException ex) {
312 logger.log(Level.SEVERE, null, ex);
315 for (AbstractFile regFile : allRegistryFiles) {
316 if (context.dataSourceIngestIsCancelled()) {
320 String regFileName = regFile.getName();
321 long regFileId = regFile.getId();
322 String regFileNameLocal = RAImageIngestModule.getRATempPath(currentCase,
"reg", ingestJobId) + File.separator + regFileName;
323 String outputPathBase = RAImageIngestModule.getRAOutputPath(currentCase,
"reg", ingestJobId) + File.separator + regFileName +
"-regripper-" + Long.toString(regFileId);
324 File regFileNameLocalFile =
new File(regFileNameLocal);
326 ContentUtils.writeToFile(regFile, regFileNameLocalFile, context::dataSourceIngestIsCancelled);
327 }
catch (ReadContentInputStreamException ex) {
328 logger.log(Level.WARNING, String.format(
"Error reading registry file '%s' (id=%d).",
329 regFile.getName(), regFileId), ex);
330 this.addErrorMessage(
331 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
332 this.getDisplayName(), regFileName));
334 }
catch (IOException ex) {
335 logger.log(Level.SEVERE, String.format(
"Error writing temp registry file '%s' for registry file '%s' (id=%d).",
336 regFileNameLocal, regFile.getName(), regFileId), ex);
337 this.addErrorMessage(
338 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
339 this.getDisplayName(), regFileName));
343 if (context.dataSourceIngestIsCancelled()) {
348 if (logFile != null) {
349 logFile.write(Long.toString(regFileId) +
"\t" + regFile.getUniquePath() +
"\n");
351 }
catch (TskCoreException | IOException ex) {
352 logger.log(Level.SEVERE, null, ex);
355 logger.log(Level.INFO,
"{0}- Now getting registry information from {1}",
new Object[]{getDisplayName(), regFileNameLocal});
356 RegOutputFiles regOutputFiles = ripRegistryFile(regFileNameLocal, outputPathBase);
357 if (context.dataSourceIngestIsCancelled()) {
362 if (regOutputFiles.autopsyPlugins.isEmpty() ==
false && parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) ==
false) {
363 this.addErrorMessage(
364 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
365 this.getDisplayName(), regFileName));
368 if (context.dataSourceIngestIsCancelled()) {
373 if (!regOutputFiles.fullPlugins.isEmpty()) {
375 if (regFileNameLocal.toLowerCase().contains(
"sam") && parseSamPluginOutput(regOutputFiles.fullPlugins, regFile, ingestJobId) ==
false) {
376 this.addErrorMessage(
377 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
378 this.getDisplayName(), regFileName));
379 }
else if (regFileNameLocal.toLowerCase().contains(
"ntuser") || regFileNameLocal.toLowerCase().contains(
"usrclass")) {
381 List<ShellBag> shellbags = ShellBagParser.parseShellbagOutput(regOutputFiles.fullPlugins);
382 createShellBagArtifacts(regFile, shellbags);
383 createRecentlyUsedArtifacts(regOutputFiles.fullPlugins, regFile);
384 }
catch (IOException | TskCoreException ex) {
385 logger.log(Level.WARNING, String.format(
"Unable to get shell bags from file %s", regOutputFiles.fullPlugins), ex);
387 }
else if (regFileNameLocal.toLowerCase().contains(
"system") && parseSystemPluginOutput(regOutputFiles.fullPlugins, regFile) ==
false) {
388 this.addErrorMessage(
389 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
390 this.getDisplayName(), regFileName));
393 if (context.dataSourceIngestIsCancelled()) {
398 Report report = currentCase.addReport(regOutputFiles.fullPlugins,
399 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.parentModuleName.noSpace"),
400 "RegRipper " + regFile.getUniquePath(), regFile);
403 KeywordSearchService searchService = Lookup.getDefault().lookup(KeywordSearchService.class);
404 if (null == searchService) {
405 logger.log(Level.WARNING,
"Keyword search service not found. Report will not be indexed");
407 searchService.index(report);
410 }
catch (TskCoreException e) {
411 this.addErrorMessage(
"Error adding regripper output as Autopsy report: " + e.getLocalizedMessage());
415 regFileNameLocalFile.delete();
419 if (logFile != null) {
422 }
catch (IOException ex) {
423 logger.log(Level.SEVERE, null, ex);
434 private RegOutputFiles ripRegistryFile(String regFilePath, String outFilePathBase) {
435 String autopsyType =
"";
438 RegOutputFiles regOutputFiles =
new RegOutputFiles();
440 if (regFilePath.toLowerCase().contains(
"system")) {
441 autopsyType =
"autopsysystem";
443 }
else if (regFilePath.toLowerCase().contains(
"software")) {
444 autopsyType =
"autopsysoftware";
445 fullType =
"software";
446 }
else if (regFilePath.toLowerCase().contains(
"ntuser")) {
447 autopsyType =
"autopsyntuser";
449 }
else if (regFilePath.toLowerCase().contains(
"sam")) {
452 }
else if (regFilePath.toLowerCase().contains(
"security")) {
453 fullType =
"security";
454 }
else if (regFilePath.toLowerCase().contains(
"usrclass")) {
455 fullType =
"usrclass";
457 return regOutputFiles;
461 if (!autopsyType.isEmpty()) {
462 regOutputFiles.autopsyPlugins = outFilePathBase +
"-autopsy.txt";
463 String errFilePath = outFilePathBase +
"-autopsy.err.txt";
464 logger.log(Level.INFO,
"Writing RegRipper results to: {0}", regOutputFiles.autopsyPlugins);
465 executeRegRipper(rrCmd, rrHome, regFilePath, autopsyType, regOutputFiles.autopsyPlugins, errFilePath);
467 if (context.dataSourceIngestIsCancelled()) {
468 return regOutputFiles;
472 if (!fullType.isEmpty()) {
473 regOutputFiles.fullPlugins = outFilePathBase +
"-full.txt";
474 String errFilePath = outFilePathBase +
"-full.err.txt";
475 logger.log(Level.INFO,
"Writing Full RegRipper results to: {0}", regOutputFiles.fullPlugins);
476 executeRegRipper(rrFullCmd, rrFullHome, regFilePath, fullType, regOutputFiles.fullPlugins, errFilePath);
478 scanErrorLogs(errFilePath);
479 }
catch (IOException ex) {
480 logger.log(Level.SEVERE, String.format(
"Unable to run RegRipper on %s", regFilePath), ex);
481 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getDisplayName(), regFilePath));
484 return regOutputFiles;
487 private void scanErrorLogs(String errFilePath)
throws IOException {
488 File regfile =
new File(errFilePath);
489 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
490 String line = reader.readLine();
491 while (line != null) {
493 if (line.toLowerCase().contains(
"error") || line.toLowerCase().contains(
"@inc")) {
494 logger.log(Level.WARNING,
"Regripper file {0} contains errors from run", errFilePath);
497 line = reader.readLine();
502 private void executeRegRipper(List<String> regRipperPath, Path regRipperHomeDir, String hiveFilePath, String hiveFileType, String outputFile, String errFile) {
504 List<String> commandLine =
new ArrayList<>();
505 for (String cmd : regRipperPath) {
506 commandLine.add(cmd);
508 commandLine.add(
"-r");
509 commandLine.add(hiveFilePath);
510 commandLine.add(
"-f");
511 commandLine.add(hiveFileType);
513 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
514 processBuilder.directory(regRipperHomeDir.toFile());
515 processBuilder.redirectOutput(
new File(outputFile));
516 processBuilder.redirectError(
new File(errFile));
517 ExecUtil.execute(processBuilder,
new DataSourceIngestModuleProcessTerminator(context,
true));
518 }
catch (IOException ex) {
519 logger.log(Level.SEVERE, String.format(
"Error running RegRipper on %s", hiveFilePath), ex);
520 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getDisplayName(), hiveFilePath));
533 private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) {
534 FileInputStream fstream = null;
535 List<BlackboardArtifact> newArtifacts =
new ArrayList<>();
538 File regfile =
new File(regFilePath);
539 fstream =
new FileInputStream(regfile);
540 String regString =
new Scanner(fstream,
"UTF-8").useDelimiter(
"\\Z").next();
541 String startdoc =
"<?xml version=\"1.0\"?><document>";
542 String result = regString.replaceAll(
"----------------------------------------",
"");
543 result = result.replaceAll(
"\\n",
"");
544 result = result.replaceAll(
"\\r",
"");
545 result = result.replaceAll(
"'",
"'");
546 result = result.replaceAll(
"&",
"&");
547 result = result.replace(
'\0',
' ');
548 String enddoc =
"</document>";
549 String stringdoc = startdoc + result + enddoc;
550 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
551 Document doc = builder.parse(
new InputSource(
new StringReader(stringdoc)));
554 Element oroot = doc.getDocumentElement();
555 NodeList children = oroot.getChildNodes();
556 int len = children.getLength();
557 for (
int i = 0; i < len; i++) {
559 if (context.dataSourceIngestIsCancelled()) {
563 Element tempnode = (Element) children.item(i);
565 String dataType = tempnode.getNodeName();
566 NodeList timenodes = tempnode.getElementsByTagName(
"mtime");
568 if (timenodes.getLength() > 0) {
569 Element timenode = (Element) timenodes.item(0);
570 String etime = timenode.getTextContent().trim();
572 if (etime != null && !etime.isEmpty()) {
574 mtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy", US).parse(etime).getTime();
575 String Tempdate = mtime.toString();
576 mtime = Long.valueOf(Tempdate) / MS_IN_SEC;
577 }
catch (ParseException ex) {
578 logger.log(Level.WARNING,
"Failed to parse epoch time when parsing the registry.", ex);
583 NodeList artroots = tempnode.getElementsByTagName(
"artifacts");
584 if (artroots.getLength() == 0) {
589 Element artroot = (Element) artroots.item(0);
590 NodeList myartlist = artroot.getChildNodes();
591 String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName();
597 String systemRoot =
"";
598 String productId =
"";
599 String regOwner =
"";
601 Long installtime = null;
602 for (
int j = 0; j < myartlist.getLength(); j++) {
603 Node artchild = myartlist.item(j);
605 if (artchild.hasAttributes()) {
606 Element artnode = (Element) artchild;
608 String value = artnode.getTextContent();
610 value = value.trim();
612 String name = artnode.getAttribute(
"name");
622 version = version +
" " + value;
630 case "RegisteredOwner":
633 case "RegisteredOrganization":
637 if (value != null && !value.isEmpty()) {
639 installtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyyZ", US).parse(value +
"+0000").getTime();
640 String Tempdate = installtime.toString();
641 installtime = Long.valueOf(Tempdate) / MS_IN_SEC;
642 }
catch (ParseException e) {
643 logger.log(Level.WARNING,
"RegRipper::Conversion on DateTime -> ", e);
653 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
654 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, version));
655 if (installtime != null) {
656 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, installtime));
658 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, parentModuleName, systemRoot));
659 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID, parentModuleName, productId));
660 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER, parentModuleName, regOwner));
661 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION, parentModuleName, regOrg));
664 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
665 if (results.isEmpty()) {
666 newArtifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_OS_INFO, regFile, bbattributes));
668 results.get(0).addAttributes(bbattributes);
671 }
catch (TskCoreException ex) {
672 logger.log(Level.SEVERE, String.format(
"Error adding installed program artifact to blackboard for file %d.", regFile.getId()), ex);
677 String procArch =
"";
679 for (
int j = 0; j < myartlist.getLength(); j++) {
680 Node artchild = myartlist.item(j);
682 if (artchild.hasAttributes()) {
683 Element artnode = (Element) artchild;
685 String value = artnode.getTextContent().trim();
686 String name = artnode.getAttribute(
"name");
691 case "PROCESSOR_ARCHITECTURE":
694 case "PROCESSOR_IDENTIFIER":
705 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
706 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VERSION, parentModuleName, os));
707 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE, parentModuleName, procArch));
708 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR, parentModuleName, tempDir));
711 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
712 if (results.isEmpty()) {
713 newArtifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_OS_INFO, regFile, bbattributes));
715 results.get(0).addAttributes(bbattributes);
717 }
catch (TskCoreException ex) {
718 logger.log(Level.SEVERE, String.format(
"Error adding installed os_info to blackboard for file %d.", regFile.getId()), ex);
722 for (
int j = 0; j < myartlist.getLength(); j++) {
723 Node artchild = myartlist.item(j);
725 if (artchild.hasAttributes()) {
726 Element artnode = (Element) artchild;
728 String value = artnode.getTextContent().trim();
729 String name = artnode.getAttribute(
"name");
731 if (name.equals(
"ComputerName")) {
733 }
else if (name.equals(
"Domain")) {
739 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
740 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, compName));
741 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN, parentModuleName, domainName));
744 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, regFile.getId());
745 if (results.isEmpty()) {
746 newArtifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_OS_INFO, regFile, bbattributes));
748 results.get(0).addAttributes(bbattributes);
750 for (Map.Entry<String, String> userMap : getUserNameMap().entrySet()) {
753 sid = userMap.getKey();
754 String userName = userMap.getValue();
756 createOrUpdateOsAccount(regFile, sid, userName, null, null, OsAccountRealm.RealmScope.LOCAL);
757 }
catch (TskCoreException | TskDataException | NotUserSIDException ex) {
758 logger.log(Level.WARNING, String.format(
"Failed to update Domain for existing OsAccount: %s, sid: %s", regFile.getId(), sid), ex);
761 }
catch (TskCoreException ex) {
762 logger.log(Level.SEVERE, String.format(
"Error adding os_info artifact to blackboard for file %d.", regFile.getId()), ex);
766 for (
int j = 0; j < myartlist.getLength(); j++) {
767 Node artchild = myartlist.item(j);
769 if (artchild.hasAttributes()) {
770 Element artnode = (Element) artchild;
772 String value = artnode.getTextContent().trim();
773 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
786 Long usbMtime = Long.valueOf(
"0");
787 if (!artnode.getAttribute(
"mtime").isEmpty()) {
788 usbMtime = Long.parseLong(artnode.getAttribute(
"mtime"));
790 usbMtime = Long.valueOf(usbMtime.toString());
792 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, usbMtime));
794 String dev = artnode.getAttribute(
"dev");
797 if (dev.toLowerCase().contains(
"vid")) {
798 USBInfo info = USB_MAPPER.parseAndLookup(dev);
799 if (info.getVendor() != null) {
800 make = info.getVendor();
802 if (info.getProduct() != null) {
803 model = info.getProduct();
806 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE, parentModuleName, make));
807 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL, parentModuleName, model));
808 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, value));
809 newArtifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_DEVICE_ATTACHED, regFile, bbattributes));
810 }
catch (TskCoreException ex) {
811 logger.log(Level.SEVERE, String.format(
"Error adding device_attached artifact to blackboard for file %d.", regFile.getId()), ex);
815 Long itemMtime = null;
817 String mTimeAttr = artnode.getAttribute(
"mtime");
818 if (mTimeAttr != null && !mTimeAttr.isEmpty()) {
819 itemMtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy", US).parse(mTimeAttr).getTime();
820 itemMtime /= MS_IN_SEC;
822 }
catch (ParseException ex) {
823 logger.log(Level.SEVERE,
"Failed to parse epoch time for installed program artifact.", ex);
827 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value));
828 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime));
829 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_INSTALLED_PROG), bbattributes);
830 newArtifacts.add(bbart);
831 }
catch (TskCoreException ex) {
832 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.", ex);
836 String officeName = artnode.getAttribute(
"name");
841 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, parentModuleName, mtime));
843 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, officeName));
844 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, parentModuleName, value));
845 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, artnode.getNodeName()));
846 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_RECENT_OBJECT), bbattributes);
848 newArtifacts.add(bbart);
849 }
catch (TskCoreException ex) {
850 logger.log(Level.SEVERE,
"Error adding recent object artifact to blackboard.", ex);
854 case "ProcessorArchitecture":
870 String homeDir = value;
871 String sid = artnode.getAttribute(
"sid");
872 String username = artnode.getAttribute(
"username");
873 String domName = domainName;
877 OsAccountRealm.RealmScope scope = OsAccountRealm.RealmScope.DOMAIN;
878 if (isDomainIdInSAMList(sid)) {
880 scope = OsAccountRealm.RealmScope.LOCAL;
884 createOrUpdateOsAccount(regFile, sid, username, homeDir, domName, scope);
885 }
catch (TskCoreException | TskDataException | NotUserSIDException ex) {
886 logger.log(Level.SEVERE, String.format(
"Failed to create OsAccount for file: %s, sid: %s", regFile.getId(), sid), ex);
890 case "NtuserNetwork":
892 String localPath = artnode.getAttribute(
"localPath");
893 String remoteName = value;
895 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH,
896 parentModuleName, localPath));
897 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH,
898 parentModuleName, remoteName));
899 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_REMOTE_DRIVE), bbattributes);
900 newArtifacts.add(bbart);
901 }
catch (TskCoreException ex) {
902 logger.log(Level.SEVERE,
"Error adding network artifact to blackboard.", ex);
906 String adapter = artnode.getAttribute(
"adapter");
908 Long lastWriteTime = Long.parseLong(artnode.getAttribute(
"writeTime"));
909 lastWriteTime = Long.valueOf(lastWriteTime.toString());
910 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SSID, parentModuleName, value));
911 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, lastWriteTime));
912 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, adapter));
913 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_WIFI_NETWORK), bbattributes);
914 newArtifacts.add(bbart);
915 }
catch (TskCoreException ex) {
916 logger.log(Level.SEVERE,
"Error adding SSID artifact to blackboard.", ex);
926 logger.log(Level.SEVERE,
"Unrecognized node name: {0}", dataType);
935 }
catch (FileNotFoundException ex) {
936 logger.log(Level.WARNING, String.format(
"Error finding the registry file: %s", regFilePath), ex);
937 }
catch (SAXException ex) {
938 logger.log(Level.WARNING, String.format(
"Error parsing the registry XML: %s", regFilePath), ex);
939 }
catch (IOException ex) {
940 logger.log(Level.WARNING, String.format(
"Error building the document parser: %s", regFilePath), ex);
941 }
catch (ParserConfigurationException ex) {
942 logger.log(Level.WARNING, String.format(
"Error configuring the registry parser: %s", regFilePath), ex);
945 if (fstream != null) {
948 }
catch (IOException ex) {
951 if (!context.dataSourceIngestIsCancelled()) {
952 postArtifacts(newArtifacts);
958 private boolean parseSystemPluginOutput(String regfilePath, AbstractFile regAbstractFile) {
959 File regfile =
new File(regfilePath);
960 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
961 String line = reader.readLine();
962 while (line != null) {
965 if (line.toLowerCase().matches(
"^bam v.*")) {
966 parseBamKey(regAbstractFile, reader, Bundle.Registry_System_Bam());
967 }
else if (line.toLowerCase().matches(
"^bthport v..*")) {
968 parseBlueToothDevices(regAbstractFile, reader);
970 line = reader.readLine();
973 }
catch (FileNotFoundException ex) {
974 logger.log(Level.WARNING,
"Error finding the registry file.", ex);
975 }
catch (IOException ex) {
976 logger.log(Level.WARNING,
"Error reading the system hive: {0}", ex);
995 private void parseBlueToothDevices(AbstractFile regFile, BufferedReader reader)
throws FileNotFoundException, IOException {
996 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
997 String line = reader.readLine();
998 while ((line != null) && (!line.contains(SECTION_DIVIDER))) {
999 line = reader.readLine();
1005 if ((line != null) && (line.toLowerCase().contains(
"device unique id"))) {
1009 while (line != null && !line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.toLowerCase().contains(
"radio support not found")) {
1010 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1011 addBlueToothAttribute(line, attributes, TSK_DEVICE_ID);
1012 line = reader.readLine();
1014 if ((line != null) && (line.toLowerCase().contains(
"name"))) {
1015 addBlueToothAttribute(line, attributes, TSK_NAME);
1016 line = reader.readLine();
1018 addBlueToothAttribute(line, attributes, TSK_DATETIME);
1019 line = reader.readLine();
1020 addBlueToothAttribute(line, attributes, TSK_DATETIME_ACCESSED);
1023 bbartifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_BLUETOOTH_PAIRING, regFile, attributes));
1024 }
catch (TskCoreException ex) {
1025 logger.log(Level.SEVERE, String.format(
"Failed to create bluetooth_pairing artifact for file %d", regFile.getId()), ex);
1029 line = reader.readLine();
1038 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1039 postArtifacts(bbartifacts);
1043 private void addBlueToothAttribute(String line, Collection<BlackboardAttribute> attributes, ATTRIBUTE_TYPE attributeType) {
1048 String tokens[] = line.split(
": ");
1049 if (tokens.length > 1 && !tokens[1].isEmpty()) {
1050 String tokenString = tokens[1];
1051 if (attributeType.getDisplayName().toLowerCase().contains(
"date")) {
1052 String dateString = tokenString.toLowerCase().replace(
" z",
"");
1054 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy", US);
1055 Long dateLong = Long.valueOf(0);
1057 Date newDate = dateFormat.parse(dateString);
1058 dateLong = newDate.getTime() / 1000;
1059 }
catch (ParseException ex) {
1062 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for Bluetooth Last Seen attribute.", dateString), ex);
1064 attributes.add(
new BlackboardAttribute(attributeType, getDisplayName(), dateLong));
1066 attributes.add(
new BlackboardAttribute(attributeType, getDisplayName(), tokenString));
1081 private boolean parseSamPluginOutput(String regFilePath, AbstractFile regAbstractFile,
long ingestJobId) {
1083 File regfile =
new File(regFilePath);
1084 List<BlackboardArtifact> newArtifacts =
new ArrayList<>();
1085 try (BufferedReader bufferedReader =
new BufferedReader(
new InputStreamReader(
new FileInputStream(regfile), StandardCharsets.UTF_8))) {
1087 String userInfoSection =
"User Information";
1088 String previousLine = null;
1089 String line = bufferedReader.readLine();
1090 Set<Map<String, String>> userSet =
new HashSet<>();
1091 Map<String, List<String>> groupMap = null;
1092 while (line != null) {
1093 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(userInfoSection)) {
1094 readUsers(bufferedReader, userSet);
1097 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(
"Group Membership Information")) {
1098 groupMap = readGroups(bufferedReader);
1101 previousLine = line;
1102 line = bufferedReader.readLine();
1104 Map<String, Map<String, String>> userInfoMap =
new HashMap<>();
1106 for (Map<String, String> userInfo : userSet) {
1107 String sid = userInfo.get(SID_KEY);
1108 userInfoMap.put(sid, userInfo);
1109 addSIDToSAMList(sid);
1113 OsAccountManager accountMgr = tskCase.getOsAccountManager();
1114 HostManager hostMrg = tskCase.getHostManager();
1115 Host host = hostMrg.getHostByDataSource((DataSource) dataSource);
1117 List<OsAccount> existingAccounts = accountMgr.getOsAccounts(host);
1118 for (OsAccount osAccount : existingAccounts) {
1119 Optional<String> optional = osAccount.getAddr();
1120 if (!optional.isPresent()) {
1124 String sid = optional.get();
1125 Map<String, String> userInfo = userInfoMap.remove(sid);
1126 if (userInfo != null) {
1127 addAccountInstance(accountMgr, osAccount, (DataSource) dataSource);
1128 updateOsAccount(osAccount, userInfo, groupMap.get(sid), regAbstractFile);
1133 for (Map<String, String> userInfo : userInfoMap.values()) {
1134 OsAccount osAccount = accountMgr.newWindowsOsAccount(userInfo.get(SID_KEY), null, null, host, OsAccountRealm.RealmScope.LOCAL);
1135 accountMgr.newOsAccountInstance(osAccount, (DataSource) dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
1136 updateOsAccount(osAccount, userInfo, groupMap.get(userInfo.get(SID_KEY)), regAbstractFile);
1139 }
catch (FileNotFoundException ex) {
1140 logger.log(Level.WARNING,
"Error finding the registry file.", ex);
1141 }
catch (IOException ex) {
1142 logger.log(Level.WARNING,
"Error building the document parser: {0}", ex);
1143 }
catch (TskDataException | TskCoreException ex) {
1144 logger.log(Level.WARNING,
"Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex);
1145 }
catch (OsAccountManager.NotUserSIDException ex) {
1146 logger.log(Level.WARNING,
"Error creating OS Account, input SID is not a user SID.", ex);
1148 if (!context.dataSourceIngestIsCancelled()) {
1149 postArtifacts(newArtifacts);
1166 private void readUsers(BufferedReader bufferedReader, Set<Map<String, String>> users) throws IOException {
1167 String line = bufferedReader.readLine();
1169 String userName =
"";
1170 String user_rid =
"";
1171 while (line != null && !line.contains(SECTION_DIVIDER)) {
1173 if (line.contains(USERNAME_KEY)) {
1174 String regx = USERNAME_KEY +
"\\s*?:";
1175 String userNameAndIdString = line.replaceAll(regx,
"");
1176 userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf(
'[')).trim();
1177 user_rid = userNameAndIdString.substring(userNameAndIdString.lastIndexOf(
'['), userNameAndIdString.lastIndexOf(
']'));
1178 }
else if (line.contains(SID_KEY) && !userName.isEmpty()) {
1179 Map.Entry<String, String> entry = getSAMKeyValue(line);
1181 HashMap<String, String> userInfo =
new HashMap<>();
1182 userInfo.put(USERNAME_KEY, userName);
1183 userInfo.put(RID_KEY, user_rid);
1184 userInfo.put(entry.getKey(), entry.getValue());
1187 line = bufferedReader.readLine();
1188 while (line != null && !line.isEmpty()) {
1189 entry = getSAMKeyValue(line);
1190 if (entry != null) {
1191 userInfo.put(entry.getKey(), entry.getValue());
1193 line = bufferedReader.readLine();
1195 users.add(userInfo);
1199 line = bufferedReader.readLine();
1212 private void createRecentlyUsedArtifacts(String regFileName, AbstractFile regFile)
throws FileNotFoundException, IOException {
1213 File regfile =
new File(regFileName);
1214 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
1215 String line = reader.readLine();
1216 while (line != null) {
1219 if (line.matches(
"^adoberdr v.*")) {
1220 parseAdobeMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Adobe());
1221 }
else if (line.matches(
"^mpmru v.*")) {
1222 parseMediaPlayerMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Mediaplayer());
1223 }
else if (line.matches(
"^trustrecords v.*")) {
1224 parseOfficeTrustRecords(regFile, reader, Bundle.Recently_Used_Artifacts_Office_Trustrecords());
1225 }
else if (line.matches(
"^ArcHistory:")) {
1226 parse7ZipMRU(regFile, reader, Bundle.Recently_Used_Artifacts_ArcHistory());
1227 }
else if (line.matches(
"^applets v.*")) {
1228 parseGenericMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Applets());
1229 }
else if (line.matches(
"^mmc v.*")) {
1230 parseGenericMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Mmc());
1231 }
else if (line.matches(
"^winrar v.*")) {
1232 parseWinRARMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Winrar());
1233 }
else if (line.matches(
"^officedocs2010 v.*")) {
1234 parseOfficeDocs2010MRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Officedocs());
1236 line = reader.readLine();
1252 private void parseBamKey(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1253 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1254 String line = reader.readLine();
1256 while (!line.contains(SECTION_DIVIDER)) {
1257 line = reader.readLine();
1260 line = reader.readLine();
1262 while (!line.contains(SECTION_DIVIDER)) {
1265 String tokens[] = line.split(
"\\|");
1266 Long progRunDateTime = Long.valueOf(tokens[0]);
1269 String fileNameSid[] = tokens[4].split(
"\\s+\\(S-");
1270 String userSid =
"S-" + fileNameSid[1].substring(0, fileNameSid[1].length() - 1);
1271 String userName = getUserNameMap().get(userSid);
1272 if (userName == null) {
1275 String fileName = fileNameSid[0];
1276 if (fileName.startsWith(
"\\Device\\HarddiskVolume")) {
1278 int fileNameStart = fileName.indexOf(
'\\', 16);
1279 fileName = fileName.substring(fileNameStart, fileName.length());
1282 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1283 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, getDisplayName(), fileName));
1284 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, getDisplayName(), userName));
1285 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, getDisplayName(), progRunDateTime));
1286 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, getDisplayName(), comment));
1289 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_PROG_RUN, regFile, attributes);
1290 bbartifacts.add(bba);
1291 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1293 bbartifacts.add(bba);
1295 }
catch (TskCoreException ex) {
1296 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_PROG_RUN artifact for file %d", regFile.getId()), ex);
1298 line = reader.readLine();
1300 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1301 postArtifacts(bbartifacts);
1316 private void parseAdobeMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1317 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1318 String line = reader.readLine();
1319 SimpleDateFormat adobePluginDateFormat =
new SimpleDateFormat(
"yyyyMMddHHmmssZ", US);
1320 Long adobeUsedTime = Long.valueOf(0);
1321 while (!line.contains(SECTION_DIVIDER)) {
1322 line = reader.readLine();
1324 if (line.matches(
"^Key name,file name,sDate,uFileSize,uPageCount")) {
1325 line = reader.readLine();
1328 while (!line.contains(SECTION_DIVIDER)) {
1331 String tokens[] = line.split(
",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
1332 String fileName = tokens[1].substring(0, tokens[1].length() - 1);
1333 fileName = fileName.replace(
"\"",
"");
1334 if (fileName.charAt(0) ==
'/') {
1335 fileName = fileName.substring(1, fileName.length() - 1);
1336 fileName = fileName.replaceFirst(
"/",
":/");
1339 if (tokens.length > 2) {
1342 String fileUsedTime = tokens[2].replaceAll(
"'",
"");
1343 Date usedDate = adobePluginDateFormat.parse(fileUsedTime);
1344 adobeUsedTime = usedDate.getTime() / 1000;
1345 }
catch (ParseException ex) {
1348 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for adobe file artifact.", tokens[2]), ex);
1351 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1352 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1353 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, getDisplayName(), adobeUsedTime));
1354 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1356 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1358 bbartifacts.add(bba);
1359 fileName = fileName.replace(
"\0",
"");
1360 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1362 bbartifacts.add(bba);
1365 }
catch (TskCoreException ex) {
1366 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1368 line = reader.readLine();
1373 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1374 postArtifacts(bbartifacts);
1390 private void parseMediaPlayerMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1391 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1392 String line = reader.readLine();
1393 while (!line.contains(SECTION_DIVIDER)) {
1394 line = reader.readLine();
1396 if (line.contains(
"LastWrite")) {
1397 line = reader.readLine();
1400 while (!line.contains(SECTION_DIVIDER) && !line.contains(
"RecentFileList has no values.")) {
1402 String tokens[] = line.split(
"> ");
1403 String fileName = tokens[1];
1404 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1405 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1406 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1408 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1410 bbartifacts.add(bba);
1411 bba = createAssociatedArtifact(fileName, bba);
1413 bbartifacts.add(bba);
1414 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1416 bbartifacts.add(bba);
1420 }
catch (TskCoreException ex) {
1421 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1423 line = reader.readLine();
1428 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1429 postArtifacts(bbartifacts);
1445 private void parseGenericMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1446 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1447 String line = reader.readLine();
1448 while (!line.contains(SECTION_DIVIDER)) {
1449 line = reader.readLine();
1451 if (line.contains(
"LastWrite")) {
1452 line = reader.readLine();
1455 while (!line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains(
"Applets")
1456 && !line.contains((
"Recent File List"))) {
1458 String tokens[] = line.split(
"> ");
1459 if (tokens.length > 1) {
1460 String fileName = tokens[1];
1461 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1462 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1463 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1465 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1467 bbartifacts.add(bba);
1468 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1470 bbartifacts.add(bba);
1473 }
catch (TskCoreException ex) {
1474 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1477 line = reader.readLine();
1482 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1483 postArtifacts(bbartifacts);
1499 private void parseWinRARMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1500 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1501 String line = reader.readLine();
1502 while (!line.contains(SECTION_DIVIDER)) {
1503 line = reader.readLine();
1505 if (line.contains(
"LastWrite")) {
1506 line = reader.readLine();
1509 if (!line.isEmpty()) {
1510 while (!line.contains(SECTION_DIVIDER)) {
1512 String tokens[] = line.split(
"> ");
1513 String fileName = tokens[1];
1514 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1515 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1516 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1518 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1519 bbartifacts.add(bba);
1520 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1522 bbartifacts.add(bba);
1524 }
catch (TskCoreException ex) {
1525 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1527 line = reader.readLine();
1533 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1534 postArtifacts(bbartifacts);
1550 private void parse7ZipMRU(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1551 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1552 String line = reader.readLine();
1554 if (!line.contains(
"PathHistory:")) {
1555 while (!line.contains(
"PathHistory:") && !line.isEmpty()) {
1558 String fileName = line;
1559 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1560 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1561 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1563 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1564 bbartifacts.add(bba);
1565 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1567 bbartifacts.add(bba);
1570 }
catch (TskCoreException ex) {
1571 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1573 line = reader.readLine();
1577 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1578 postArtifacts(bbartifacts);
1594 private void parseOfficeDocs2010MRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1595 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1596 String line = reader.readLine();
1600 while (!line.contains(SECTION_DIVIDER)) {
1601 line = reader.readLine();
1603 line = reader.readLine();
1604 while (!line.contains(SECTION_DIVIDER)) {
1607 String tokens[] = line.split(
"\\|");
1608 Long docDate = Long.valueOf(tokens[0]);
1609 String fileNameTokens[] = tokens[4].split(
" - ");
1610 String fileName = fileNameTokens[1];
1611 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1612 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1613 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, getDisplayName(), docDate));
1614 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1616 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1617 bbartifacts.add(bba);
1618 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1620 bbartifacts.add(bba);
1622 }
catch (TskCoreException ex) {
1623 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1625 line = reader.readLine();
1628 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1629 postArtifacts(bbartifacts);
1645 private void parseOfficeTrustRecords(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1646 String userProfile = regFile.getParentPath();
1647 userProfile = userProfile.substring(0, userProfile.length() - 1);
1648 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1649 SimpleDateFormat pluginDateFormat =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy", US);
1650 Long usedTime = Long.valueOf(0);
1651 String line = reader.readLine();
1652 while (!line.contains(SECTION_DIVIDER)) {
1653 line = reader.readLine();
1655 usedTime = Long.valueOf(0);
1656 if (!line.contains(
"**") && !line.contains(
"----------") && !line.contains(
"LastWrite")
1657 && !line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains(
"TrustRecords")
1658 && !line.contains(
"VBAWarnings =")) {
1662 String fileName = null;
1663 String tokens[] = line.split(
" : ");
1664 fileName = tokens[1];
1665 fileName = fileName.replace(
"%USERPROFILE%", userProfile);
1668 String fileUsedTime = tokens[0].replaceAll(
" Z",
"");
1669 Date usedDate = pluginDateFormat.parse(fileUsedTime);
1670 usedTime = usedDate.getTime() / 1000;
1671 }
catch (ParseException ex) {
1674 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for TrustRecords artifact.", tokens[0]), ex);
1676 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1677 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1678 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, getDisplayName(), usedTime));
1679 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1681 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1682 bbartifacts.add(bba);
1683 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1685 bbartifacts.add(bba);
1687 }
catch (TskCoreException ex) {
1688 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1693 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1694 postArtifacts(bbartifacts);
1708 private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) {
1709 String fileName = FilenameUtils.getName(filePathName);
1710 String filePath = FilenameUtils.getPath(filePathName);
1711 List<AbstractFile> sourceFiles;
1713 sourceFiles = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, fileName, filePath);
1714 if (!sourceFiles.isEmpty()) {
1715 return createAssociatedArtifact(sourceFiles.get(0), bba);
1717 }
catch (TskCoreException ex) {
1720 logger.log(Level.WARNING, String.format(
"Error finding actual file %s. file may not exist", filePathName));
1736 private Map<String, String> makeUserNameMap(Content dataSource)
throws TskCoreException {
1737 Map<String, String> map =
new HashMap<>();
1739 for (OsAccount account : tskCase.getOsAccountManager().getOsAccounts(((DataSource) dataSource).getHost())) {
1740 Optional<String> userName = account.getLoginName();
1741 String address = account.getAddr().orElse(
"");
1742 if (!address.isEmpty()) {
1743 map.put(address, userName.isPresent() ? userName.get() :
"");
1769 private String stripRelativeIdentifierFromSID(String osAccountSID) {
1770 if (osAccountSID.split(
"-").length > 4) {
1771 int index = osAccountSID.lastIndexOf(
'-');
1772 return index > 1 ? osAccountSID.substring(0, index) :
"";
1777 private final List<String> machineSIDs =
new ArrayList<>();
1784 private Map<String, String> getUserNameMap() {
1785 if (userNameMap == null) {
1789 userNameMap = makeUserNameMap(dataSource);
1790 }
catch (TskCoreException ex) {
1791 logger.log(Level.WARNING,
"Unable to create OS Account user name map", ex);
1794 userNameMap =
new HashMap<>();
1811 private BlackboardAttribute getAttributeForArtifact(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type) throws TskCoreException {
1812 return artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(type.getTypeID())));
1823 void createShellBagArtifacts(AbstractFile regFile, List<ShellBag> shellbags)
throws TskCoreException {
1824 List<BlackboardArtifact> artifacts =
new ArrayList<>();
1826 for (ShellBag bag : shellbags) {
1827 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1828 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), bag.getResource()));
1829 attributes.add(
new BlackboardAttribute(getKeyAttribute(), getDisplayName(), bag.getKey()));
1832 time = bag.getLastWrite();
1834 attributes.add(
new BlackboardAttribute(getLastWriteAttribute(), getDisplayName(), time));
1837 time = bag.getModified();
1839 attributes.add(
new BlackboardAttribute(TSK_DATETIME_MODIFIED, getDisplayName(), time));
1842 time = bag.getCreated();
1844 attributes.add(
new BlackboardAttribute(TSK_DATETIME_CREATED, getDisplayName(), time));
1847 time = bag.getAccessed();
1849 attributes.add(
new BlackboardAttribute(TSK_DATETIME_ACCESSED, getDisplayName(), time));
1852 BlackboardArtifact artifact = createArtifactWithAttributes(getShellBagArtifact(), regFile, attributes);
1853 artifacts.add(artifact);
1856 if (!context.dataSourceIngestIsCancelled()) {
1857 postArtifacts(artifacts);
1870 private BlackboardArtifact.Type getShellBagArtifact() throws TskCoreException {
1871 if (shellBagArtifactType == null) {
1873 shellBagArtifactType = tskCase.getBlackboard().getOrAddArtifactType(SHELLBAG_ARTIFACT_NAME, Bundle.Shellbag_Artifact_Display_Name());
1874 }
catch (BlackboardException ex) {
1875 throw new TskCoreException(String.format(
"Failed to get shell bag artifact type", SHELLBAG_ARTIFACT_NAME), ex);
1879 return shellBagArtifactType;
1890 private BlackboardAttribute.Type getLastWriteAttribute() throws TskCoreException {
1891 if (shellBagLastWriteAttributeType == null) {
1893 shellBagLastWriteAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SHELLBAG_ATTRIBUTE_LAST_WRITE,
1894 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME,
1895 Bundle.Shellbag_Last_Write_Attribute_Display_Name());
1896 }
catch (BlackboardException ex) {
1898 throw new TskCoreException(String.format(
"Failed to get custom attribute %s", SHELLBAG_ATTRIBUTE_LAST_WRITE), ex);
1901 return shellBagLastWriteAttributeType;
1912 private BlackboardAttribute.Type getKeyAttribute() throws TskCoreException {
1913 if (shellBagKeyAttributeType == null) {
1915 shellBagKeyAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SHELLBAG_ATTRIBUTE_KEY,
1916 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
1917 Bundle.Shellbag_Key_Attribute_Display_Name());
1918 }
catch (BlackboardException ex) {
1919 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SHELLBAG_ATTRIBUTE_KEY), ex);
1922 return shellBagKeyAttributeType;
1934 Map<String, List<String>> readGroups(BufferedReader bufferedReader)
throws IOException {
1935 Map<String, List<String>> groupMap =
new HashMap<>();
1937 String line = bufferedReader.readLine();
1940 String groupName = null;
1942 while (line != null && !line.contains(SECTION_DIVIDER)) {
1944 if (line.contains(
"Group Name")) {
1945 String value = line.replaceAll(
"Group Name\\s*?:",
"").trim();
1946 groupName = (value.replaceAll(
"\\[\\d*?\\]",
"")).trim();
1947 int startIndex = value.indexOf(
" [") + 1;
1948 int endIndex = value.indexOf(
']');
1950 if (startIndex != -1 && endIndex != -1) {
1951 String countStr = value.substring(startIndex + 1, endIndex);
1952 userCount = Integer.parseInt(countStr);
1954 }
else if (line.matches(
"Users\\s*?:")) {
1955 for (
int i = 0; i < userCount; i++) {
1956 line = bufferedReader.readLine();
1958 String sid = line.trim();
1959 List<String> groupList = groupMap.get(sid);
1960 if (groupList == null) {
1961 groupList =
new ArrayList<>();
1962 groupMap.put(sid, groupList);
1964 groupList.add(groupName);
1969 line = bufferedReader.readLine();
1982 private Map.Entry<String, String> getSAMKeyValue(String line) {
1983 int index = line.indexOf(
':');
1984 Map.Entry<String, String> returnValue = null;
1986 String value = null;
1989 key = line.substring(0, index).trim();
1990 if (index + 1 < line.length()) {
1991 value = line.substring(index + 1).trim();
1996 }
else if (line.contains(
"-->")) {
1997 key = line.replace(
"-->",
"").trim();
2002 returnValue =
new AbstractMap.SimpleEntry<>(key, value);
2009 public void process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
2010 this.dataSource = dataSource;
2012 progressBar.progress(Bundle.Progress_Message_Analyze_Registry());
2013 analyzeRegistryFiles(context.getJobId());
2022 public String autopsyPlugins =
"";
2023 public String fullPlugins =
"";
2038 private void createOrUpdateOsAccount(AbstractFile file, String sid, String userName, String homeDir, String domainName, OsAccountRealm.RealmScope realmScope) throws TskCoreException, TskDataException, NotUserSIDException {
2039 OsAccountManager accountMgr = tskCase.getOsAccountManager();
2040 HostManager hostMrg = tskCase.getHostManager();
2041 Host host = hostMrg.getHostByDataSource((DataSource) dataSource);
2043 Optional<OsAccount> optional = accountMgr.getWindowsOsAccount(sid, null, null, host);
2044 OsAccount osAccount;
2045 if (!optional.isPresent()) {
2046 osAccount = accountMgr.newWindowsOsAccount(sid, userName != null && userName.isEmpty() ? null : userName, domainName, host, realmScope);
2047 accountMgr.newOsAccountInstance(osAccount, (DataSource) dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
2049 osAccount = optional.get();
2050 addAccountInstance(accountMgr, osAccount, (DataSource) dataSource);
2051 if (userName != null && !userName.isEmpty()) {
2052 OsAccountUpdateResult updateResult = accountMgr.updateCoreWindowsOsAccountAttributes(osAccount, null, userName, (domainName == null || domainName.isEmpty()) ? null : domainName, host);
2053 osAccount = updateResult.getUpdatedAccount().orElse(osAccount);
2057 if (homeDir != null && !homeDir.isEmpty()) {
2058 List<OsAccountAttribute> attributes =
new ArrayList<>();
2059 String dir = homeDir.replaceFirst(
"^(%\\w*%)",
"");
2060 dir = dir.replace(
"\\",
"/");
2061 attributes.add(createOsAccountAttribute(TSK_HOME_DIR, dir, osAccount, host, file));
2062 accountMgr.addExtendedOsAccountAttributes(osAccount, attributes);
2073 private void addEmailAccount(AbstractFile regFile, String emailAddress) {
2075 currentCase.getSleuthkitCase()
2076 .getCommunicationsManager()
2077 .createAccountFileInstance(Account.Type.EMAIL,
2078 emailAddress, getRAModuleName(), regFile);
2079 }
catch (TskCoreException ex) {
2080 logger.log(Level.SEVERE,
2081 String.format(
"Error adding email account with value "
2082 +
"%s, to the case database for file %s [objId=%d]",
2083 emailAddress, regFile.getName(), regFile.getId()), ex);
2095 private Long parseRegRipTime(String value) {
2097 return REG_RIPPER_TIME_FORMAT.parse(value).getTime() / MS_IN_SEC;
2098 }
catch (ParseException ex) {
2099 logger.log(Level.SEVERE, String.format(
"Failed to parse reg rip time: %s", value));
2115 private void updateOsAccount(OsAccount osAccount, Map<String, String> userInfo, List<String> groupList, AbstractFile regFile)
throws TskDataException, TskCoreException, NotUserSIDException {
2116 Host host = ((DataSource) dataSource).getHost();
2118 SimpleDateFormat regRipperTimeFormat =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'", US);
2119 regRipperTimeFormat.setTimeZone(getTimeZone(
"GMT"));
2121 List<OsAccountAttribute> attributes =
new ArrayList<>();
2123 Long creationTime = null;
2125 String value = userInfo.get(ACCOUNT_CREATED_KEY);
2126 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2127 creationTime = parseRegRipTime(value);
2130 value = userInfo.get(LAST_LOGIN_KEY);
2131 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2132 Long time = parseRegRipTime(value);
2134 attributes.add(createOsAccountAttribute(TSK_DATETIME_ACCESSED,
2135 parseRegRipTime(value),
2136 osAccount, host, regFile));
2140 String loginName = null;
2141 value = userInfo.get(USERNAME_KEY);
2142 if (value != null && !value.isEmpty()) {
2146 value = userInfo.get(LOGIN_COUNT_KEY);
2147 if (value != null && !value.isEmpty()) {
2148 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
2149 Integer.parseInt(value),
2150 osAccount, host, regFile));
2156 value = userInfo.get(ACCOUNT_TYPE_KEY);
2157 if (value != null && !value.isEmpty() && value.toLowerCase().contains(
"admin")) {
2158 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_IS_ADMIN,
2159 1, osAccount, host, regFile));
2162 value = userInfo.get(USER_COMMENT_KEY);
2163 if (value != null && !value.isEmpty()) {
2164 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_DESCRIPTION,
2165 value, osAccount, host, regFile));
2168 value = userInfo.get(INTERNET_NAME_KEY);
2169 if (value != null && !value.isEmpty()) {
2170 addEmailAccount(regFile, value);
2172 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_EMAIL,
2173 value, osAccount, host, regFile));
2177 String fullName = null;
2178 value = userInfo.get(FULL_NAME_KEY);
2179 if (value != null && !value.isEmpty()) {
2182 value = userInfo.get(NAME_KEY);
2183 if (value != null && !value.isEmpty()) {
2188 value = userInfo.get(PWD_RESET_KEY);
2189 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2190 Long time = parseRegRipTime(value);
2192 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_RESET,
2193 time, osAccount, host, regFile));
2197 value = userInfo.get(PASSWORD_HINT);
2198 if (value != null && !value.isEmpty()) {
2199 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_HINT,
2200 value, osAccount, host, regFile));
2203 value = userInfo.get(PWD_FAILE_KEY);
2204 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2205 Long time = parseRegRipTime(value);
2207 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_FAIL,
2208 time, osAccount, host, regFile));
2212 String settingString = getSettingsFromMap(PASSWORD_SETTINGS_FLAGS, userInfo);
2213 if (!settingString.isEmpty()) {
2214 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_SETTINGS,
2215 settingString, osAccount, host, regFile));
2218 settingString = getSettingsFromMap(ACCOUNT_SETTINGS_FLAGS, userInfo);
2219 if (!settingString.isEmpty()) {
2220 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_SETTINGS,
2221 settingString, osAccount, host, regFile));
2224 settingString = getSettingsFromMap(ACCOUNT_TYPE_FLAGS, userInfo);
2225 if (!settingString.isEmpty()) {
2226 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_FLAG,
2227 settingString, osAccount, host, regFile));
2230 if (groupList != null && groupList.isEmpty()) {
2231 String groups = groupList.stream()
2232 .map(String::valueOf)
2233 .collect(Collectors.joining(
", "));
2235 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_GROUPS,
2236 groups, osAccount, host, regFile));
2240 OsAccountManager accountMgr = tskCase.getOsAccountManager();
2241 accountMgr.addExtendedOsAccountAttributes(osAccount, attributes);
2244 accountMgr.updateCoreWindowsOsAccountAttributes(osAccount, null, loginName, null, host);
2247 accountMgr.updateStandardOsAccountAttributes(osAccount, fullName, null, null, creationTime);
2259 private String getSettingsFromMap(String[] keys, Map<String, String> map) {
2260 List<String> settingsList =
new ArrayList<>();
2261 for (String setting : keys) {
2262 if (map.containsKey(setting)) {
2263 settingsList.add(setting);
2267 if (!settingsList.isEmpty()) {
2268 return settingsList.stream()
2269 .map(String::valueOf)
2270 .collect(Collectors.joining(
", "));
2287 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.ATTRIBUTE_TYPE type, String value, OsAccount osAccount, Host host, AbstractFile file) {
2288 return osAccount.new OsAccountAttribute(
new BlackboardAttribute.Type(type), value, osAccount, host, file);
2302 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.ATTRIBUTE_TYPE type, Long value, OsAccount osAccount, Host host, AbstractFile file) {
2303 return osAccount.new OsAccountAttribute(
new BlackboardAttribute.Type(type), value, osAccount, host, file);
2317 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.ATTRIBUTE_TYPE type, Integer value, OsAccount osAccount, Host host, AbstractFile file) {
2318 return osAccount.new OsAccountAttribute(
new BlackboardAttribute.Type(type), value, osAccount, host, file);
2331 private void addAccountInstance(OsAccountManager accountMgr, OsAccount osAccount, DataSource dataSource)
throws TskCoreException {
2332 accountMgr.newOsAccountInstance(osAccount, dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
2340 private void addSIDToSAMList(String sid) {
2341 String relativeID = stripRelativeIdentifierFromSID(sid);
2342 if (!relativeID.isEmpty() && !samDomainIDsList.contains(relativeID)) {
2343 samDomainIDsList.add(relativeID);
2355 private boolean isDomainIdInSAMList(String osAccountSID) {
2356 String relativeID = stripRelativeIdentifierFromSID(osAccountSID);
2357 return samDomainIDsList.contains(relativeID);