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.Collections;
65 import java.util.Date;
66 import java.util.HashMap;
68 import java.util.Scanner;
70 import java.util.HashSet;
71 import static java.util.Locale.US;
72 import java.util.Optional;
73 import static java.util.TimeZone.getTimeZone;
74 import java.util.stream.Collectors;
75 import org.openide.util.Lookup;
82 import org.
sleuthkit.datamodel.Blackboard.BlackboardException;
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_HOME_DIR;
99 import org.
sleuthkit.datamodel.OsAccount.OsAccountAttribute;
102 import org.
sleuthkit.datamodel.OsAccountManager.NotUserSIDException;
103 import org.
sleuthkit.datamodel.OsAccountManager.OsAccountUpdateResult;
105 import org.
sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
117 "RegRipperNotFound=Autopsy RegRipper executable not found.",
118 "RegRipperFullNotFound=Full version RegRipper executable not found.",
119 "Progress_Message_Analyze_Registry=Analyzing Registry Files",
120 "Shellbag_Artifact_Display_Name=Shell Bags",
121 "Shellbag_Key_Attribute_Display_Name=Key",
122 "Shellbag_Last_Write_Attribute_Display_Name=Last Write",
123 "Sam_Security_Question_1_Attribute_Display_Name=Security Question 1",
124 "Sam_Security_Answer_1_Attribute_Display_Name=Security Answer 1",
125 "Sam_Security_Question_2_Attribute_Display_Name=Security Question 2",
126 "Sam_Security_Answer_2_Attribute_Display_Name=Security Answer 2",
127 "Sam_Security_Question_3_Attribute_Display_Name=Security Question 3",
128 "Sam_Security_Answer_3_Attribute_Display_Name=Security Answer 3",
129 "Recently_Used_Artifacts_Office_Trustrecords=Stored in TrustRecords because Office security exception was granted",
130 "Recently_Used_Artifacts_ArcHistory=Recently opened by 7Zip",
131 "Recently_Used_Artifacts_Applets=Recently opened according to Applets registry key",
132 "Recently_Used_Artifacts_Mmc=Recently opened according to Windows Management Console MRU",
133 "Recently_Used_Artifacts_Winrar=Recently opened according to WinRAR MRU",
134 "Recently_Used_Artifacts_Officedocs=Recently opened according to Office MRU",
135 "Recently_Used_Artifacts_Adobe=Recently opened according to Adobe MRU",
136 "Recently_Used_Artifacts_Mediaplayer=Recently opened according to Media Player MRU",
137 "Registry_System_Bam=Recently Executed according to Background Activity Moderator (BAM)"
139 class ExtractRegistry extends Extract {
141 private static final String USERNAME_KEY =
"Username";
142 private static final String SID_KEY =
"SID";
143 private static final String RID_KEY =
"RID";
144 private static final String ACCOUNT_CREATED_KEY =
"Account Created";
145 private static final String LAST_LOGIN_KEY =
"Last Login Date";
146 private static final String LOGIN_COUNT_KEY =
"Login Count";
147 private static final String FULL_NAME_KEY =
"Full Name";
148 private static final String USER_COMMENT_KEY =
"User Comment";
149 private static final String ACCOUNT_TYPE_KEY =
"Account Type";
150 private static final String NAME_KEY =
"Name";
151 private static final String PWD_RESET_KEY =
"Pwd Rest Date";
152 private static final String PWD_FAILE_KEY =
"Pwd Fail Date";
153 private static final String INTERNET_NAME_KEY =
"InternetName";
154 private static final String PWD_DOES_NOT_EXPIRE_KEY =
"Password does not expire";
155 private static final String ACCOUNT_DISABLED_KEY =
"Account Disabled";
156 private static final String PWD_NOT_REQUIRED_KEY =
"Password not required";
157 private static final String NORMAL_ACCOUNT_KEY =
"Normal user account";
158 private static final String HOME_DIRECTORY_REQUIRED_KEY =
"Home directory required";
159 private static final String TEMPORARY_DUPLICATE_ACCOUNT =
"Temporary duplicate account";
160 private static final String MNS_LOGON_ACCOUNT_KEY =
"MNS logon user account";
161 private static final String INTERDOMAIN_TRUST_ACCOUNT_KEY =
"Interdomain trust account";
162 private static final String WORKSTATION_TRUST_ACCOUNT =
"Workstation trust account";
163 private static final String SERVER_TRUST_ACCOUNT =
"Server trust account";
164 private static final String ACCOUNT_AUTO_LOCKED =
"Account auto locked";
165 private static final String PASSWORD_HINT =
"Password Hint";
166 private static final String SECURITY_QUESTION_1 =
"Question 1";
167 private static final String SECURITY_ANSWER_1 =
"Answer 1";
168 private static final String SECURITY_QUESTION_2 =
"Question 2";
169 private static final String SECURITY_ANSWER_2 =
"Answer 2";
170 private static final String SECURITY_QUESTION_3 =
"Question 3";
171 private static final String SECURITY_ANSWER_3 =
"Answer 3";
173 private static final String[] PASSWORD_SETTINGS_FLAGS = {PWD_DOES_NOT_EXPIRE_KEY, PWD_NOT_REQUIRED_KEY};
174 private static final String[] ACCOUNT_SETTINGS_FLAGS = {ACCOUNT_AUTO_LOCKED, HOME_DIRECTORY_REQUIRED_KEY, ACCOUNT_DISABLED_KEY};
175 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};
177 final private static UsbDeviceIdMapper USB_MAPPER =
new UsbDeviceIdMapper();
178 final private static String RIP_EXE =
"rip.exe";
179 final private static String RIP_PL =
"rip.pl";
180 final private static String RIP_PL_INCLUDE_FLAG =
"-I";
181 final private static int MS_IN_SEC = 1000;
182 final private static String NEVER_DATE =
"Never";
183 final private static String SECTION_DIVIDER =
"-------------------------";
184 final private static Logger logger = Logger.getLogger(ExtractRegistry.class.getName());
185 private final List<String> rrCmd =
new ArrayList<>();
186 private final List<String> rrFullCmd =
new ArrayList<>();
187 private final Path rrHome;
188 private final Path rrFullHome;
189 private Content dataSource;
190 private final IngestJobContext context;
191 private Map<String, String> userNameMap;
192 private final List<String> samDomainIDsList =
new ArrayList<>();
194 private String compName =
"";
195 private String domainName =
"";
197 private static final String SHELLBAG_ARTIFACT_NAME =
"RA_SHELL_BAG";
198 private static final String SHELLBAG_ATTRIBUTE_LAST_WRITE =
"RA_SHELL_BAG_LAST_WRITE";
199 private static final String SHELLBAG_ATTRIBUTE_KEY =
"RA_SHELL_BAG_KEY";
200 private static final String SAM_SECURITY_QUESTION_1 =
"RA_SAM_QUESTION_1";
201 private static final String SAM_SECURITY_ANSWER_1 =
"RA_SAM_ANSWER_1";
202 private static final String SAM_SECURITY_QUESTION_2 =
"RA_SAM_QUESTION_2";
203 private static final String SAM_SECURITY_ANSWER_2 =
"RA_SAM_ANSWER_2";
204 private static final String SAM_SECURITY_QUESTION_3 =
"RA_SAM_QUESTION_3";
205 private static final String SAM_SECURITY_ANSWER_3 =
"RA_SAM_ANSWER_3";
208 private static final SimpleDateFormat REG_RIPPER_TIME_FORMAT =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'", US);
210 private BlackboardArtifact.Type shellBagArtifactType = null;
211 private BlackboardAttribute.Type shellBagKeyAttributeType = null;
212 private BlackboardAttribute.Type shellBagLastWriteAttributeType = null;
214 private OSInfo osInfo =
new OSInfo();
217 REG_RIPPER_TIME_FORMAT.setTimeZone(getTimeZone(
"GMT"));
220 ExtractRegistry(IngestJobContext context)
throws IngestModuleException {
221 super(NbBundle.getMessage(ExtractRegistry.class,
"ExtractRegistry.moduleName.text"), context);
222 this.context = context;
224 final File rrRoot = InstalledFileLocator.getDefault().locate(
"rr", ExtractRegistry.class.getPackage().getName(),
false);
225 if (rrRoot == null) {
226 throw new IngestModuleException(Bundle.RegRipperNotFound());
229 final File rrFullRoot = InstalledFileLocator.getDefault().locate(
"rr-full", ExtractRegistry.class.getPackage().getName(),
false);
230 if (rrFullRoot == null) {
231 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
234 String executableToRun = RIP_EXE;
235 if (!PlatformUtil.isWindowsOS()) {
236 executableToRun = RIP_PL;
238 rrHome = rrRoot.toPath();
239 String rrPath = rrHome.resolve(executableToRun).toString();
240 rrFullHome = rrFullRoot.toPath();
242 if (!(
new File(rrPath).exists())) {
243 throw new IngestModuleException(Bundle.RegRipperNotFound());
245 String rrFullPath = rrFullHome.resolve(executableToRun).toString();
246 if (!(
new File(rrFullPath).exists())) {
247 throw new IngestModuleException(Bundle.RegRipperFullNotFound());
249 if (PlatformUtil.isWindowsOS()) {
251 rrFullCmd.add(rrFullPath);
254 File usrBin =
new File(
"/usr/bin/perl");
255 File usrLocalBin =
new File(
"/usr/local/bin/perl");
256 if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
257 perl =
"/usr/bin/perl";
258 }
else if (usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()) {
259 perl =
"/usr/local/bin/perl";
261 throw new IngestModuleException(
"perl not found in your system");
264 rrCmd.add(RIP_PL_INCLUDE_FLAG);
265 rrCmd.add(rrHome.toString());
268 rrFullCmd.add(RIP_PL_INCLUDE_FLAG);
269 rrFullCmd.add(rrFullHome.toString());
270 rrFullCmd.add(rrFullPath);
277 private List<AbstractFile> findRegistryFiles() {
278 List<AbstractFile> allRegistryFiles =
new ArrayList<>();
283 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"sam",
"/system32/config"));
284 }
catch (TskCoreException ex) {
285 String msg = NbBundle.getMessage(this.getClass(),
286 "ExtractRegistry.findRegFiles.errMsg.errReadingFile",
"sam");
287 logger.log(Level.WARNING, msg, ex);
288 this.addErrorMessage(this.getDisplayName() +
": " + msg);
293 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"ntuser.dat"));
294 }
catch (TskCoreException ex) {
295 logger.log(Level.WARNING,
"Error fetching 'ntuser.dat' file.");
300 allRegistryFiles.addAll(fileManager.findFiles(dataSource,
"usrclass.dat"));
301 }
catch (TskCoreException ex) {
302 logger.log(Level.WARNING, String.format(
"Error finding 'usrclass.dat' files."), ex);
306 String[] regFileNames =
new String[]{
"system",
"software",
"security"};
307 for (String regFileName : regFileNames) {
309 allRegistryFiles.addAll(fileManager.findFiles(dataSource, regFileName,
"/system32/config"));
310 }
catch (TskCoreException ex) {
311 String msg = NbBundle.getMessage(this.getClass(),
312 "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName);
313 logger.log(Level.WARNING, msg, ex);
314 this.addErrorMessage(this.getDisplayName() +
": " + msg);
317 return allRegistryFiles;
326 private void analyzeRegistryFiles(
long ingestJobId) {
327 List<AbstractFile> allRegistryFiles = findRegistryFiles();
330 FileWriter logFile = null;
332 logFile =
new FileWriter(RAImageIngestModule.getRAOutputPath(currentCase,
"reg", ingestJobId) + File.separator +
"regripper-info.txt");
333 }
catch (IOException ex) {
334 logger.log(Level.SEVERE, null, ex);
337 for (AbstractFile regFile : allRegistryFiles) {
338 if (context.dataSourceIngestIsCancelled()) {
342 String regFileName = regFile.getName();
343 long regFileId = regFile.getId();
344 String regFileNameLocal = RAImageIngestModule.getRATempPath(currentCase,
"reg", ingestJobId) + File.separator + regFileName;
345 String outputPathBase = RAImageIngestModule.getRAOutputPath(currentCase,
"reg", ingestJobId) + File.separator + regFileName +
"-regripper-" + Long.toString(regFileId);
346 File regFileNameLocalFile =
new File(regFileNameLocal);
348 ContentUtils.writeToFile(regFile, regFileNameLocalFile, context::dataSourceIngestIsCancelled);
349 }
catch (ReadContentInputStreamException ex) {
350 logger.log(Level.WARNING, String.format(
"Error reading registry file '%s' (id=%d).",
351 regFile.getName(), regFileId), ex);
352 this.addErrorMessage(
353 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
354 this.getDisplayName(), regFileName));
356 }
catch (IOException ex) {
357 logger.log(Level.SEVERE, String.format(
"Error writing temp registry file '%s' for registry file '%s' (id=%d).",
358 regFileNameLocal, regFile.getName(), regFileId), ex);
359 this.addErrorMessage(
360 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
361 this.getDisplayName(), regFileName));
365 if (context.dataSourceIngestIsCancelled()) {
370 if (logFile != null) {
371 logFile.write(Long.toString(regFileId) +
"\t" + regFile.getUniquePath() +
"\n");
373 }
catch (TskCoreException | IOException ex) {
374 logger.log(Level.SEVERE, null, ex);
377 logger.log(Level.INFO,
"{0}- Now getting registry information from {1}",
new Object[]{getDisplayName(), regFileNameLocal});
378 RegOutputFiles regOutputFiles = ripRegistryFile(regFileNameLocal, outputPathBase);
379 if (context.dataSourceIngestIsCancelled()) {
384 if (regOutputFiles.autopsyPlugins.isEmpty() ==
false && parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) ==
false) {
385 this.addErrorMessage(
386 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
387 this.getDisplayName(), regFileName));
390 if (context.dataSourceIngestIsCancelled()) {
395 if (!regOutputFiles.fullPlugins.isEmpty()) {
397 if (regFileNameLocal.toLowerCase().contains(
"sam") && parseSamPluginOutput(regOutputFiles.fullPlugins, regFile, ingestJobId) ==
false) {
398 this.addErrorMessage(
399 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
400 this.getDisplayName(), regFileName));
401 }
else if (regFileNameLocal.toLowerCase().contains(
"ntuser") || regFileNameLocal.toLowerCase().contains(
"usrclass")) {
403 List<ShellBag> shellbags = ShellBagParser.parseShellbagOutput(regOutputFiles.fullPlugins);
404 createShellBagArtifacts(regFile, shellbags);
405 createRecentlyUsedArtifacts(regOutputFiles.fullPlugins, regFile);
406 }
catch (IOException | TskCoreException ex) {
407 logger.log(Level.WARNING, String.format(
"Unable to get shell bags from file %s", regOutputFiles.fullPlugins), ex);
409 }
else if (regFileNameLocal.toLowerCase().contains(
"system") && parseSystemPluginOutput(regOutputFiles.fullPlugins, regFile) ==
false) {
410 this.addErrorMessage(
411 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
412 this.getDisplayName(), regFileName));
415 if (context.dataSourceIngestIsCancelled()) {
420 Report report = currentCase.addReport(regOutputFiles.fullPlugins,
421 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.parentModuleName.noSpace"),
422 "RegRipper " + regFile.getUniquePath(), regFile);
423 }
catch (TskCoreException e) {
424 this.addErrorMessage(
"Error adding regripper output as Autopsy report: " + e.getLocalizedMessage());
428 regFileNameLocalFile.delete();
435 if(allRegistryFiles.size() > 0) {
436 osInfo.createOSInfo();
440 if (logFile != null) {
443 }
catch (IOException ex) {
444 logger.log(Level.SEVERE, null, ex);
455 private RegOutputFiles ripRegistryFile(String regFilePath, String outFilePathBase) {
456 String autopsyType =
"";
459 RegOutputFiles regOutputFiles =
new RegOutputFiles();
461 if (regFilePath.toLowerCase().contains(
"system")) {
462 autopsyType =
"autopsysystem";
464 }
else if (regFilePath.toLowerCase().contains(
"software")) {
465 autopsyType =
"autopsysoftware";
466 fullType =
"software";
467 }
else if (regFilePath.toLowerCase().contains(
"ntuser")) {
468 autopsyType =
"autopsyntuser";
470 }
else if (regFilePath.toLowerCase().contains(
"sam")) {
473 }
else if (regFilePath.toLowerCase().contains(
"security")) {
474 fullType =
"security";
475 }
else if (regFilePath.toLowerCase().contains(
"usrclass")) {
476 fullType =
"usrclass";
478 return regOutputFiles;
482 if (!autopsyType.isEmpty()) {
483 regOutputFiles.autopsyPlugins = outFilePathBase +
"-autopsy.txt";
484 String errFilePath = outFilePathBase +
"-autopsy.err.txt";
485 logger.log(Level.INFO,
"Writing RegRipper results to: {0}", regOutputFiles.autopsyPlugins);
486 executeRegRipper(rrCmd, rrHome, regFilePath, autopsyType, regOutputFiles.autopsyPlugins, errFilePath);
488 if (context.dataSourceIngestIsCancelled()) {
489 return regOutputFiles;
493 if (!fullType.isEmpty()) {
494 regOutputFiles.fullPlugins = outFilePathBase +
"-full.txt";
495 String errFilePath = outFilePathBase +
"-full.err.txt";
496 logger.log(Level.INFO,
"Writing Full RegRipper results to: {0}", regOutputFiles.fullPlugins);
497 executeRegRipper(rrFullCmd, rrFullHome, regFilePath, fullType, regOutputFiles.fullPlugins, errFilePath);
499 scanErrorLogs(errFilePath);
500 }
catch (IOException ex) {
501 logger.log(Level.SEVERE, String.format(
"Unable to run RegRipper on %s", regFilePath), ex);
502 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getDisplayName(), regFilePath));
505 return regOutputFiles;
508 private void scanErrorLogs(String errFilePath)
throws IOException {
509 File regfile =
new File(errFilePath);
510 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
511 String line = reader.readLine();
512 while (line != null) {
514 if (line.toLowerCase().contains(
"error") || line.toLowerCase().contains(
"@inc")) {
515 logger.log(Level.WARNING,
"Regripper file {0} contains errors from run", errFilePath);
518 line = reader.readLine();
523 private void executeRegRipper(List<String> regRipperPath, Path regRipperHomeDir, String hiveFilePath, String hiveFileType, String outputFile, String errFile) {
525 List<String> commandLine =
new ArrayList<>();
526 for (String cmd : regRipperPath) {
527 commandLine.add(cmd);
529 commandLine.add(
"-r");
530 commandLine.add(hiveFilePath);
531 commandLine.add(
"-f");
532 commandLine.add(hiveFileType);
534 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
535 processBuilder.directory(regRipperHomeDir.toFile());
536 processBuilder.redirectOutput(
new File(outputFile));
537 processBuilder.redirectError(
new File(errFile));
538 ExecUtil.execute(processBuilder,
new DataSourceIngestModuleProcessTerminator(context,
true));
539 }
catch (IOException ex) {
540 logger.log(Level.SEVERE, String.format(
"Error running RegRipper on %s", hiveFilePath), ex);
541 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile", this.getDisplayName(), hiveFilePath));
554 private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) {
555 FileInputStream fstream = null;
556 List<BlackboardArtifact> newArtifacts =
new ArrayList<>();
557 String parentModuleName = RecentActivityExtracterModuleFactory.getModuleName();
560 File regfile =
new File(regFilePath);
561 fstream =
new FileInputStream(regfile);
562 String regString =
new Scanner(fstream,
"UTF-8").useDelimiter(
"\\Z").next();
563 String startdoc =
"<?xml version=\"1.0\"?><document>";
564 String result = regString.replaceAll(
"----------------------------------------",
"");
565 result = result.replaceAll(
"\\n",
"");
566 result = result.replaceAll(
"\\r",
"");
567 result = result.replaceAll(
"'",
"'");
568 result = result.replaceAll(
"&",
"&");
569 result = result.replace(
'\0',
' ');
570 String enddoc =
"</document>";
571 String stringdoc = startdoc + result + enddoc;
572 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
573 Document doc = builder.parse(
new InputSource(
new StringReader(stringdoc)));
576 Element oroot = doc.getDocumentElement();
577 NodeList children = oroot.getChildNodes();
578 int len = children.getLength();
579 for (
int i = 0; i < len; i++) {
581 if (context.dataSourceIngestIsCancelled()) {
585 Element tempnode = (Element) children.item(i);
587 String dataType = tempnode.getNodeName();
588 NodeList timenodes = tempnode.getElementsByTagName(
"mtime");
590 if (timenodes.getLength() > 0) {
591 Element timenode = (Element) timenodes.item(0);
592 String etime = timenode.getTextContent().trim();
594 if (etime != null && !etime.isEmpty()) {
596 mtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy", US).parse(etime).getTime();
597 String Tempdate = mtime.toString();
598 mtime = Long.valueOf(Tempdate) / MS_IN_SEC;
599 }
catch (ParseException ex) {
600 logger.log(Level.WARNING,
"Failed to parse epoch time when parsing the registry.", ex);
605 NodeList artroots = tempnode.getElementsByTagName(
"artifacts");
606 if (artroots.getLength() == 0) {
611 Element artroot = (Element) artroots.item(0);
612 NodeList myartlist = artroot.getChildNodes();
618 String systemRoot =
"";
619 String productId =
"";
620 String regOwner =
"";
622 Long installtime = null;
623 for (
int j = 0; j < myartlist.getLength(); j++) {
624 Node artchild = myartlist.item(j);
626 if (artchild.hasAttributes()) {
627 Element artnode = (Element) artchild;
629 String value = artnode.getTextContent();
631 value = value.trim();
633 String name = artnode.getAttribute(
"name");
643 version = version +
" " + value;
651 case "RegisteredOwner":
654 case "RegisteredOrganization":
658 if (value != null && !value.isEmpty()) {
660 installtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyyZ", US).parse(value +
"+0000").getTime();
661 String Tempdate = installtime.toString();
662 installtime = Long.valueOf(Tempdate) / MS_IN_SEC;
663 }
catch (ParseException e) {
664 logger.log(Level.WARNING,
"RegRipper::Conversion on DateTime -> ", e);
674 osInfo.setOsName(version);
675 osInfo.setInstalltime(installtime);
676 osInfo.setSystemRoot(systemRoot);
677 osInfo.setProductId(productId);
678 osInfo.setRegOwner(regOwner);
679 osInfo.setRegOrg(regOrg);
683 String procArch =
"";
685 for (
int j = 0; j < myartlist.getLength(); j++) {
686 Node artchild = myartlist.item(j);
688 if (artchild.hasAttributes()) {
689 Element artnode = (Element) artchild;
691 String value = artnode.getTextContent().trim();
692 String name = artnode.getAttribute(
"name");
697 case "PROCESSOR_ARCHITECTURE":
700 case "PROCESSOR_IDENTIFIER":
711 osInfo.setOsName(os);
712 osInfo.setProcessorArchitecture(procArch);
713 osInfo.setTempDir(tempDir);
716 for (
int j = 0; j < myartlist.getLength(); j++) {
717 Node artchild = myartlist.item(j);
719 if (artchild.hasAttributes()) {
720 Element artnode = (Element) artchild;
722 String value = artnode.getTextContent().trim();
723 String name = artnode.getAttribute(
"name");
725 if (name.equals(
"ComputerName")) {
727 }
else if (name.equals(
"Domain")) {
733 osInfo.setCompName(compName);
734 osInfo.setDomain(domainName);
736 for (Map.Entry<String, String> userMap : getUserNameMap().entrySet()) {
739 sid = userMap.getKey();
740 String userName = userMap.getValue();
742 createOrUpdateOsAccount(regFile, sid, userName, null, null, OsAccountRealm.RealmScope.LOCAL);
743 }
catch (TskCoreException | TskDataException | NotUserSIDException ex) {
744 logger.log(Level.WARNING, String.format(
"Failed to update Domain for existing OsAccount: %s, sid: %s", regFile.getId(), sid), ex);
750 for (
int j = 0; j < myartlist.getLength(); j++) {
751 Node artchild = myartlist.item(j);
753 if (artchild.hasAttributes()) {
754 Element artnode = (Element) artchild;
756 String value = artnode.getTextContent().trim();
757 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
770 Long usbMtime = Long.valueOf(
"0");
771 if (!artnode.getAttribute(
"mtime").isEmpty()) {
772 usbMtime = Long.parseLong(artnode.getAttribute(
"mtime"));
774 usbMtime = Long.valueOf(usbMtime.toString());
776 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, usbMtime));
778 String dev = artnode.getAttribute(
"dev");
781 if (dev.toLowerCase().contains(
"vid")) {
782 USBInfo info = USB_MAPPER.parseAndLookup(dev);
783 if (info.getVendor() != null) {
784 make = info.getVendor();
786 if (info.getProduct() != null) {
787 model = info.getProduct();
790 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE, parentModuleName, make));
791 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL, parentModuleName, model));
792 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, value));
793 newArtifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_DEVICE_ATTACHED, regFile, bbattributes));
794 }
catch (TskCoreException ex) {
795 logger.log(Level.SEVERE, String.format(
"Error adding device_attached artifact to blackboard for file %d.", regFile.getId()), ex);
799 Long itemMtime = null;
801 String mTimeAttr = artnode.getAttribute(
"mtime");
802 if (mTimeAttr != null && !mTimeAttr.isEmpty()) {
803 itemMtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy", US).parse(mTimeAttr).getTime();
804 itemMtime /= MS_IN_SEC;
806 }
catch (ParseException ex) {
807 logger.log(Level.SEVERE,
"Failed to parse epoch time for installed program artifact.", ex);
811 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value));
812 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime));
813 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_INSTALLED_PROG), bbattributes);
814 newArtifacts.add(bbart);
815 }
catch (TskCoreException ex) {
816 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.", ex);
820 String officeName = artnode.getAttribute(
"name");
825 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, parentModuleName, mtime));
827 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, officeName));
828 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, parentModuleName, value));
829 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, artnode.getNodeName()));
830 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_RECENT_OBJECT), bbattributes);
832 newArtifacts.add(bbart);
833 }
catch (TskCoreException ex) {
834 logger.log(Level.SEVERE,
"Error adding recent object artifact to blackboard.", ex);
838 case "ProcessorArchitecture":
854 String homeDir = value;
855 String sid = artnode.getAttribute(
"sid");
856 String username = artnode.getAttribute(
"username");
857 String domName = domainName;
861 OsAccountRealm.RealmScope scope = OsAccountRealm.RealmScope.DOMAIN;
862 if (isDomainIdInSAMList(sid)) {
864 scope = OsAccountRealm.RealmScope.LOCAL;
868 createOrUpdateOsAccount(regFile, sid, username, homeDir, domName, scope);
869 }
catch (TskCoreException | TskDataException | NotUserSIDException ex) {
870 logger.log(Level.SEVERE, String.format(
"Failed to create OsAccount for file: %s, sid: %s", regFile.getId(), sid), ex);
874 case "NtuserNetwork":
876 String localPath = artnode.getAttribute(
"localPath");
877 String remoteName = value;
879 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH,
880 parentModuleName, localPath));
881 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH,
882 parentModuleName, remoteName));
883 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_REMOTE_DRIVE), bbattributes);
884 newArtifacts.add(bbart);
885 }
catch (TskCoreException ex) {
886 logger.log(Level.SEVERE,
"Error adding network artifact to blackboard.", ex);
890 String adapter = artnode.getAttribute(
"adapter");
892 Long lastWriteTime = Long.parseLong(artnode.getAttribute(
"writeTime"));
893 lastWriteTime = Long.valueOf(lastWriteTime.toString());
894 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SSID, parentModuleName, value));
895 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, lastWriteTime));
896 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, adapter));
897 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_WIFI_NETWORK), bbattributes);
898 newArtifacts.add(bbart);
899 }
catch (TskCoreException ex) {
900 logger.log(Level.SEVERE,
"Error adding SSID artifact to blackboard.", ex);
910 logger.log(Level.SEVERE,
"Unrecognized node name: {0}", dataType);
919 }
catch (FileNotFoundException ex) {
920 logger.log(Level.WARNING, String.format(
"Error finding the registry file: %s", regFilePath), ex);
921 }
catch (SAXException ex) {
922 logger.log(Level.WARNING, String.format(
"Error parsing the registry XML: %s", regFilePath), ex);
923 }
catch (IOException ex) {
924 logger.log(Level.WARNING, String.format(
"Error building the document parser: %s", regFilePath), ex);
925 }
catch (ParserConfigurationException ex) {
926 logger.log(Level.WARNING, String.format(
"Error configuring the registry parser: %s", regFilePath), ex);
929 if (fstream != null) {
932 }
catch (IOException ex) {
935 if (!context.dataSourceIngestIsCancelled()) {
936 postArtifacts(newArtifacts);
942 private boolean parseSystemPluginOutput(String regfilePath, AbstractFile regAbstractFile) {
943 File regfile =
new File(regfilePath);
944 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
945 String line = reader.readLine();
946 while (line != null) {
949 if (line.toLowerCase().matches(
"^bam v.*")) {
950 parseBamKey(regAbstractFile, reader, Bundle.Registry_System_Bam());
951 }
else if (line.toLowerCase().matches(
"^bthport v..*")) {
952 parseBlueToothDevices(regAbstractFile, reader);
954 line = reader.readLine();
957 }
catch (FileNotFoundException ex) {
958 logger.log(Level.WARNING,
"Error finding the registry file.", ex);
959 }
catch (IOException ex) {
960 logger.log(Level.WARNING,
"Error reading the system hive: {0}", ex);
979 private void parseBlueToothDevices(AbstractFile regFile, BufferedReader reader)
throws FileNotFoundException, IOException {
980 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
981 String line = reader.readLine();
982 while ((line != null) && (!line.contains(SECTION_DIVIDER))) {
983 line = reader.readLine();
989 if ((line != null) && (line.toLowerCase().contains(
"device unique id"))) {
993 while (line != null && !line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.toLowerCase().contains(
"radio support not found")) {
994 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
995 addBlueToothAttribute(line, attributes, TSK_DEVICE_ID);
996 line = reader.readLine();
998 if ((line != null) && (line.toLowerCase().contains(
"name"))) {
999 addBlueToothAttribute(line, attributes, TSK_NAME);
1000 line = reader.readLine();
1002 addBlueToothAttribute(line, attributes, TSK_DATETIME);
1003 line = reader.readLine();
1004 addBlueToothAttribute(line, attributes, TSK_DATETIME_ACCESSED);
1007 bbartifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_BLUETOOTH_PAIRING, regFile, attributes));
1008 }
catch (TskCoreException ex) {
1009 logger.log(Level.SEVERE, String.format(
"Failed to create bluetooth_pairing artifact for file %d", regFile.getId()), ex);
1013 line = reader.readLine();
1022 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1023 postArtifacts(bbartifacts);
1027 private void addBlueToothAttribute(String line, Collection<BlackboardAttribute> attributes, ATTRIBUTE_TYPE attributeType) {
1032 String tokens[] = line.split(
": ");
1033 if (tokens.length > 1 && !tokens[1].isEmpty()) {
1034 String tokenString = tokens[1];
1035 if (attributeType.getDisplayName().toLowerCase().contains(
"date")) {
1036 String dateString = tokenString.toLowerCase().replace(
" z",
"");
1038 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy", US);
1039 Long dateLong = Long.valueOf(0);
1041 Date newDate = dateFormat.parse(dateString);
1042 dateLong = newDate.getTime() / 1000;
1043 }
catch (ParseException ex) {
1046 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for Bluetooth Last Seen attribute.", dateString), ex);
1048 attributes.add(
new BlackboardAttribute(attributeType, getDisplayName(), dateLong));
1050 attributes.add(
new BlackboardAttribute(attributeType, getDisplayName(), tokenString));
1065 private boolean parseSamPluginOutput(String regFilePath, AbstractFile regAbstractFile,
long ingestJobId) {
1067 File regfile =
new File(regFilePath);
1068 List<BlackboardArtifact> newArtifacts =
new ArrayList<>();
1069 try (BufferedReader bufferedReader =
new BufferedReader(
new InputStreamReader(
new FileInputStream(regfile), StandardCharsets.UTF_8))) {
1071 String userInfoSection =
"User Information";
1072 String previousLine = null;
1073 String line = bufferedReader.readLine();
1074 Set<Map<String, String>> userSet =
new HashSet<>();
1075 Map<String, List<String>> groupMap = null;
1076 while (line != null) {
1077 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(userInfoSection)) {
1078 readUsers(bufferedReader, userSet);
1081 if (line.contains(SECTION_DIVIDER) && previousLine != null && previousLine.contains(
"Group Membership Information")) {
1082 groupMap = readGroups(bufferedReader);
1085 previousLine = line;
1086 line = bufferedReader.readLine();
1088 Map<String, Map<String, String>> userInfoMap =
new HashMap<>();
1090 for (Map<String, String> userInfo : userSet) {
1091 String sid = userInfo.get(SID_KEY);
1092 userInfoMap.put(sid, userInfo);
1093 addSIDToSAMList(sid);
1097 OsAccountManager accountMgr = tskCase.getOsAccountManager();
1098 HostManager hostMrg = tskCase.getHostManager();
1099 Host host = hostMrg.getHostByDataSource((DataSource) dataSource);
1101 List<OsAccount> existingAccounts = accountMgr.getOsAccounts(host);
1102 for (OsAccount osAccount : existingAccounts) {
1103 Optional<String> optional = osAccount.getAddr();
1104 if (!optional.isPresent()) {
1108 String sid = optional.get();
1109 Map<String, String> userInfo = userInfoMap.remove(sid);
1110 if (userInfo != null) {
1111 addAccountInstance(accountMgr, osAccount, (DataSource) dataSource);
1112 updateOsAccount(osAccount, userInfo, groupMap.get(sid), regAbstractFile, ingestJobId);
1117 for (Map<String, String> userInfo : userInfoMap.values()) {
1118 OsAccount osAccount = accountMgr.newWindowsOsAccount(userInfo.get(SID_KEY), null, null, host, OsAccountRealm.RealmScope.LOCAL);
1119 accountMgr.newOsAccountInstance(osAccount, (DataSource) dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
1120 updateOsAccount(osAccount, userInfo, groupMap.get(userInfo.get(SID_KEY)), regAbstractFile, ingestJobId);
1123 }
catch (FileNotFoundException ex) {
1124 logger.log(Level.WARNING,
"Error finding the registry file.", ex);
1125 }
catch (IOException ex) {
1126 logger.log(Level.WARNING,
"Error building the document parser: {0}", ex);
1127 }
catch (TskDataException | TskCoreException ex) {
1128 logger.log(Level.WARNING,
"Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex);
1129 }
catch (OsAccountManager.NotUserSIDException ex) {
1130 logger.log(Level.WARNING,
"Error creating OS Account, input SID is not a user SID.", ex);
1132 if (!context.dataSourceIngestIsCancelled()) {
1133 postArtifacts(newArtifacts);
1150 private void readUsers(BufferedReader bufferedReader, Set<Map<String, String>> users) throws IOException {
1151 String line = bufferedReader.readLine();
1153 String userName =
"";
1154 String user_rid =
"";
1155 while (line != null && !line.contains(SECTION_DIVIDER)) {
1157 if (line.contains(USERNAME_KEY)) {
1158 String regx = USERNAME_KEY +
"\\s*?:";
1159 String userNameAndIdString = line.replaceAll(regx,
"");
1160 userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf(
'[')).trim();
1161 user_rid = userNameAndIdString.substring(userNameAndIdString.lastIndexOf(
'['), userNameAndIdString.lastIndexOf(
']'));
1162 }
else if (line.contains(SID_KEY) && !userName.isEmpty()) {
1163 Map.Entry<String, String> entry = getSAMKeyValue(line);
1165 HashMap<String, String> userInfo =
new HashMap<>();
1166 userInfo.put(USERNAME_KEY, userName);
1167 userInfo.put(RID_KEY, user_rid);
1168 userInfo.put(entry.getKey(), entry.getValue());
1171 line = bufferedReader.readLine();
1172 while (line != null && !line.isEmpty()) {
1173 entry = getSAMKeyValue(line);
1174 if (entry != null) {
1175 userInfo.put(entry.getKey(), entry.getValue());
1177 line = bufferedReader.readLine();
1179 users.add(userInfo);
1183 line = bufferedReader.readLine();
1196 private void createRecentlyUsedArtifacts(String regFileName, AbstractFile regFile)
throws FileNotFoundException, IOException {
1197 File regfile =
new File(regFileName);
1198 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
1199 String line = reader.readLine();
1200 while (line != null) {
1203 if (line.matches(
"^adoberdr v.*")) {
1204 parseAdobeMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Adobe());
1205 }
else if (line.matches(
"^mpmru v.*")) {
1206 parseMediaPlayerMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Mediaplayer());
1207 }
else if (line.matches(
"^trustrecords v.*")) {
1208 parseOfficeTrustRecords(regFile, reader, Bundle.Recently_Used_Artifacts_Office_Trustrecords());
1209 }
else if (line.matches(
"^ArcHistory:")) {
1210 parse7ZipMRU(regFile, reader, Bundle.Recently_Used_Artifacts_ArcHistory());
1211 }
else if (line.matches(
"^applets v.*")) {
1212 parseGenericMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Applets());
1213 }
else if (line.matches(
"^mmc v.*")) {
1214 parseGenericMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Mmc());
1215 }
else if (line.matches(
"^winrar v.*")) {
1216 parseWinRARMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Winrar());
1217 }
else if (line.matches(
"^officedocs2010 v.*")) {
1218 parseOfficeDocs2010MRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Officedocs());
1220 line = reader.readLine();
1236 private void parseBamKey(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1237 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1238 String line = reader.readLine();
1240 while (!line.contains(SECTION_DIVIDER)) {
1241 line = reader.readLine();
1244 line = reader.readLine();
1246 while (!line.contains(SECTION_DIVIDER)) {
1249 String tokens[] = line.split(
"\\|");
1250 Long progRunDateTime = Long.valueOf(tokens[0]);
1253 String fileNameSid[] = tokens[4].split(
"\\s+\\(S-");
1254 String userSid =
"S-" + fileNameSid[1].substring(0, fileNameSid[1].length() - 1);
1255 String userName = getUserNameMap().get(userSid);
1256 if (userName == null) {
1259 String fileName = fileNameSid[0];
1260 if (fileName.startsWith(
"\\Device\\HarddiskVolume")) {
1262 int fileNameStart = fileName.indexOf(
'\\', 16);
1263 fileName = fileName.substring(fileNameStart, fileName.length());
1266 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1267 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, getDisplayName(), fileName));
1268 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, getDisplayName(), userName));
1269 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, getDisplayName(), progRunDateTime));
1270 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, getDisplayName(), comment));
1273 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_PROG_RUN, regFile, attributes);
1274 bbartifacts.add(bba);
1275 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1277 bbartifacts.add(bba);
1279 }
catch (TskCoreException ex) {
1280 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_PROG_RUN artifact for file %d", regFile.getId()), ex);
1282 line = reader.readLine();
1284 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1285 postArtifacts(bbartifacts);
1300 private void parseAdobeMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1301 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1302 String line = reader.readLine();
1303 SimpleDateFormat adobePluginDateFormat =
new SimpleDateFormat(
"yyyyMMddHHmmssZ", US);
1304 Long adobeUsedTime = Long.valueOf(0);
1305 while (!line.contains(SECTION_DIVIDER)) {
1306 line = reader.readLine();
1308 if (line.matches(
"^Key name,file name,sDate,uFileSize,uPageCount")) {
1309 line = reader.readLine();
1312 while (!line.contains(SECTION_DIVIDER)) {
1315 String tokens[] = line.split(
",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
1316 String fileName = tokens[1].substring(0, tokens[1].length() - 1);
1317 fileName = fileName.replace(
"\"",
"");
1318 if (fileName.charAt(0) ==
'/') {
1319 fileName = fileName.substring(1, fileName.length() - 1);
1320 fileName = fileName.replaceFirst(
"/",
":/");
1323 if (tokens.length > 2) {
1326 String fileUsedTime = tokens[2].replaceAll(
"'",
"");
1327 Date usedDate = adobePluginDateFormat.parse(fileUsedTime);
1328 adobeUsedTime = usedDate.getTime() / 1000;
1329 }
catch (ParseException ex) {
1332 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for adobe file artifact.", tokens[2]), ex);
1335 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1336 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1337 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, getDisplayName(), adobeUsedTime));
1338 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1340 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1342 bbartifacts.add(bba);
1343 fileName = fileName.replace(
"\0",
"");
1344 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1346 bbartifacts.add(bba);
1349 }
catch (TskCoreException ex) {
1350 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1352 line = reader.readLine();
1357 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1358 postArtifacts(bbartifacts);
1374 private void parseMediaPlayerMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1375 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1376 String line = reader.readLine();
1377 while (!line.contains(SECTION_DIVIDER)) {
1378 line = reader.readLine();
1380 if (line.contains(
"LastWrite")) {
1381 line = reader.readLine();
1384 while (!line.contains(SECTION_DIVIDER) && !line.contains(
"RecentFileList has no values.")) {
1386 String tokens[] = line.split(
"> ");
1387 String fileName = tokens[1];
1388 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1389 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1390 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1392 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1394 bbartifacts.add(bba);
1395 bba = createAssociatedArtifact(fileName, bba);
1397 bbartifacts.add(bba);
1398 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1400 bbartifacts.add(bba);
1404 }
catch (TskCoreException ex) {
1405 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1407 line = reader.readLine();
1412 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1413 postArtifacts(bbartifacts);
1429 private void parseGenericMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1430 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1431 String line = reader.readLine();
1432 while (!line.contains(SECTION_DIVIDER)) {
1433 line = reader.readLine();
1435 if (line.contains(
"LastWrite")) {
1436 line = reader.readLine();
1439 while (!line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains(
"Applets")
1440 && !line.contains((
"Recent File List"))) {
1442 String tokens[] = line.split(
"> ");
1443 if (tokens.length > 1) {
1444 String fileName = tokens[1];
1445 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1446 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1447 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1449 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1451 bbartifacts.add(bba);
1452 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1454 bbartifacts.add(bba);
1457 }
catch (TskCoreException ex) {
1458 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1461 line = reader.readLine();
1466 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1467 postArtifacts(bbartifacts);
1483 private void parseWinRARMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1484 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1485 String line = reader.readLine();
1486 while (!line.contains(SECTION_DIVIDER)) {
1487 line = reader.readLine();
1489 if (line.contains(
"LastWrite")) {
1490 line = reader.readLine();
1493 if (!line.isEmpty()) {
1494 while (!line.contains(SECTION_DIVIDER)) {
1496 String tokens[] = line.split(
"> ");
1497 String fileName = tokens[1];
1498 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1499 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1500 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1502 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1503 bbartifacts.add(bba);
1504 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1506 bbartifacts.add(bba);
1508 }
catch (TskCoreException ex) {
1509 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1511 line = reader.readLine();
1517 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1518 postArtifacts(bbartifacts);
1534 private void parse7ZipMRU(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1535 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1536 String line = reader.readLine();
1538 if (!line.contains(
"PathHistory:")) {
1539 while (!line.contains(
"PathHistory:") && !line.isEmpty()) {
1542 String fileName = line;
1543 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1544 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1545 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1547 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1548 bbartifacts.add(bba);
1549 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1551 bbartifacts.add(bba);
1554 }
catch (TskCoreException ex) {
1555 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1557 line = reader.readLine();
1561 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1562 postArtifacts(bbartifacts);
1578 private void parseOfficeDocs2010MRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1579 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1580 String line = reader.readLine();
1584 while (!line.contains(SECTION_DIVIDER)) {
1585 line = reader.readLine();
1587 line = reader.readLine();
1588 while (!line.contains(SECTION_DIVIDER)) {
1591 String tokens[] = line.split(
"\\|");
1592 Long docDate = Long.valueOf(tokens[0]);
1593 String fileNameTokens[] = tokens[4].split(
" - ");
1594 String fileName = fileNameTokens[1];
1595 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1596 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1597 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, getDisplayName(), docDate));
1598 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1600 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1601 bbartifacts.add(bba);
1602 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1604 bbartifacts.add(bba);
1606 }
catch (TskCoreException ex) {
1607 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1609 line = reader.readLine();
1612 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1613 postArtifacts(bbartifacts);
1629 private void parseOfficeTrustRecords(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1630 String userProfile = regFile.getParentPath();
1631 userProfile = userProfile.substring(0, userProfile.length() - 1);
1632 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1633 SimpleDateFormat pluginDateFormat =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy", US);
1634 Long usedTime = Long.valueOf(0);
1635 String line = reader.readLine();
1636 while (!line.contains(SECTION_DIVIDER)) {
1637 line = reader.readLine();
1639 usedTime = Long.valueOf(0);
1640 if (!line.contains(
"**") && !line.contains(
"----------") && !line.contains(
"LastWrite")
1641 && !line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains(
"TrustRecords")
1642 && !line.contains(
"VBAWarnings =")) {
1646 String fileName = null;
1647 String tokens[] = line.split(
" : ");
1648 fileName = tokens[1];
1649 fileName = fileName.replace(
"%USERPROFILE%", userProfile);
1652 String fileUsedTime = tokens[0].replaceAll(
" Z",
"");
1653 Date usedDate = pluginDateFormat.parse(fileUsedTime);
1654 usedTime = usedDate.getTime() / 1000;
1655 }
catch (ParseException ex) {
1658 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for TrustRecords artifact.", tokens[0]), ex);
1660 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1661 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1662 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, getDisplayName(), usedTime));
1663 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1665 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1666 bbartifacts.add(bba);
1667 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1669 bbartifacts.add(bba);
1671 }
catch (TskCoreException ex) {
1672 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1677 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1678 postArtifacts(bbartifacts);
1692 private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) {
1693 String fileName = FilenameUtils.getName(filePathName);
1694 String filePath = FilenameUtils.getPath(filePathName);
1695 List<AbstractFile> sourceFiles;
1697 sourceFiles = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, fileName, filePath);
1698 if (!sourceFiles.isEmpty()) {
1699 return createAssociatedArtifact(sourceFiles.get(0), bba);
1701 }
catch (TskCoreException ex) {
1704 logger.log(Level.WARNING, String.format(
"Error finding actual file %s. file may not exist", filePathName));
1720 private Map<String, String> makeUserNameMap(Content dataSource)
throws TskCoreException {
1721 Map<String, String> map =
new HashMap<>();
1723 for (OsAccount account : tskCase.getOsAccountManager().getOsAccounts(((DataSource) dataSource).getHost())) {
1724 Optional<String> userName = account.getLoginName();
1725 String address = account.getAddr().orElse(
"");
1726 if (!address.isEmpty()) {
1727 map.put(address, userName.isPresent() ? userName.get() :
"");
1753 private String stripRelativeIdentifierFromSID(String osAccountSID) {
1754 if (osAccountSID.split(
"-").length > 4) {
1755 int index = osAccountSID.lastIndexOf(
'-');
1756 return index > 1 ? osAccountSID.substring(0, index) :
"";
1761 private final List<String> machineSIDs =
new ArrayList<>();
1768 private Map<String, String> getUserNameMap() {
1769 if (userNameMap == null) {
1773 userNameMap = makeUserNameMap(dataSource);
1774 }
catch (TskCoreException ex) {
1775 logger.log(Level.WARNING,
"Unable to create OS Account user name map", ex);
1778 userNameMap =
new HashMap<>();
1795 private BlackboardAttribute getAttributeForArtifact(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type) throws TskCoreException {
1796 return artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(type.getTypeID())));
1807 void createShellBagArtifacts(AbstractFile regFile, List<ShellBag> shellbags)
throws TskCoreException {
1808 List<BlackboardArtifact> artifacts =
new ArrayList<>();
1810 for (ShellBag bag : shellbags) {
1811 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1812 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), bag.getResource()));
1813 attributes.add(
new BlackboardAttribute(getKeyAttribute(), getDisplayName(), bag.getKey()));
1816 time = bag.getLastWrite();
1818 attributes.add(
new BlackboardAttribute(getLastWriteAttribute(), getDisplayName(), time));
1821 time = bag.getModified();
1823 attributes.add(
new BlackboardAttribute(TSK_DATETIME_MODIFIED, getDisplayName(), time));
1826 time = bag.getCreated();
1828 attributes.add(
new BlackboardAttribute(TSK_DATETIME_CREATED, getDisplayName(), time));
1831 time = bag.getAccessed();
1833 attributes.add(
new BlackboardAttribute(TSK_DATETIME_ACCESSED, getDisplayName(), time));
1836 BlackboardArtifact artifact = createArtifactWithAttributes(getShellBagArtifact(), regFile, attributes);
1837 artifacts.add(artifact);
1840 if (!context.dataSourceIngestIsCancelled()) {
1841 postArtifacts(artifacts);
1854 private BlackboardArtifact.Type getShellBagArtifact() throws TskCoreException {
1855 if (shellBagArtifactType == null) {
1857 shellBagArtifactType = tskCase.getBlackboard().getOrAddArtifactType(SHELLBAG_ARTIFACT_NAME, Bundle.Shellbag_Artifact_Display_Name());
1858 }
catch (BlackboardException ex) {
1859 throw new TskCoreException(String.format(
"Failed to get shell bag artifact type", SHELLBAG_ARTIFACT_NAME), ex);
1863 return shellBagArtifactType;
1874 private BlackboardAttribute.Type getLastWriteAttribute() throws TskCoreException {
1875 if (shellBagLastWriteAttributeType == null) {
1877 shellBagLastWriteAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SHELLBAG_ATTRIBUTE_LAST_WRITE,
1878 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME,
1879 Bundle.Shellbag_Last_Write_Attribute_Display_Name());
1880 }
catch (BlackboardException ex) {
1882 throw new TskCoreException(String.format(
"Failed to get custom attribute %s", SHELLBAG_ATTRIBUTE_LAST_WRITE), ex);
1885 return shellBagLastWriteAttributeType;
1896 private BlackboardAttribute.Type getKeyAttribute() throws TskCoreException {
1897 if (shellBagKeyAttributeType == null) {
1899 shellBagKeyAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SHELLBAG_ATTRIBUTE_KEY,
1900 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
1901 Bundle.Shellbag_Key_Attribute_Display_Name());
1902 }
catch (BlackboardException ex) {
1903 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SHELLBAG_ATTRIBUTE_KEY), ex);
1906 return shellBagKeyAttributeType;
1918 Map<String, List<String>> readGroups(BufferedReader bufferedReader)
throws IOException {
1919 Map<String, List<String>> groupMap =
new HashMap<>();
1921 String line = bufferedReader.readLine();
1924 String groupName = null;
1926 while (line != null && !line.contains(SECTION_DIVIDER)) {
1928 if (line.contains(
"Group Name")) {
1929 String value = line.replaceAll(
"Group Name\\s*?:",
"").trim();
1930 groupName = (value.replaceAll(
"\\[\\d*?\\]",
"")).trim();
1931 int startIndex = value.indexOf(
" [") + 1;
1932 int endIndex = value.indexOf(
']');
1934 if (startIndex != -1 && endIndex != -1) {
1935 String countStr = value.substring(startIndex + 1, endIndex);
1936 userCount = Integer.parseInt(countStr);
1938 }
else if (line.matches(
"Users\\s*?:")) {
1939 for (
int i = 0; i < userCount; i++) {
1940 line = bufferedReader.readLine();
1942 String sid = line.trim();
1943 List<String> groupList = groupMap.get(sid);
1944 if (groupList == null) {
1945 groupList =
new ArrayList<>();
1946 groupMap.put(sid, groupList);
1948 groupList.add(groupName);
1953 line = bufferedReader.readLine();
1966 private Map.Entry<String, String> getSAMKeyValue(String line) {
1967 int index = line.indexOf(
':');
1968 Map.Entry<String, String> returnValue = null;
1970 String value = null;
1973 key = line.substring(0, index).trim();
1974 if (index + 1 < line.length()) {
1975 value = line.substring(index + 1).trim();
1980 }
else if (line.contains(
"-->")) {
1981 key = line.replace(
"-->",
"").trim();
1986 returnValue =
new AbstractMap.SimpleEntry<>(key, value);
1993 public void process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
1994 this.dataSource = dataSource;
1996 progressBar.progress(Bundle.Progress_Message_Analyze_Registry());
1997 analyzeRegistryFiles(context.getJobId());
2005 public String autopsyPlugins =
"";
2006 public String fullPlugins =
"";
2021 private void createOrUpdateOsAccount(AbstractFile file, String sid, String userName, String homeDir, String domainName, OsAccountRealm.RealmScope realmScope) throws TskCoreException, TskDataException, NotUserSIDException {
2022 OsAccountManager accountMgr = tskCase.getOsAccountManager();
2023 HostManager hostMrg = tskCase.getHostManager();
2024 Host host = hostMrg.getHostByDataSource((DataSource) dataSource);
2026 Optional<OsAccount> optional = accountMgr.getWindowsOsAccount(sid, null, null, host);
2027 OsAccount osAccount;
2028 if (!optional.isPresent()) {
2029 osAccount = accountMgr.newWindowsOsAccount(sid, userName != null && userName.isEmpty() ? null : userName, domainName, host, realmScope);
2030 accountMgr.newOsAccountInstance(osAccount, (DataSource) dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
2032 osAccount = optional.get();
2033 addAccountInstance(accountMgr, osAccount, (DataSource) dataSource);
2034 if (userName != null && !userName.isEmpty()) {
2035 OsAccountUpdateResult updateResult = accountMgr.updateCoreWindowsOsAccountAttributes(osAccount, null, userName, (domainName == null || domainName.isEmpty()) ? null : domainName, host);
2036 osAccount = updateResult.getUpdatedAccount().orElse(osAccount);
2040 if (homeDir != null && !homeDir.isEmpty()) {
2041 List<OsAccountAttribute> attributes =
new ArrayList<>();
2042 String dir = homeDir.replaceFirst(
"^(%\\w*%)",
"");
2043 dir = dir.replace(
"\\",
"/");
2044 attributes.add(createOsAccountAttribute(TSK_HOME_DIR, dir, osAccount, host, file));
2045 accountMgr.addExtendedOsAccountAttributes(osAccount, attributes);
2057 private void addEmailAccount(AbstractFile regFile, String emailAddress,
long ingestJobId) {
2059 currentCase.getSleuthkitCase()
2060 .getCommunicationsManager()
2061 .createAccountFileInstance(Account.Type.EMAIL,
2062 emailAddress, getRAModuleName(), regFile,
2063 Collections.emptyList(),
2065 }
catch (TskCoreException ex) {
2066 logger.log(Level.SEVERE,
2067 String.format(
"Error adding email account with value "
2068 +
"%s, to the case database for file %s [objId=%d]",
2069 emailAddress, regFile.getName(), regFile.getId()), ex);
2081 private Long parseRegRipTime(String value) {
2083 return REG_RIPPER_TIME_FORMAT.parse(value).getTime() / MS_IN_SEC;
2084 }
catch (ParseException ex) {
2085 logger.log(Level.SEVERE, String.format(
"Failed to parse reg rip time: %s", value));
2102 private void updateOsAccount(OsAccount osAccount, Map<String, String> userInfo, List<String> groupList, AbstractFile regFile,
long ingestJobId)
throws TskDataException, TskCoreException, NotUserSIDException {
2103 Host host = ((DataSource) dataSource).getHost();
2104 SimpleDateFormat regRipperTimeFormat =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'", US);
2105 regRipperTimeFormat.setTimeZone(getTimeZone(
"GMT"));
2107 List<OsAccountAttribute> attributes =
new ArrayList<>();
2109 Long creationTime = null;
2111 String value = userInfo.get(ACCOUNT_CREATED_KEY);
2112 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2113 creationTime = parseRegRipTime(value);
2116 value = userInfo.get(LAST_LOGIN_KEY);
2117 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2118 Long time = parseRegRipTime(value);
2120 attributes.add(createOsAccountAttribute(TSK_DATETIME_ACCESSED,
2121 parseRegRipTime(value),
2122 osAccount, host, regFile));
2126 String loginName = null;
2127 value = userInfo.get(USERNAME_KEY);
2128 if (value != null && !value.isEmpty()) {
2132 value = userInfo.get(LOGIN_COUNT_KEY);
2133 if (value != null && !value.isEmpty()) {
2134 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
2135 Integer.parseInt(value),
2136 osAccount, host, regFile));
2142 value = userInfo.get(ACCOUNT_TYPE_KEY);
2143 if (value != null && !value.isEmpty() && value.toLowerCase().contains(
"admin")) {
2144 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_IS_ADMIN,
2145 1, osAccount, host, regFile));
2148 value = userInfo.get(USER_COMMENT_KEY);
2149 if (value != null && !value.isEmpty()) {
2150 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_DESCRIPTION,
2151 value, osAccount, host, regFile));
2154 value = userInfo.get(INTERNET_NAME_KEY);
2155 if (value != null && !value.isEmpty()) {
2156 addEmailAccount(regFile, value, ingestJobId);
2158 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_EMAIL,
2159 value, osAccount, host, regFile));
2163 String fullName = null;
2164 value = userInfo.get(FULL_NAME_KEY);
2165 if (value != null && !value.isEmpty()) {
2168 value = userInfo.get(NAME_KEY);
2169 if (value != null && !value.isEmpty()) {
2174 value = userInfo.get(PWD_RESET_KEY);
2175 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2176 Long time = parseRegRipTime(value);
2178 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_RESET,
2179 time, osAccount, host, regFile));
2183 value = userInfo.get(SECURITY_QUESTION_1);
2184 if (value != null && !value.isEmpty()) {
2185 BlackboardAttribute.Type securityQuestionAttributeType = null;
2187 securityQuestionAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_QUESTION_1,
2188 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2189 Bundle.Sam_Security_Question_1_Attribute_Display_Name());
2190 }
catch (BlackboardException ex) {
2191 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_QUESTION_1), ex);
2193 attributes.add(createOsAccountAttribute(securityQuestionAttributeType, value, osAccount, host, regFile));
2196 value = userInfo.get(SECURITY_ANSWER_1);
2197 if (value != null && !value.isEmpty()) {
2198 BlackboardAttribute.Type securityAnswerAttributeType = null;
2200 securityAnswerAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_ANSWER_1,
2201 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2202 Bundle.Sam_Security_Answer_1_Attribute_Display_Name());
2203 }
catch (BlackboardException ex) {
2204 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_ANSWER_1), ex);
2206 attributes.add(createOsAccountAttribute(securityAnswerAttributeType, value, osAccount, host, regFile));
2209 value = userInfo.get(SECURITY_QUESTION_2);
2210 if (value != null && !value.isEmpty()) {
2211 BlackboardAttribute.Type securityQuestionAttributeType = null;
2213 securityQuestionAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_QUESTION_2,
2214 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2215 Bundle.Sam_Security_Question_2_Attribute_Display_Name());
2216 }
catch (BlackboardException ex) {
2217 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_QUESTION_2), ex);
2219 attributes.add(createOsAccountAttribute(securityQuestionAttributeType, value, osAccount, host, regFile));
2222 value = userInfo.get(SECURITY_ANSWER_2);
2223 if (value != null && !value.isEmpty()) {
2224 BlackboardAttribute.Type securityAnswerAttributeType = null;
2226 securityAnswerAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_ANSWER_2,
2227 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2228 Bundle.Sam_Security_Answer_2_Attribute_Display_Name());
2229 }
catch (BlackboardException ex) {
2230 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_ANSWER_2), ex);
2232 attributes.add(createOsAccountAttribute(securityAnswerAttributeType, value, osAccount, host, regFile));
2235 value = userInfo.get(SECURITY_QUESTION_3);
2236 if (value != null && !value.isEmpty()) {
2237 BlackboardAttribute.Type securityQuestionAttributeType = null;
2239 securityQuestionAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_QUESTION_3,
2240 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2241 Bundle.Sam_Security_Question_2_Attribute_Display_Name());
2242 }
catch (BlackboardException ex) {
2243 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_QUESTION_3), ex);
2245 attributes.add(createOsAccountAttribute(securityQuestionAttributeType, value, osAccount, host, regFile));
2248 value = userInfo.get(SECURITY_ANSWER_3);
2249 if (value != null && !value.isEmpty()) {
2250 BlackboardAttribute.Type securityAnswerAttributeType = null;
2252 securityAnswerAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_ANSWER_3,
2253 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2254 Bundle.Sam_Security_Answer_3_Attribute_Display_Name());
2255 }
catch (BlackboardException ex) {
2256 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_ANSWER_3), ex);
2258 attributes.add(createOsAccountAttribute(securityAnswerAttributeType, value, osAccount, host, regFile));
2261 value = userInfo.get(PASSWORD_HINT);
2262 if (value != null && !value.isEmpty()) {
2263 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_HINT,
2264 value, osAccount, host, regFile));
2267 value = userInfo.get(PWD_FAILE_KEY);
2268 if (value != null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2269 Long time = parseRegRipTime(value);
2271 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_FAIL,
2272 time, osAccount, host, regFile));
2276 String settingString = getSettingsFromMap(PASSWORD_SETTINGS_FLAGS, userInfo);
2277 if (!settingString.isEmpty()) {
2278 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_SETTINGS,
2279 settingString, osAccount, host, regFile));
2282 settingString = getSettingsFromMap(ACCOUNT_SETTINGS_FLAGS, userInfo);
2283 if (!settingString.isEmpty()) {
2284 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_SETTINGS,
2285 settingString, osAccount, host, regFile));
2288 settingString = getSettingsFromMap(ACCOUNT_TYPE_FLAGS, userInfo);
2289 if (!settingString.isEmpty()) {
2290 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_FLAG,
2291 settingString, osAccount, host, regFile));
2294 if (groupList != null && groupList.isEmpty()) {
2295 String groups = groupList.stream()
2296 .map(String::valueOf)
2297 .collect(Collectors.joining(
", "));
2299 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_GROUPS,
2300 groups, osAccount, host, regFile));
2304 OsAccountManager accountMgr = tskCase.getOsAccountManager();
2305 accountMgr.addExtendedOsAccountAttributes(osAccount, attributes);
2308 accountMgr.updateCoreWindowsOsAccountAttributes(osAccount, null, loginName, null, host);
2311 accountMgr.updateStandardOsAccountAttributes(osAccount, fullName, null, null, creationTime);
2323 private String getSettingsFromMap(String[] keys, Map<String, String> map) {
2324 List<String> settingsList =
new ArrayList<>();
2325 for (String setting : keys) {
2326 if (map.containsKey(setting)) {
2327 settingsList.add(setting);
2331 if (!settingsList.isEmpty()) {
2332 return settingsList.stream()
2333 .map(String::valueOf)
2334 .collect(Collectors.joining(
", "));
2351 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.Type type, String value, OsAccount osAccount, Host host, AbstractFile file) {
2352 return osAccount.new OsAccountAttribute(type, value, osAccount, host, file);
2366 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.ATTRIBUTE_TYPE type, String value, OsAccount osAccount, Host host, AbstractFile file) {
2367 return osAccount.new OsAccountAttribute(
new BlackboardAttribute.Type(type), value, osAccount, host, file);
2381 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.ATTRIBUTE_TYPE type, Long value, OsAccount osAccount, Host host, AbstractFile file) {
2382 return osAccount.new OsAccountAttribute(
new BlackboardAttribute.Type(type), value, osAccount, host, file);
2396 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.ATTRIBUTE_TYPE type, Integer value, OsAccount osAccount, Host host, AbstractFile file) {
2397 return osAccount.new OsAccountAttribute(
new BlackboardAttribute.Type(type), value, osAccount, host, file);
2410 private void addAccountInstance(OsAccountManager accountMgr, OsAccount osAccount, DataSource dataSource)
throws TskCoreException {
2411 accountMgr.newOsAccountInstance(osAccount, dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
2419 private void addSIDToSAMList(String sid) {
2420 String relativeID = stripRelativeIdentifierFromSID(sid);
2421 if (!relativeID.isEmpty() && !samDomainIDsList.contains(relativeID)) {
2422 samDomainIDsList.add(relativeID);
2434 private boolean isDomainIdInSAMList(String osAccountSID) {
2435 String relativeID = stripRelativeIdentifierFromSID(osAccountSID);
2436 return samDomainIDsList.contains(relativeID);
2442 private String compName = null;
2443 private String progName =
"Windows";
2444 private String processorArchitecture = null;
2445 private String tempDir = null;
2446 private String domain = null;
2447 private Long installtime = null;
2448 private String systemRoot = null;
2449 private String productId = null;
2450 private String regOwner = null;
2451 private String regOrg = null;
2455 void createOSInfo() {
2458 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, context.getDataSource().getId());
2460 if (results.isEmpty()) {
2461 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
2462 if (compName != null && !compName.isEmpty()) {
2463 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, compName));
2465 if (domain != null && !domain.isEmpty()) {
2466 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN, parentModuleName, domain));
2468 if (progName != null && !progName.isEmpty()) {
2469 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, progName));
2471 if (processorArchitecture != null && !processorArchitecture.isEmpty()) {
2472 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE, parentModuleName, processorArchitecture));
2474 if (tempDir != null && !tempDir.isEmpty()) {
2475 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR, parentModuleName, tempDir));
2477 if (installtime != null) {
2478 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, installtime));
2480 if (systemRoot != null && !systemRoot.isEmpty()) {
2481 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, parentModuleName, systemRoot));
2483 if (productId != null && !productId.isEmpty()) {
2484 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID, parentModuleName, productId));
2486 if (regOwner != null && !regOwner.isEmpty()) {
2487 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER, parentModuleName, regOwner));
2489 if (regOrg != null && !regOrg.isEmpty()) {
2490 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION, parentModuleName, regOrg));
2493 postArtifact(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_OS_INFO, context.getDataSource(), bbattributes));
2495 }
catch (TskCoreException ex) {
2496 logger.log(Level.SEVERE,
"Failed to create default OS_INFO artifact", ex);
2500 void setCompName(String compName) {
2501 if(this.compName == null || this.compName.isEmpty()) {
2502 this.compName = compName;
2506 void setOsName(String progName) {
2507 if(progName != null && !progName.isEmpty()) {
2508 this.progName = progName;
2512 void setProcessorArchitecture(String processorArchitecture) {
2513 if(this.processorArchitecture == null || this.processorArchitecture.isEmpty()) {
2514 this.processorArchitecture = processorArchitecture;
2518 void setTempDir(String tempDir) {
2519 if(this.tempDir == null || this.tempDir.isEmpty()) {
2520 this.tempDir = tempDir;
2524 void setDomain(String domain) {
2525 if(this.domain == null || this.domain.isEmpty()) {
2526 this.domain = domain;
2530 void setInstalltime(Long installtime) {
2531 if(this.domain == null) {
2532 this.installtime = installtime;
2536 void setSystemRoot(String systemRoot) {
2537 if(this.systemRoot == null || this.systemRoot.isEmpty()) {
2538 this.systemRoot = systemRoot;
2542 void setProductId(String productId) {
2543 if(this.productId == null || this.productId.isEmpty()) {
2544 this.productId = productId;
2548 void setRegOwner(String regOwner) {
2549 if(this.regOwner == null || this.regOwner.isEmpty()) {
2550 this.regOwner = regOwner;
2554 void setRegOrg(String regOrg) {
2555 if(this.regOrg == null || this.regOrg.isEmpty()) {
2556 this.regOrg = regOrg;