23package org.sleuthkit.autopsy.recentactivity;
25import java.io.BufferedReader;
27import java.io.FileInputStream;
28import java.io.FileNotFoundException;
29import java.io.FileReader;
30import java.io.FileWriter;
31import java.io.IOException;
32import java.io.InputStreamReader;
33import java.io.StringReader;
34import java.nio.charset.StandardCharsets;
35import java.text.ParseException;
36import java.text.SimpleDateFormat;
37import java.util.logging.Level;
38import javax.xml.parsers.DocumentBuilder;
39import javax.xml.parsers.ParserConfigurationException;
40import org.apache.commons.io.FilenameUtils;
41import org.openide.modules.InstalledFileLocator;
42import org.openide.util.NbBundle;
43import org.sleuthkit.autopsy.coreutils.ExecUtil;
44import org.sleuthkit.autopsy.coreutils.Logger;
45import org.sleuthkit.autopsy.coreutils.PlatformUtil;
46import org.sleuthkit.autopsy.coreutils.XMLUtil;
47import org.sleuthkit.autopsy.datamodel.ContentUtils;
48import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator;
49import org.sleuthkit.autopsy.ingest.IngestJobContext;
50import org.sleuthkit.autopsy.recentactivity.UsbDeviceIdMapper.USBInfo;
51import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
52import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
53import org.w3c.dom.Document;
54import org.w3c.dom.Element;
55import org.w3c.dom.Node;
56import org.w3c.dom.NodeList;
57import org.xml.sax.InputSource;
58import org.xml.sax.SAXException;
59import java.nio.file.Path;
60import java.util.AbstractMap;
61import java.util.ArrayList;
63import java.util.Collection;
64import java.util.Collections;
66import java.util.HashMap;
68import java.util.Scanner;
70import java.util.HashSet;
71import static java.util.Locale.US;
72import java.util.Optional;
73import static java.util.TimeZone.getTimeZone;
74import java.util.stream.Collectors;
75import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
76import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException;
77import org.sleuthkit.autopsy.recentactivity.ShellBagParser.ShellBag;
78import org.sleuthkit.datamodel.AbstractFile;
79import org.sleuthkit.datamodel.Account;
80import org.sleuthkit.datamodel.Blackboard.BlackboardException;
81import org.sleuthkit.datamodel.BlackboardArtifact;
82import org.sleuthkit.datamodel.BlackboardAttribute;
83import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT;
84import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
85import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED;
86import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED;
87import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_MODIFIED;
88import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID;
89import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME;
90import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH;
91import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HOME_DIR;
92import org.sleuthkit.datamodel.Content;
93import org.sleuthkit.datamodel.DataSource;
94import org.sleuthkit.datamodel.Host;
95import org.sleuthkit.datamodel.HostManager;
96import org.sleuthkit.datamodel.OsAccount;
97import org.sleuthkit.datamodel.OsAccount.OsAccountAttribute;
98import org.sleuthkit.datamodel.OsAccountInstance;
99import org.sleuthkit.datamodel.OsAccountManager;
100import org.sleuthkit.datamodel.OsAccountManager.NotUserSIDException;
101import org.sleuthkit.datamodel.OsAccountManager.OsAccountUpdateResult;
102import org.sleuthkit.datamodel.OsAccountRealm;
103import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
104import org.sleuthkit.datamodel.Report;
105import org.sleuthkit.datamodel.TskCoreException;
106import org.sleuthkit.datamodel.TskDataException;
115 "RegRipperNotFound=Autopsy RegRipper executable not found.",
116 "RegRipperFullNotFound=Full version RegRipper executable not found.",
117 "Progress_Message_Analyze_Registry=Analyzing Registry Files",
118 "Shellbag_Artifact_Display_Name=Shell Bags",
119 "WSL_Artifact_Display_Name=Windows Subsystem For Linux",
120 "WSL_Kernal_Command_Attribute_Display_Name=Kernal Command",
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 "Recently_Used_Artifacts_WSL=Windows Subsystem For Linux",
138 "Registry_System_Bam=Recently Executed according to Background Activity Moderator (BAM)"
140class ExtractRegistry extends Extract {
142 private static final String USERNAME_KEY =
"Username";
143 private static final String SID_KEY =
"SID";
144 private static final String RID_KEY =
"RID";
145 private static final String ACCOUNT_CREATED_KEY =
"Account Created";
146 private static final String LAST_LOGIN_KEY =
"Last Login Date";
147 private static final String LOGIN_COUNT_KEY =
"Login Count";
148 private static final String FULL_NAME_KEY =
"Full Name";
149 private static final String USER_COMMENT_KEY =
"User Comment";
150 private static final String ACCOUNT_TYPE_KEY =
"Account Type";
151 private static final String NAME_KEY =
"Name";
152 private static final String PWD_RESET_KEY =
"Pwd Rest Date";
153 private static final String PWD_FAILE_KEY =
"Pwd Fail Date";
154 private static final String INTERNET_NAME_KEY =
"InternetName";
155 private static final String PWD_DOES_NOT_EXPIRE_KEY =
"Password does not expire";
156 private static final String ACCOUNT_DISABLED_KEY =
"Account Disabled";
157 private static final String PWD_NOT_REQUIRED_KEY =
"Password not required";
158 private static final String NORMAL_ACCOUNT_KEY =
"Normal user account";
159 private static final String HOME_DIRECTORY_REQUIRED_KEY =
"Home directory required";
160 private static final String TEMPORARY_DUPLICATE_ACCOUNT =
"Temporary duplicate account";
161 private static final String MNS_LOGON_ACCOUNT_KEY =
"MNS logon user account";
162 private static final String INTERDOMAIN_TRUST_ACCOUNT_KEY =
"Interdomain trust account";
163 private static final String WORKSTATION_TRUST_ACCOUNT =
"Workstation trust account";
164 private static final String SERVER_TRUST_ACCOUNT =
"Server trust account";
165 private static final String ACCOUNT_AUTO_LOCKED =
"Account auto locked";
166 private static final String PASSWORD_HINT =
"Password Hint";
167 private static final String SECURITY_QUESTION_1 =
"Question 1";
168 private static final String SECURITY_ANSWER_1 =
"Answer 1";
169 private static final String SECURITY_QUESTION_2 =
"Question 2";
170 private static final String SECURITY_ANSWER_2 =
"Answer 2";
171 private static final String SECURITY_QUESTION_3 =
"Question 3";
172 private static final String SECURITY_ANSWER_3 =
"Answer 3";
174 private static final String[] PASSWORD_SETTINGS_FLAGS = {PWD_DOES_NOT_EXPIRE_KEY, PWD_NOT_REQUIRED_KEY};
175 private static final String[] ACCOUNT_SETTINGS_FLAGS = {ACCOUNT_AUTO_LOCKED, HOME_DIRECTORY_REQUIRED_KEY, ACCOUNT_DISABLED_KEY};
176 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};
178 final private static UsbDeviceIdMapper USB_MAPPER =
new UsbDeviceIdMapper();
179 final private static String RIP_EXE =
"rip.exe";
180 final private static String RIP_PL =
"rip.pl";
181 final private static String RIP_PL_INCLUDE_FLAG =
"-I";
182 final private static int MS_IN_SEC = 1000;
183 final private static String NEVER_DATE =
"Never";
184 final private static String SECTION_DIVIDER =
"----------------------------------------";
186 private final List<String> rrCmd =
new ArrayList<>();
187 private final List<String> rrFullCmd =
new ArrayList<>();
188 private final Path rrHome;
189 private final Path rrFullHome;
190 private Content dataSource;
192 private Map<String, String> userNameMap;
193 private final List<String> samDomainIDsList =
new ArrayList<>();
195 private String compName =
"";
196 private String domainName =
"";
198 private static final String WSL_ARTIFACT_NAME =
"WSL_NAME";
199 private static final String SHELLBAG_ARTIFACT_NAME =
"RA_SHELL_BAG";
200 private static final String SHELLBAG_ATTRIBUTE_LAST_WRITE =
"RA_SHELL_BAG_LAST_WRITE";
201 private static final String WSL_ATTRIBUTE_KERNAL_COMMAND =
"WSL_KERNAL_COMMAND";
202 private static final String SHELLBAG_ATTRIBUTE_KEY =
"RA_SHELL_BAG_KEY";
203 private static final String SAM_SECURITY_QUESTION_1 =
"RA_SAM_QUESTION_1";
204 private static final String SAM_SECURITY_ANSWER_1 =
"RA_SAM_ANSWER_1";
205 private static final String SAM_SECURITY_QUESTION_2 =
"RA_SAM_QUESTION_2";
206 private static final String SAM_SECURITY_ANSWER_2 =
"RA_SAM_ANSWER_2";
207 private static final String SAM_SECURITY_QUESTION_3 =
"RA_SAM_QUESTION_3";
208 private static final String SAM_SECURITY_ANSWER_3 =
"RA_SAM_ANSWER_3";
211 private static final SimpleDateFormat REG_RIPPER_TIME_FORMAT =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'", US);
213 private BlackboardArtifact.Type wslArtifactType =
null;
214 private BlackboardArtifact.Type shellBagArtifactType =
null;
215 private BlackboardAttribute.Type kernalCommandAttributeType =
null;
216 private BlackboardAttribute.Type shellBagKeyAttributeType =
null;
217 private BlackboardAttribute.Type shellBagLastWriteAttributeType =
null;
219 private OSInfo osInfo =
new OSInfo();
222 REG_RIPPER_TIME_FORMAT.setTimeZone(getTimeZone(
"GMT"));
226 super(NbBundle.getMessage(ExtractRegistry.class,
"ExtractRegistry.moduleName.text"), context);
227 this.context = context;
229 final File rrRoot = InstalledFileLocator.getDefault().locate(
"rr", ExtractRegistry.class.getPackage().getName(),
false);
230 if (rrRoot ==
null) {
234 final File rrFullRoot = InstalledFileLocator.getDefault().locate(
"rr-full", ExtractRegistry.class.getPackage().getName(),
false);
235 if (rrFullRoot ==
null) {
239 String executableToRun = RIP_EXE;
241 executableToRun = RIP_PL;
243 rrHome = rrRoot.toPath();
244 String rrPath = rrHome.resolve(executableToRun).toString();
245 rrFullHome = rrFullRoot.toPath();
247 if (!(
new File(rrPath).exists())) {
250 String rrFullPath = rrFullHome.resolve(executableToRun).toString();
251 if (!(
new File(rrFullPath).exists())) {
256 rrFullCmd.add(rrFullPath);
259 File usrBin =
new File(
"/usr/bin/perl");
260 File usrLocalBin =
new File(
"/usr/local/bin/perl");
261 if (usrBin.canExecute() && usrBin.exists() && !usrBin.isDirectory()) {
262 perl =
"/usr/bin/perl";
263 }
else if (usrLocalBin.canExecute() && usrLocalBin.exists() && !usrLocalBin.isDirectory()) {
264 perl =
"/usr/local/bin/perl";
269 rrCmd.add(RIP_PL_INCLUDE_FLAG);
270 rrCmd.add(rrHome.toString());
273 rrFullCmd.add(RIP_PL_INCLUDE_FLAG);
274 rrFullCmd.add(rrFullHome.toString());
275 rrFullCmd.add(rrFullPath);
282 private List<AbstractFile> findRegistryFiles() {
283 List<AbstractFile> allRegistryFiles =
new ArrayList<>();
284 org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
288 allRegistryFiles.addAll(fileManager.
findFiles(dataSource,
"sam",
"/system32/config"));
289 }
catch (TskCoreException ex) {
290 String msg = NbBundle.getMessage(this.getClass(),
291 "ExtractRegistry.findRegFiles.errMsg.errReadingFile",
"sam");
292 logger.log(Level.WARNING, msg, ex);
293 this.addErrorMessage(this.getDisplayName() +
": " + msg);
298 allRegistryFiles.addAll(fileManager.
findFiles(dataSource,
"ntuser.dat"));
299 }
catch (TskCoreException ex) {
300 logger.log(Level.WARNING,
"Error fetching 'ntuser.dat' file.");
305 allRegistryFiles.addAll(fileManager.
findFiles(dataSource,
"usrclass.dat"));
306 }
catch (TskCoreException ex) {
307 logger.log(Level.WARNING, String.format(
"Error finding 'usrclass.dat' files."), ex);
311 String[] regFileNames =
new String[]{
"system",
"software",
"security"};
312 for (String regFileName : regFileNames) {
314 allRegistryFiles.addAll(fileManager.
findFiles(dataSource, regFileName,
"/system32/config"));
315 }
catch (TskCoreException ex) {
316 String msg = NbBundle.getMessage(this.getClass(),
317 "ExtractRegistry.findRegFiles.errMsg.errReadingFile", regFileName);
318 logger.log(Level.WARNING, msg, ex);
319 this.addErrorMessage(this.getDisplayName() +
": " + msg);
322 return allRegistryFiles;
331 private void analyzeRegistryFiles(
long ingestJobId) {
332 List<AbstractFile> allRegistryFiles = findRegistryFiles();
335 FileWriter logFile =
null;
337 logFile =
new FileWriter(
RAImageIngestModule.getRAOutputPath(currentCase,
"reg", ingestJobId) + File.separator +
"regripper-info.txt");
338 }
catch (IOException ex) {
339 logger.log(Level.SEVERE,
null, ex);
342 for (AbstractFile regFile : allRegistryFiles) {
343 if (context.dataSourceIngestIsCancelled()) {
347 String regFileName = regFile.getName();
348 long regFileId = regFile.getId();
349 String regFileNameLocal =
RAImageIngestModule.getRATempPath(currentCase,
"reg", ingestJobId) + File.separator + regFileName;
350 String outputPathBase =
RAImageIngestModule.getRAOutputPath(currentCase,
"reg", ingestJobId) + File.separator + regFileName +
"-regripper-" + Long.toString(regFileId);
351 File regFileNameLocalFile =
new File(regFileNameLocal);
354 }
catch (ReadContentInputStreamException ex) {
355 logger.log(Level.WARNING, String.format(
"Error reading registry file '%s' (id=%d).",
356 regFile.getName(), regFileId), ex);
357 this.addErrorMessage(
358 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
359 this.getDisplayName(), regFileName));
361 }
catch (IOException ex) {
362 logger.log(Level.SEVERE, String.format(
"Error writing temp registry file '%s' for registry file '%s' (id=%d).",
363 regFileNameLocal, regFile.getName(), regFileId), ex);
364 this.addErrorMessage(
365 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.errMsg.errWritingTemp",
366 this.getDisplayName(), regFileName));
370 if (context.dataSourceIngestIsCancelled()) {
375 if (logFile !=
null) {
376 logFile.write(Long.toString(regFileId) +
"\t" + regFile.getUniquePath() +
"\n");
378 }
catch (TskCoreException | IOException ex) {
379 logger.log(Level.SEVERE,
null, ex);
382 logger.log(Level.INFO,
"{0}- Now getting registry information from {1}",
new Object[]{getDisplayName(), regFileNameLocal});
383 RegOutputFiles regOutputFiles = ripRegistryFile(regFileNameLocal, outputPathBase);
384 if (context.dataSourceIngestIsCancelled()) {
389 if (regOutputFiles.autopsyPlugins.isEmpty() ==
false && parseAutopsyPluginOutput(regOutputFiles.autopsyPlugins, regFile) ==
false) {
390 this.addErrorMessage(
391 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
392 this.getDisplayName(), regFileName));
395 if (context.dataSourceIngestIsCancelled()) {
400 if (!regOutputFiles.fullPlugins.isEmpty()) {
402 if (regFileNameLocal.toLowerCase().contains(
"sam") && parseSamPluginOutput(regOutputFiles.fullPlugins, regFile, ingestJobId) ==
false) {
403 this.addErrorMessage(
404 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
405 this.getDisplayName(), regFileName));
406 }
else if (regFileNameLocal.toLowerCase().contains(
"ntuser") || regFileNameLocal.toLowerCase().contains(
"usrclass")) {
408 List<ShellBag> shellbags = ShellBagParser.parseShellbagOutput(regOutputFiles.fullPlugins);
409 createShellBagArtifacts(regFile, shellbags);
410 createRecentlyUsedArtifacts(regOutputFiles.fullPlugins, regFile);
411 }
catch (IOException | TskCoreException ex) {
412 logger.log(Level.WARNING, String.format(
"Unable to get shell bags from file %s", regOutputFiles.fullPlugins), ex);
414 }
else if (regFileNameLocal.toLowerCase().contains(
"system") && parseSystemPluginOutput(regOutputFiles.fullPlugins, regFile) ==
false) {
415 this.addErrorMessage(
416 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.analyzeRegFiles.failedParsingResults",
417 this.getDisplayName(), regFileName));
420 if (context.dataSourceIngestIsCancelled()) {
425 Report report = currentCase.addReport(regOutputFiles.fullPlugins,
426 NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.parentModuleName.noSpace"),
427 "RegRipper " + regFile.getUniquePath(), regFile);
428 }
catch (TskCoreException e) {
429 this.addErrorMessage(
"Error adding regripper output as Autopsy report: " + e.getLocalizedMessage());
433 regFileNameLocalFile.delete();
440 if(allRegistryFiles.size() > 0) {
441 osInfo.createOSInfo();
445 if (logFile !=
null) {
448 }
catch (IOException ex) {
449 logger.log(Level.SEVERE,
null, ex);
460 private RegOutputFiles ripRegistryFile(String regFilePath, String outFilePathBase) {
461 String autopsyType =
"";
464 RegOutputFiles regOutputFiles =
new RegOutputFiles();
466 if (regFilePath.toLowerCase().contains(
"system")) {
467 autopsyType =
"autopsysystem";
469 }
else if (regFilePath.toLowerCase().contains(
"software")) {
470 autopsyType =
"autopsysoftware";
471 fullType =
"software";
472 }
else if (regFilePath.toLowerCase().contains(
"ntuser")) {
473 autopsyType =
"autopsyntuser";
475 }
else if (regFilePath.toLowerCase().contains(
"sam")) {
478 }
else if (regFilePath.toLowerCase().contains(
"security")) {
479 fullType =
"security";
480 }
else if (regFilePath.toLowerCase().contains(
"usrclass")) {
481 fullType =
"usrclass";
483 return regOutputFiles;
487 if (!autopsyType.isEmpty()) {
488 regOutputFiles.autopsyPlugins = outFilePathBase +
"-autopsy.txt";
489 String errFilePath = outFilePathBase +
"-autopsy.err.txt";
490 logger.log(Level.INFO,
"Writing RegRipper results to: {0}", regOutputFiles.autopsyPlugins);
491 executeRegRipper(rrCmd, rrHome, regFilePath, autopsyType, regOutputFiles.autopsyPlugins, errFilePath);
493 if (context.dataSourceIngestIsCancelled()) {
494 return regOutputFiles;
498 if (!fullType.isEmpty()) {
499 regOutputFiles.fullPlugins = outFilePathBase +
"-full.txt";
500 String errFilePath = outFilePathBase +
"-full.err.txt";
501 logger.log(Level.INFO,
"Writing Full RegRipper results to: {0}", regOutputFiles.fullPlugins);
502 executeRegRipper(rrFullCmd, rrFullHome, regFilePath, fullType, regOutputFiles.fullPlugins, errFilePath);
504 scanErrorLogs(errFilePath);
505 }
catch (IOException ex) {
506 logger.log(Level.SEVERE, String.format(
"Unable to run RegRipper on %s", regFilePath), ex);
507 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile",
this.getDisplayName(), regFilePath));
510 return regOutputFiles;
513 private void scanErrorLogs(String errFilePath)
throws IOException {
514 File regfile =
new File(errFilePath);
515 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
516 String line = reader.readLine();
517 while (line !=
null) {
519 if (line.toLowerCase().contains(
"error") || line.toLowerCase().contains(
"@inc")) {
520 logger.log(Level.WARNING,
"Regripper file {0} contains errors from run", errFilePath);
523 line = reader.readLine();
528 private void executeRegRipper(List<String> regRipperPath, Path regRipperHomeDir, String hiveFilePath, String hiveFileType, String outputFile, String errFile) {
530 List<String> commandLine =
new ArrayList<>();
531 for (String cmd : regRipperPath) {
532 commandLine.add(cmd);
534 commandLine.add(
"-r");
535 commandLine.add(hiveFilePath);
536 commandLine.add(
"-f");
537 commandLine.add(hiveFileType);
539 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
540 processBuilder.directory(regRipperHomeDir.toFile());
541 processBuilder.redirectOutput(
new File(outputFile));
542 processBuilder.redirectError(
new File(errFile));
544 }
catch (IOException ex) {
545 logger.log(Level.SEVERE, String.format(
"Error running RegRipper on %s", hiveFilePath), ex);
546 this.addErrorMessage(NbBundle.getMessage(
this.getClass(),
"ExtractRegistry.execRegRip.errMsg.failedAnalyzeRegFile",
this.getDisplayName(), hiveFilePath));
559 private boolean parseAutopsyPluginOutput(String regFilePath, AbstractFile regFile) {
560 FileInputStream fstream =
null;
561 List<BlackboardArtifact> newArtifacts =
new ArrayList<>();
565 File regfile =
new File(regFilePath);
566 fstream =
new FileInputStream(regfile);
567 String regString =
new Scanner(fstream,
"UTF-8").useDelimiter(
"\\Z").next();
568 String startdoc =
"<?xml version=\"1.0\"?><document>";
569 String result = regString.replaceAll(
"----------------------------------------",
"");
570 result = result.replaceAll(
"\\n",
"");
571 result = result.replaceAll(
"\\r",
"");
572 result = result.replaceAll(
"'",
"'");
573 result = result.replaceAll(
"&",
"&");
574 result = result.replace(
'\0',
' ');
575 String enddoc =
"</document>";
576 String stringdoc = startdoc + result + enddoc;
578 Document doc = builder.parse(
new InputSource(
new StringReader(stringdoc)));
581 Element oroot = doc.getDocumentElement();
582 NodeList children = oroot.getChildNodes();
583 int len = children.getLength();
584 for (
int i = 0; i < len; i++) {
586 if (context.dataSourceIngestIsCancelled()) {
590 Element tempnode = (Element) children.item(i);
592 String dataType = tempnode.getNodeName();
593 NodeList timenodes = tempnode.getElementsByTagName(
"mtime");
595 if (timenodes.getLength() > 0) {
596 Element timenode = (Element) timenodes.item(0);
597 String etime = timenode.getTextContent().trim();
599 if (etime !=
null && !etime.isEmpty()) {
601 mtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy", US).parse(etime).getTime();
602 String Tempdate = mtime.toString();
603 mtime = Long.valueOf(Tempdate) / MS_IN_SEC;
604 }
catch (ParseException ex) {
605 logger.log(Level.WARNING,
"Failed to parse epoch time when parsing the registry.", ex);
610 NodeList artroots = tempnode.getElementsByTagName(
"artifacts");
611 if (artroots.getLength() == 0) {
616 Element artroot = (Element) artroots.item(0);
617 NodeList myartlist = artroot.getChildNodes();
623 String systemRoot =
"";
624 String productId =
"";
625 String regOwner =
"";
627 Long installtime =
null;
628 for (
int j = 0; j < myartlist.getLength(); j++) {
629 Node artchild = myartlist.item(j);
631 if (artchild.hasAttributes()) {
632 Element artnode = (Element) artchild;
634 String value = artnode.getTextContent();
636 value = value.trim();
638 String name = artnode.getAttribute(
"name");
648 version = version +
" " + value;
656 case "RegisteredOwner":
659 case "RegisteredOrganization":
663 if (value !=
null && !value.isEmpty()) {
665 installtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyyZ", US).parse(value +
"+0000").getTime();
666 String Tempdate = installtime.toString();
667 installtime = Long.valueOf(Tempdate) / MS_IN_SEC;
668 }
catch (ParseException e) {
669 logger.log(Level.WARNING,
"RegRipper::Conversion on DateTime -> ", e);
679 osInfo.setOsName(version);
680 osInfo.setInstalltime(installtime);
681 osInfo.setSystemRoot(systemRoot);
682 osInfo.setProductId(productId);
683 osInfo.setRegOwner(regOwner);
684 osInfo.setRegOrg(regOrg);
688 String procArch =
"";
690 for (
int j = 0; j < myartlist.getLength(); j++) {
691 Node artchild = myartlist.item(j);
693 if (artchild.hasAttributes()) {
694 Element artnode = (Element) artchild;
696 String value = artnode.getTextContent().trim();
697 String name = artnode.getAttribute(
"name");
702 case "PROCESSOR_ARCHITECTURE":
705 case "PROCESSOR_IDENTIFIER":
716 osInfo.setOsName(os);
717 osInfo.setProcessorArchitecture(procArch);
718 osInfo.setTempDir(tempDir);
721 for (
int j = 0; j < myartlist.getLength(); j++) {
722 Node artchild = myartlist.item(j);
724 if (artchild.hasAttributes()) {
725 Element artnode = (Element) artchild;
727 String value = artnode.getTextContent().trim();
728 String name = artnode.getAttribute(
"name");
730 if (name.equals(
"ComputerName")) {
732 }
else if (name.equals(
"Domain")) {
738 osInfo.setCompName(compName);
739 osInfo.setDomain(domainName);
741 for (Map.Entry<String, String> userMap : getUserNameMap().entrySet()) {
744 sid = userMap.getKey();
745 String userName = userMap.getValue();
747 createOrUpdateOsAccount(regFile, sid, userName,
null,
null, OsAccountRealm.RealmScope.LOCAL);
748 }
catch (TskCoreException | TskDataException | NotUserSIDException ex) {
749 logger.log(Level.WARNING, String.format(
"Failed to update Domain for existing OsAccount: %s, sid: %s", regFile.getId(), sid), ex);
755 for (
int j = 0; j < myartlist.getLength(); j++) {
756 Node artchild = myartlist.item(j);
758 if (artchild.hasAttributes()) {
759 Element artnode = (Element) artchild;
761 String value = artnode.getTextContent().trim();
762 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
775 Long usbMtime = Long.valueOf(
"0");
776 if (!artnode.getAttribute(
"mtime").isEmpty()) {
777 usbMtime = Long.parseLong(artnode.getAttribute(
"mtime"));
779 usbMtime = Long.valueOf(usbMtime.toString());
781 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, usbMtime));
783 String dev = artnode.getAttribute(
"dev");
786 if (dev.toLowerCase().contains(
"vid")) {
787 USBInfo info = USB_MAPPER.parseAndLookup(dev);
788 if (info.getVendor() !=
null) {
789 make = info.getVendor();
791 if (info.getProduct() !=
null) {
792 model = info.getProduct();
795 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE, parentModuleName, make));
796 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL, parentModuleName, model));
797 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, value));
798 newArtifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_DEVICE_ATTACHED, regFile, bbattributes));
799 }
catch (TskCoreException ex) {
800 logger.log(Level.SEVERE, String.format(
"Error adding device_attached artifact to blackboard for file %d.", regFile.getId()), ex);
804 Long itemMtime =
null;
806 String mTimeAttr = artnode.getAttribute(
"mtime");
807 if (mTimeAttr !=
null && !mTimeAttr.isEmpty()) {
808 itemMtime =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy", US).parse(mTimeAttr).getTime();
809 itemMtime /= MS_IN_SEC;
811 }
catch (ParseException ex) {
812 logger.log(Level.SEVERE,
"Failed to parse epoch time for installed program artifact.", ex);
816 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, value));
817 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, itemMtime));
818 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_INSTALLED_PROG), bbattributes);
819 newArtifacts.add(bbart);
820 }
catch (TskCoreException ex) {
821 logger.log(Level.SEVERE,
"Error adding installed program artifact to blackboard.", ex);
825 String officeName = artnode.getAttribute(
"name");
830 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, parentModuleName, mtime));
832 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, officeName));
833 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE, parentModuleName, value));
834 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, artnode.getNodeName()));
835 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_RECENT_OBJECT), bbattributes);
837 newArtifacts.add(bbart);
838 }
catch (TskCoreException ex) {
839 logger.log(Level.SEVERE,
"Error adding recent object artifact to blackboard.", ex);
843 case "ProcessorArchitecture":
859 String homeDir = value;
860 String sid = artnode.getAttribute(
"sid");
861 String username = artnode.getAttribute(
"username");
862 String domName = domainName;
866 OsAccountRealm.RealmScope scope = OsAccountRealm.RealmScope.DOMAIN;
867 if (isDomainIdInSAMList(sid)) {
869 scope = OsAccountRealm.RealmScope.LOCAL;
873 createOrUpdateOsAccount(regFile, sid, username, homeDir, domName, scope);
874 }
catch (TskCoreException | TskDataException | NotUserSIDException ex) {
875 logger.log(Level.SEVERE, String.format(
"Failed to create OsAccount for file: %s, sid: %s", regFile.getId(), sid), ex);
879 case "NtuserNetwork":
881 String localPath = artnode.getAttribute(
"localPath");
882 String remoteName = value;
884 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LOCAL_PATH,
885 parentModuleName, localPath));
886 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REMOTE_PATH,
887 parentModuleName, remoteName));
888 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_REMOTE_DRIVE), bbattributes);
889 newArtifacts.add(bbart);
890 }
catch (TskCoreException ex) {
891 logger.log(Level.SEVERE,
"Error adding network artifact to blackboard.", ex);
895 String adapter = artnode.getAttribute(
"adapter");
897 Long lastWriteTime = Long.parseLong(artnode.getAttribute(
"writeTime"));
898 lastWriteTime = Long.valueOf(lastWriteTime.toString());
899 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SSID, parentModuleName, value));
900 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, lastWriteTime));
901 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_ID, parentModuleName, adapter));
902 BlackboardArtifact bbart = regFile.newDataArtifact(
new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_WIFI_NETWORK), bbattributes);
903 newArtifacts.add(bbart);
904 }
catch (TskCoreException ex) {
905 logger.log(Level.SEVERE,
"Error adding SSID artifact to blackboard.", ex);
915 logger.log(Level.SEVERE,
"Unrecognized node name: {0}", dataType);
924 }
catch (FileNotFoundException ex) {
925 logger.log(Level.WARNING, String.format(
"Error finding the registry file: %s", regFilePath), ex);
926 }
catch (SAXException ex) {
927 logger.log(Level.WARNING, String.format(
"Error parsing the registry XML: %s", regFilePath), ex);
928 }
catch (IOException ex) {
929 logger.log(Level.WARNING, String.format(
"Error building the document parser: %s", regFilePath), ex);
930 }
catch (ParserConfigurationException ex) {
931 logger.log(Level.WARNING, String.format(
"Error configuring the registry parser: %s", regFilePath), ex);
934 if (fstream !=
null) {
937 }
catch (IOException ex) {
940 if (!context.dataSourceIngestIsCancelled()) {
941 postArtifacts(newArtifacts);
947 private boolean parseSystemPluginOutput(String regfilePath, AbstractFile regAbstractFile) {
948 File regfile =
new File(regfilePath);
949 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
950 String line = reader.readLine();
951 while (line !=
null) {
954 if (line.toLowerCase().matches(
"^bam v.*")) {
955 parseBamKey(regAbstractFile, reader, Bundle.Registry_System_Bam());
956 }
else if (line.toLowerCase().matches(
"^bthport v..*")) {
957 parseBlueToothDevices(regAbstractFile, reader);
959 line = reader.readLine();
962 }
catch (FileNotFoundException ex) {
963 logger.log(Level.WARNING,
"Error finding the registry file.", ex);
964 }
catch (IOException ex) {
965 logger.log(Level.WARNING,
"Error reading the system hive: {0}", ex);
984 private void parseBlueToothDevices(AbstractFile regFile, BufferedReader reader)
throws FileNotFoundException, IOException {
985 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
986 String line = reader.readLine();
987 while ((line !=
null) && (!line.contains(SECTION_DIVIDER))) {
988 line = reader.readLine();
994 if ((line !=
null) && (line.toLowerCase().contains(
"device unique id"))) {
998 while (line !=
null && !line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.toLowerCase().contains(
"radio support not found")) {
999 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1000 addBlueToothAttribute(line, attributes, TSK_DEVICE_ID);
1001 line = reader.readLine();
1003 if ((line !=
null) && (line.toLowerCase().contains(
"name"))) {
1004 addBlueToothAttribute(line, attributes, TSK_NAME);
1005 line = reader.readLine();
1007 addBlueToothAttribute(line, attributes, TSK_DATETIME);
1008 line = reader.readLine();
1009 addBlueToothAttribute(line, attributes, TSK_DATETIME_ACCESSED);
1012 bbartifacts.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_BLUETOOTH_PAIRING, regFile, attributes));
1013 }
catch (TskCoreException ex) {
1014 logger.log(Level.SEVERE, String.format(
"Failed to create bluetooth_pairing artifact for file %d", regFile.getId()), ex);
1018 line = reader.readLine();
1027 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1028 postArtifacts(bbartifacts);
1032 private void addBlueToothAttribute(String line, Collection<BlackboardAttribute> attributes, ATTRIBUTE_TYPE attributeType) {
1037 String tokens[] = line.split(
": ");
1038 if (tokens.length > 1 && !tokens[1].isEmpty()) {
1039 String tokenString = tokens[1];
1040 if (attributeType.getDisplayName().toLowerCase().contains(
"date")) {
1041 String dateString = tokenString.toLowerCase().replace(
" z",
"");
1043 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"EEE MMM d HH:mm:ss yyyy", US);
1044 Long dateLong = Long.valueOf(0);
1046 Date newDate = dateFormat.parse(dateString);
1047 dateLong = newDate.getTime() / 1000;
1048 }
catch (ParseException ex) {
1051 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for Bluetooth Last Seen attribute.", dateString), ex);
1053 attributes.add(
new BlackboardAttribute(attributeType, getDisplayName(), dateLong));
1055 attributes.add(
new BlackboardAttribute(attributeType, getDisplayName(), tokenString));
1070 private boolean parseSamPluginOutput(String regFilePath, AbstractFile regAbstractFile,
long ingestJobId) {
1072 File regfile =
new File(regFilePath);
1073 List<BlackboardArtifact> newArtifacts =
new ArrayList<>();
1074 try (BufferedReader bufferedReader =
new BufferedReader(
new InputStreamReader(
new FileInputStream(regfile), StandardCharsets.UTF_8))) {
1076 String userInfoSection =
"User Information";
1077 String previousLine =
null;
1078 String line = bufferedReader.readLine();
1079 Set<Map<String, String>> userSet =
new HashSet<>();
1080 Map<String, List<String>> groupMap =
null;
1081 while (line !=
null) {
1082 if (line.contains(SECTION_DIVIDER) && previousLine !=
null && previousLine.contains(userInfoSection)) {
1083 readUsers(bufferedReader, userSet);
1086 if (line.contains(SECTION_DIVIDER) && previousLine !=
null && previousLine.contains(
"Group Membership Information")) {
1087 groupMap = readGroups(bufferedReader);
1090 previousLine = line;
1091 line = bufferedReader.readLine();
1093 Map<String, Map<String, String>> userInfoMap =
new HashMap<>();
1095 for (Map<String, String> userInfo : userSet) {
1096 String sid = userInfo.get(SID_KEY);
1097 userInfoMap.put(sid, userInfo);
1098 addSIDToSAMList(sid);
1102 OsAccountManager accountMgr = tskCase.getOsAccountManager();
1103 HostManager hostMrg = tskCase.getHostManager();
1104 Host host = hostMrg.getHostByDataSource((DataSource) dataSource);
1106 List<OsAccount> existingAccounts = accountMgr.getOsAccounts(host);
1107 for (OsAccount osAccount : existingAccounts) {
1108 Optional<String> optional = osAccount.getAddr();
1109 if (!optional.isPresent()) {
1113 String sid = optional.get();
1114 Map<String, String> userInfo = userInfoMap.remove(sid);
1115 if (userInfo !=
null) {
1116 addAccountInstance(accountMgr, osAccount, (DataSource) dataSource);
1117 updateOsAccount(osAccount, userInfo, groupMap.get(sid), regAbstractFile, ingestJobId);
1122 for (Map<String, String> userInfo : userInfoMap.values()) {
1123 OsAccount osAccount = accountMgr.newWindowsOsAccount(userInfo.get(SID_KEY),
null,
null, host, OsAccountRealm.RealmScope.LOCAL);
1124 accountMgr.newOsAccountInstance(osAccount, (DataSource) dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
1125 updateOsAccount(osAccount, userInfo, groupMap.get(userInfo.get(SID_KEY)), regAbstractFile, ingestJobId);
1128 }
catch (FileNotFoundException ex) {
1129 logger.log(Level.WARNING,
"Error finding the registry file.", ex);
1130 }
catch (IOException ex) {
1131 logger.log(Level.WARNING,
"Error building the document parser: {0}", ex);
1132 }
catch (TskDataException | TskCoreException ex) {
1133 logger.log(Level.WARNING,
"Error updating TSK_OS_ACCOUNT artifacts to include newly parsed data.", ex);
1134 }
catch (OsAccountManager.NotUserSIDException ex) {
1135 logger.log(Level.WARNING,
"Error creating OS Account, input SID is not a user SID.", ex);
1137 if (!context.dataSourceIngestIsCancelled()) {
1138 postArtifacts(newArtifacts);
1155 private void readUsers(BufferedReader bufferedReader, Set<Map<String, String>> users)
throws IOException {
1156 String line = bufferedReader.readLine();
1158 String userName =
"";
1159 String user_rid =
"";
1160 while (line !=
null && !line.contains(SECTION_DIVIDER)) {
1162 if (line.contains(USERNAME_KEY)) {
1163 String regx = USERNAME_KEY +
"\\s*?:";
1164 String userNameAndIdString = line.replaceAll(regx,
"");
1165 userName = userNameAndIdString.substring(0, userNameAndIdString.lastIndexOf(
'[')).trim();
1166 user_rid = userNameAndIdString.substring(userNameAndIdString.lastIndexOf(
'['), userNameAndIdString.lastIndexOf(
']'));
1167 }
else if (line.contains(SID_KEY) && !userName.isEmpty()) {
1168 Map.Entry<String, String> entry = getSAMKeyValue(line);
1170 HashMap<String, String> userInfo =
new HashMap<>();
1171 userInfo.put(USERNAME_KEY, userName);
1172 userInfo.put(RID_KEY, user_rid);
1173 userInfo.put(entry.getKey(), entry.getValue());
1176 line = bufferedReader.readLine();
1177 while (line !=
null && !line.isEmpty()) {
1178 entry = getSAMKeyValue(line);
1179 if (entry !=
null) {
1180 userInfo.put(entry.getKey(), entry.getValue());
1182 line = bufferedReader.readLine();
1184 users.add(userInfo);
1188 line = bufferedReader.readLine();
1201 private void createRecentlyUsedArtifacts(String regFileName, AbstractFile regFile)
throws FileNotFoundException, IOException {
1202 File regfile =
new File(regFileName);
1203 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
1204 String line = reader.readLine();
1205 while (line !=
null) {
1208 if (line.matches(
"^adobe v.*")) {
1209 parseAdobeMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Adobe());
1210 }
else if (line.matches(
"^mpmru v.*")) {
1211 parseMediaPlayerMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Mediaplayer());
1212 }
else if (line.matches(
"^ArcHistory:")) {
1213 parse7ZipMRU(regFile, reader, Bundle.Recently_Used_Artifacts_ArcHistory());
1214 }
else if (line.matches(
"^applets v.*")) {
1215 parseGenericMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Applets());
1216 }
else if (line.matches(
"^mmc v.*")) {
1217 parseGenericMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Mmc());
1218 }
else if (line.matches(
"^winrar v.*")) {
1219 parseWinRARMRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Winrar());
1220 }
else if (line.matches(
"^msoffice v.*")) {
1221 parseOfficeDocs2010MRUList(regFile, reader, Bundle.Recently_Used_Artifacts_Officedocs());
1222 }
else if (line.matches(
"^lxss v.*")) {
1223 parseWSL(regFile, reader, Bundle.Recently_Used_Artifacts_WSL());
1225 line = reader.readLine();
1241 private void parseBamKey(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1242 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1243 String line = reader.readLine();
1245 while (!line.contains(SECTION_DIVIDER)) {
1246 line = reader.readLine();
1249 line = reader.readLine();
1251 while (!line.contains(SECTION_DIVIDER)) {
1254 String tokens[] = line.split(
"\\|");
1255 Long progRunDateTime = Long.valueOf(tokens[0]);
1258 String fileNameSid[] = tokens[4].split(
"\\s+\\(S-");
1259 String userSid =
"S-" + fileNameSid[1].substring(0, fileNameSid[1].length() - 1);
1260 String userName = getUserNameMap().get(userSid);
1261 if (userName ==
null) {
1264 String fileName = fileNameSid[0];
1265 if (fileName.startsWith(
"\\Device\\HarddiskVolume")) {
1267 int fileNameStart = fileName.indexOf(
'\\', 16);
1268 fileName = fileName.substring(fileNameStart, fileName.length());
1271 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1272 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, getDisplayName(), fileName));
1273 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USER_NAME, getDisplayName(), userName));
1274 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, getDisplayName(), progRunDateTime));
1275 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, getDisplayName(), comment));
1278 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_PROG_RUN, regFile, attributes);
1279 bbartifacts.add(bba);
1280 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1282 bbartifacts.add(bba);
1284 }
catch (TskCoreException ex) {
1285 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_PROG_RUN artifact for file %d", regFile.getId()), ex);
1287 line = reader.readLine();
1289 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1290 postArtifacts(bbartifacts);
1305 private void parseAdobeMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1306 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1307 String line = reader.readLine();
1308 SimpleDateFormat adobePluginDateFormat =
new SimpleDateFormat(
"yyyyMMddHHmmssZ", US);
1309 Long adobeUsedTime = Long.valueOf(0);
1310 while (!line.contains(SECTION_DIVIDER)) {
1311 line = reader.readLine();
1313 if (line.matches(
"^Key name,file name,sDate,uFileSize,uPageCount")) {
1314 line = reader.readLine();
1317 while (!line.contains(SECTION_DIVIDER) && !line.isEmpty()) {
1320 String tokens[] = line.split(
",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
1321 String fileName = tokens[1].substring(0, tokens[1].length() - 1);
1322 fileName = fileName.replace(
"\"",
"");
1323 if (fileName.charAt(0) ==
'/') {
1324 fileName = fileName.substring(1, fileName.length() - 1);
1325 fileName = fileName.replaceFirst(
"/",
":/");
1328 if (tokens.length > 2) {
1331 String fileUsedTime = tokens[2].replaceAll(
"'",
"");
1332 Date usedDate = adobePluginDateFormat.parse(fileUsedTime);
1333 adobeUsedTime = usedDate.getTime() / 1000;
1334 }
catch (ParseException ex) {
1337 logger.log(Level.WARNING, String.format(
"Failed to parse date/time %s for adobe file artifact.", tokens[2]), ex);
1340 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1341 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1342 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, getDisplayName(), adobeUsedTime));
1343 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1345 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1347 bbartifacts.add(bba);
1348 fileName = fileName.replace(
"\0",
"");
1349 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1351 bbartifacts.add(bba);
1354 }
catch (TskCoreException ex) {
1355 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1357 line = reader.readLine();
1362 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1363 postArtifacts(bbartifacts);
1379 private void parseMediaPlayerMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1380 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1381 String line = reader.readLine();
1382 while (!line.contains(SECTION_DIVIDER)) {
1383 line = reader.readLine();
1385 if (line.contains(
"LastWrite")) {
1386 line = reader.readLine();
1389 while (!line.contains(SECTION_DIVIDER) && !line.contains(
"RecentFileList has no values.")) {
1391 String tokens[] = line.split(
"> ");
1392 String fileName = tokens[1];
1393 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1394 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1395 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1397 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1399 bbartifacts.add(bba);
1400 bba = createAssociatedArtifact(fileName, bba);
1402 bbartifacts.add(bba);
1403 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1405 bbartifacts.add(bba);
1409 }
catch (TskCoreException ex) {
1410 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1412 line = reader.readLine();
1417 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1418 postArtifacts(bbartifacts);
1434 private void parseGenericMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1435 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1436 String line = reader.readLine();
1437 while (!line.contains(SECTION_DIVIDER)) {
1438 line = reader.readLine();
1440 if (line.contains(
"LastWrite")) {
1441 line = reader.readLine();
1444 while (!line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains(
"Applets")
1445 && !line.contains((
"Recent File List"))) {
1447 String tokens[] = line.split(
"> ");
1448 if (tokens.length > 1) {
1449 String fileName = tokens[1];
1450 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1451 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1452 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1454 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1456 bbartifacts.add(bba);
1457 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1459 bbartifacts.add(bba);
1462 }
catch (TskCoreException ex) {
1463 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1466 line = reader.readLine();
1471 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1472 postArtifacts(bbartifacts);
1488 private void parseWinRARMRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1489 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1490 String line = reader.readLine();
1491 while (!line.contains(SECTION_DIVIDER)) {
1492 line = reader.readLine();
1494 if (line.contains(
"LastWrite")) {
1495 line = reader.readLine();
1498 if (!line.isEmpty()) {
1499 while (!line.contains(SECTION_DIVIDER)) {
1501 String tokens[] = line.split(
"> ");
1502 String fileName = tokens[1];
1503 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1504 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1505 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1507 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1508 bbartifacts.add(bba);
1509 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1511 bbartifacts.add(bba);
1513 }
catch (TskCoreException ex) {
1514 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1516 line = reader.readLine();
1522 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1523 postArtifacts(bbartifacts);
1539 private void parse7ZipMRU(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1540 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1541 String line = reader.readLine();
1543 if (!line.contains(
"PathHistory:")) {
1544 while (!line.contains(
"PathHistory:") && !line.isEmpty()) {
1547 String fileName = line;
1548 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1549 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1550 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1552 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1553 bbartifacts.add(bba);
1554 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1556 bbartifacts.add(bba);
1559 }
catch (TskCoreException ex) {
1560 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1562 line = reader.readLine();
1566 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1567 postArtifacts(bbartifacts);
1583 private void parseOfficeDocs2010MRUList(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1584 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1585 String line = reader.readLine();
1589 while (!line.contains(SECTION_DIVIDER)) {
1590 line = reader.readLine();
1592 line = reader.readLine();
1593 while (!line.contains(SECTION_DIVIDER)) {
1596 String tokens[] = line.split(
"\\|");
1597 Long docDate = Long.valueOf(tokens[0]);
1598 String fileNameTokens[] = tokens[4].split(
" - ");
1599 if (fileNameTokens[0].contains(
"MSOffice LastLoginTime")) {
1600 line = reader.readLine();
1605 if (fileNameTokens.length > 2) {
1606 fileName = fileNameTokens[2];
1608 fileName = fileNameTokens[1];
1610 if (line.contains(
" MRU ")) {
1611 comment = Bundle.Recently_Used_Artifacts_Officedocs();
1613 comment = Bundle.Recently_Used_Artifacts_Office_Trustrecords();
1615 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1616 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), fileName));
1617 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, getDisplayName(), docDate));
1618 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1620 BlackboardArtifact bba = createArtifactWithAttributes(BlackboardArtifact.Type.TSK_RECENT_OBJECT, regFile, attributes);
1621 bbartifacts.add(bba);
1622 bba = createAssociatedArtifact(FilenameUtils.normalize(fileName,
true), bba);
1624 bbartifacts.add(bba);
1626 }
catch (TskCoreException ex) {
1627 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1629 line = reader.readLine();
1632 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1633 postArtifacts(bbartifacts);
1649 private void parseWSL(AbstractFile regFile, BufferedReader reader, String comment)
throws FileNotFoundException, IOException {
1650 List<BlackboardArtifact> bbartifacts =
new ArrayList<>();
1651 String line = reader.readLine();
1655 while (!line.contains(SECTION_DIVIDER)) {
1656 line = reader.readLine();
1658 line = reader.readLine();
1659 while (!line.contains(SECTION_DIVIDER)) {
1662 String tokens[] = line.split(
"\\|");
1663 Long docDate = Long.valueOf(tokens[0]);
1664 String fileNameTokens[] = tokens[4].split(
" - ");
1665 String filePath =
"";
1666 String imagePath =
"";
1668 String kernalCommand;
1669 if (fileNameTokens.length > 3) {
1670 distro = fileNameTokens[1].replaceFirst(
" ",
"");
1671 filePath = fileNameTokens[2];
1672 imagePath = fileNameTokens[2] +
"\\ext4.vhdx";
1673 kernalCommand = fileNameTokens[3];
1675 distro = fileNameTokens[1].replaceFirst(
" ",
"");
1676 filePath = fileNameTokens[2];
1677 imagePath = fileNameTokens[2] +
"\\ext4.vhdx";
1680 comment = Bundle.Recently_Used_Artifacts_WSL();
1681 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1684 attributes.add(
new BlackboardAttribute(TSK_NAME, getDisplayName(), distro));
1685 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), imagePath));
1686 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED, getDisplayName(), docDate));
1687 attributes.add(
new BlackboardAttribute(getKernalCommandAttribute(), getDisplayName(), kernalCommand));
1688 attributes.add(
new BlackboardAttribute(TSK_COMMENT, getDisplayName(), comment));
1689 BlackboardArtifact.Type wslArtifact = getWSLArtifact();
1690 BlackboardArtifact bba = createArtifactWithAttributes(wslArtifact, regFile, attributes);
1691 bbartifacts.add(bba);
1692 }
catch (TskCoreException ex) {
1693 logger.log(Level.SEVERE, String.format(
"Failed to create TSK_RECENT_OBJECT artifact for file %d", regFile.getId()), ex);
1695 line = reader.readLine();
1698 if (!bbartifacts.isEmpty() && !context.dataSourceIngestIsCancelled()) {
1699 postArtifacts(bbartifacts);
1713 private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) {
1714 String fileName = FilenameUtils.getName(filePathName);
1715 String filePath = FilenameUtils.getPath(filePathName);
1716 List<AbstractFile> sourceFiles;
1718 sourceFiles = currentCase.getSleuthkitCase().getFileManager().findFilesExactNameExactPath(dataSource, fileName, filePath);
1719 if (!sourceFiles.isEmpty()) {
1720 return createAssociatedArtifact(sourceFiles.get(0), bba);
1722 }
catch (TskCoreException ex) {
1725 logger.log(Level.WARNING, String.format(
"Error finding actual file %s. file may not exist", filePathName));
1741 private Map<String, String> makeUserNameMap(Content dataSource)
throws TskCoreException {
1742 Map<String, String> map =
new HashMap<>();
1744 for (OsAccount account : tskCase.getOsAccountManager().getOsAccounts(((DataSource) dataSource).getHost())) {
1745 Optional<String> userName = account.getLoginName();
1746 String address = account.getAddr().orElse(
"");
1747 if (!address.isEmpty()) {
1748 map.put(address, userName.isPresent() ? userName.get() :
"");
1774 private String stripRelativeIdentifierFromSID(String osAccountSID) {
1775 if (osAccountSID.split(
"-").length > 4) {
1776 int index = osAccountSID.lastIndexOf(
'-');
1777 return index > 1 ? osAccountSID.substring(0, index) :
"";
1782 private final List<String> machineSIDs =
new ArrayList<>();
1789 private Map<String, String> getUserNameMap() {
1790 if (userNameMap ==
null) {
1794 userNameMap = makeUserNameMap(dataSource);
1795 }
catch (TskCoreException ex) {
1796 logger.log(Level.WARNING,
"Unable to create OS Account user name map", ex);
1799 userNameMap =
new HashMap<>();
1816 private BlackboardAttribute getAttributeForArtifact(BlackboardArtifact artifact, BlackboardAttribute.ATTRIBUTE_TYPE type)
throws TskCoreException {
1817 return artifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(type.getTypeID())));
1828 void createShellBagArtifacts(AbstractFile regFile, List<ShellBag> shellbags)
throws TskCoreException {
1829 List<BlackboardArtifact> artifacts =
new ArrayList<>();
1831 for (ShellBag bag : shellbags) {
1832 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
1833 attributes.add(
new BlackboardAttribute(TSK_PATH, getDisplayName(), bag.getResource()));
1834 attributes.add(
new BlackboardAttribute(getKeyAttribute(), getDisplayName(), bag.getKey()));
1837 time = bag.getLastWrite();
1839 attributes.add(
new BlackboardAttribute(getLastWriteAttribute(), getDisplayName(), time));
1842 time = bag.getModified();
1844 attributes.add(
new BlackboardAttribute(TSK_DATETIME_MODIFIED, getDisplayName(), time));
1847 time = bag.getCreated();
1849 attributes.add(
new BlackboardAttribute(TSK_DATETIME_CREATED, getDisplayName(), time));
1852 time = bag.getAccessed();
1854 attributes.add(
new BlackboardAttribute(TSK_DATETIME_ACCESSED, getDisplayName(), time));
1857 BlackboardArtifact artifact = createArtifactWithAttributes(getShellBagArtifact(), regFile, attributes);
1858 artifacts.add(artifact);
1861 if (!context.dataSourceIngestIsCancelled()) {
1862 postArtifacts(artifacts);
1875 private BlackboardArtifact.Type getShellBagArtifact() throws TskCoreException {
1876 if (shellBagArtifactType ==
null) {
1878 shellBagArtifactType = tskCase.getBlackboard().getOrAddArtifactType(SHELLBAG_ARTIFACT_NAME, Bundle.Shellbag_Artifact_Display_Name());
1879 }
catch (BlackboardException ex) {
1880 throw new TskCoreException(String.format(
"Failed to get shell bag artifact type", SHELLBAG_ARTIFACT_NAME), ex);
1884 return shellBagArtifactType;
1895 private BlackboardArtifact.Type getWSLArtifact() throws TskCoreException {
1896 if (wslArtifactType ==
null) {
1898 wslArtifactType = tskCase.getBlackboard().getOrAddArtifactType(WSL_ARTIFACT_NAME, Bundle.WSL_Artifact_Display_Name());
1899 }
catch (BlackboardException ex) {
1900 throw new TskCoreException(String.format(
"Failed to get WSL artifact type", WSL_ARTIFACT_NAME), ex);
1904 return wslArtifactType;
1915 private BlackboardAttribute.Type getKernalCommandAttribute() throws TskCoreException {
1916 if (kernalCommandAttributeType ==
null) {
1918 kernalCommandAttributeType = tskCase.getBlackboard().getOrAddAttributeType(WSL_ATTRIBUTE_KERNAL_COMMAND,
1919 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
1920 Bundle.WSL_Kernal_Command_Attribute_Display_Name());
1921 }
catch (BlackboardException ex) {
1923 throw new TskCoreException(String.format(
"Failed to get custom attribute %s", WSL_ATTRIBUTE_KERNAL_COMMAND), ex);
1926 return kernalCommandAttributeType;
1937 private BlackboardAttribute.Type getLastWriteAttribute() throws TskCoreException {
1938 if (shellBagLastWriteAttributeType ==
null) {
1940 shellBagLastWriteAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SHELLBAG_ATTRIBUTE_LAST_WRITE,
1941 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME,
1942 Bundle.Shellbag_Last_Write_Attribute_Display_Name());
1943 }
catch (BlackboardException ex) {
1945 throw new TskCoreException(String.format(
"Failed to get custom attribute %s", SHELLBAG_ATTRIBUTE_LAST_WRITE), ex);
1948 return shellBagLastWriteAttributeType;
1959 private BlackboardAttribute.Type getKeyAttribute() throws TskCoreException {
1960 if (shellBagKeyAttributeType ==
null) {
1962 shellBagKeyAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SHELLBAG_ATTRIBUTE_KEY,
1963 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
1964 Bundle.Shellbag_Key_Attribute_Display_Name());
1965 }
catch (BlackboardException ex) {
1966 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SHELLBAG_ATTRIBUTE_KEY), ex);
1969 return shellBagKeyAttributeType;
1981 Map<String, List<String>> readGroups(BufferedReader bufferedReader)
throws IOException {
1982 Map<String, List<String>> groupMap =
new HashMap<>();
1984 String line = bufferedReader.readLine();
1987 String groupName =
null;
1989 while (line !=
null && !line.contains(SECTION_DIVIDER)) {
1991 if (line.contains(
"Group Name")) {
1992 String value = line.replaceAll(
"Group Name\\s*?:",
"").trim();
1993 groupName = (value.replaceAll(
"\\[\\d*?\\]",
"")).trim();
1994 int startIndex = value.indexOf(
" [") + 1;
1995 int endIndex = value.indexOf(
']');
1997 if (startIndex != -1 && endIndex != -1) {
1998 String countStr = value.substring(startIndex + 1, endIndex);
1999 userCount = Integer.parseInt(countStr);
2001 }
else if (line.matches(
"Users\\s*?:")) {
2002 for (
int i = 0; i < userCount; i++) {
2003 line = bufferedReader.readLine();
2005 String sid = line.trim();
2006 List<String> groupList = groupMap.get(sid);
2007 if (groupList ==
null) {
2008 groupList =
new ArrayList<>();
2009 groupMap.put(sid, groupList);
2011 groupList.add(groupName);
2016 line = bufferedReader.readLine();
2029 private Map.Entry<String, String> getSAMKeyValue(String line) {
2030 int index = line.indexOf(
':');
2031 Map.Entry<String, String> returnValue =
null;
2033 String value =
null;
2036 key = line.substring(0, index).trim();
2037 if (index + 1 < line.length()) {
2038 value = line.substring(index + 1).trim();
2043 }
else if (line.contains(
"-->")) {
2044 key = line.replace(
"-->",
"").trim();
2049 returnValue =
new AbstractMap.SimpleEntry<>(key, value);
2057 this.dataSource = dataSource;
2059 progressBar.progress(Bundle.Progress_Message_Analyze_Registry());
2060 analyzeRegistryFiles(context.getJobId());
2084 private void createOrUpdateOsAccount(AbstractFile file, String sid, String userName, String homeDir, String domainName, OsAccountRealm.RealmScope realmScope)
throws TskCoreException, TskDataException, NotUserSIDException {
2085 OsAccountManager accountMgr = tskCase.getOsAccountManager();
2086 HostManager hostMrg = tskCase.getHostManager();
2087 Host host = hostMrg.getHostByDataSource((DataSource) dataSource);
2089 Optional<OsAccount> optional = accountMgr.getWindowsOsAccount(sid,
null,
null, host);
2090 OsAccount osAccount;
2091 if (!optional.isPresent()) {
2092 osAccount = accountMgr.newWindowsOsAccount(sid, userName !=
null && userName.isEmpty() ?
null : userName, domainName, host, realmScope);
2093 accountMgr.newOsAccountInstance(osAccount, (DataSource) dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
2095 osAccount = optional.get();
2096 addAccountInstance(accountMgr, osAccount, (DataSource) dataSource);
2097 if (userName !=
null && !userName.isEmpty()) {
2098 OsAccountUpdateResult updateResult = accountMgr.updateCoreWindowsOsAccountAttributes(osAccount,
null, userName, (domainName ==
null || domainName.isEmpty()) ?
null : domainName, host);
2099 osAccount = updateResult.getUpdatedAccount().orElse(osAccount);
2103 if (homeDir !=
null && !homeDir.isEmpty()) {
2104 List<OsAccountAttribute> attributes =
new ArrayList<>();
2105 String dir = homeDir.replaceFirst(
"^(%\\w*%)",
"");
2106 dir = dir.replace(
"\\",
"/");
2107 attributes.add(createOsAccountAttribute(TSK_HOME_DIR, dir, osAccount, host, file));
2108 accountMgr.addExtendedOsAccountAttributes(osAccount, attributes);
2120 private void addEmailAccount(AbstractFile regFile, String emailAddress,
long ingestJobId) {
2122 currentCase.getSleuthkitCase()
2123 .getCommunicationsManager()
2124 .createAccountFileInstance(Account.Type.EMAIL,
2125 emailAddress, getRAModuleName(), regFile,
2126 Collections.emptyList(),
2128 }
catch (TskCoreException ex) {
2129 logger.log(Level.SEVERE,
2130 String.format(
"Error adding email account with value "
2131 +
"%s, to the case database for file %s [objId=%d]",
2132 emailAddress, regFile.getName(), regFile.getId()), ex);
2144 private Long parseRegRipTime(String value) {
2146 return REG_RIPPER_TIME_FORMAT.parse(value).getTime() / MS_IN_SEC;
2147 }
catch (ParseException ex) {
2148 logger.log(Level.SEVERE, String.format(
"Failed to parse reg rip time: %s", value));
2165 private void updateOsAccount(OsAccount osAccount, Map<String, String> userInfo, List<String> groupList, AbstractFile regFile,
long ingestJobId)
throws TskDataException, TskCoreException, NotUserSIDException {
2166 Host host = ((DataSource) dataSource).getHost();
2167 SimpleDateFormat regRipperTimeFormat =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyy 'Z'", US);
2168 regRipperTimeFormat.setTimeZone(getTimeZone(
"GMT"));
2170 List<OsAccountAttribute> attributes =
new ArrayList<>();
2172 Long creationTime =
null;
2174 String value = userInfo.get(ACCOUNT_CREATED_KEY);
2175 if (value !=
null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2176 creationTime = parseRegRipTime(value);
2179 value = userInfo.get(LAST_LOGIN_KEY);
2180 if (value !=
null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2181 Long time = parseRegRipTime(value);
2183 attributes.add(createOsAccountAttribute(TSK_DATETIME_ACCESSED,
2184 parseRegRipTime(value),
2185 osAccount, host, regFile));
2189 String loginName =
null;
2190 value = userInfo.get(USERNAME_KEY);
2191 if (value !=
null && !value.isEmpty()) {
2195 value = userInfo.get(LOGIN_COUNT_KEY);
2196 if (value !=
null && !value.isEmpty()) {
2197 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_COUNT,
2198 Integer.parseInt(value),
2199 osAccount, host, regFile));
2205 value = userInfo.get(ACCOUNT_TYPE_KEY);
2206 if (value !=
null && !value.isEmpty() && value.toLowerCase().contains(
"admin")) {
2207 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_IS_ADMIN,
2208 1, osAccount, host, regFile));
2211 value = userInfo.get(USER_COMMENT_KEY);
2212 if (value !=
null && !value.isEmpty()) {
2213 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_DESCRIPTION,
2214 value, osAccount, host, regFile));
2217 value = userInfo.get(INTERNET_NAME_KEY);
2218 if (value !=
null && !value.isEmpty()) {
2219 addEmailAccount(regFile, value, ingestJobId);
2221 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_EMAIL,
2222 value, osAccount, host, regFile));
2226 String fullName =
null;
2227 value = userInfo.get(FULL_NAME_KEY);
2228 if (value !=
null && !value.isEmpty()) {
2231 value = userInfo.get(NAME_KEY);
2232 if (value !=
null && !value.isEmpty()) {
2237 value = userInfo.get(PWD_RESET_KEY);
2238 if (value !=
null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2239 Long time = parseRegRipTime(value);
2241 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_RESET,
2242 time, osAccount, host, regFile));
2246 value = userInfo.get(SECURITY_QUESTION_1);
2247 if (value !=
null && !value.isEmpty()) {
2248 BlackboardAttribute.Type securityQuestionAttributeType =
null;
2250 securityQuestionAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_QUESTION_1,
2251 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2252 Bundle.Sam_Security_Question_1_Attribute_Display_Name());
2253 }
catch (BlackboardException ex) {
2254 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_QUESTION_1), ex);
2256 attributes.add(createOsAccountAttribute(securityQuestionAttributeType, value, osAccount, host, regFile));
2259 value = userInfo.get(SECURITY_ANSWER_1);
2260 if (value !=
null && !value.isEmpty()) {
2261 BlackboardAttribute.Type securityAnswerAttributeType =
null;
2263 securityAnswerAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_ANSWER_1,
2264 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2265 Bundle.Sam_Security_Answer_1_Attribute_Display_Name());
2266 }
catch (BlackboardException ex) {
2267 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_ANSWER_1), ex);
2269 attributes.add(createOsAccountAttribute(securityAnswerAttributeType, value, osAccount, host, regFile));
2272 value = userInfo.get(SECURITY_QUESTION_2);
2273 if (value !=
null && !value.isEmpty()) {
2274 BlackboardAttribute.Type securityQuestionAttributeType =
null;
2276 securityQuestionAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_QUESTION_2,
2277 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2278 Bundle.Sam_Security_Question_2_Attribute_Display_Name());
2279 }
catch (BlackboardException ex) {
2280 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_QUESTION_2), ex);
2282 attributes.add(createOsAccountAttribute(securityQuestionAttributeType, value, osAccount, host, regFile));
2285 value = userInfo.get(SECURITY_ANSWER_2);
2286 if (value !=
null && !value.isEmpty()) {
2287 BlackboardAttribute.Type securityAnswerAttributeType =
null;
2289 securityAnswerAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_ANSWER_2,
2290 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2291 Bundle.Sam_Security_Answer_2_Attribute_Display_Name());
2292 }
catch (BlackboardException ex) {
2293 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_ANSWER_2), ex);
2295 attributes.add(createOsAccountAttribute(securityAnswerAttributeType, value, osAccount, host, regFile));
2298 value = userInfo.get(SECURITY_QUESTION_3);
2299 if (value !=
null && !value.isEmpty()) {
2300 BlackboardAttribute.Type securityQuestionAttributeType =
null;
2302 securityQuestionAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_QUESTION_3,
2303 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2304 Bundle.Sam_Security_Question_2_Attribute_Display_Name());
2305 }
catch (BlackboardException ex) {
2306 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_QUESTION_3), ex);
2308 attributes.add(createOsAccountAttribute(securityQuestionAttributeType, value, osAccount, host, regFile));
2311 value = userInfo.get(SECURITY_ANSWER_3);
2312 if (value !=
null && !value.isEmpty()) {
2313 BlackboardAttribute.Type securityAnswerAttributeType =
null;
2315 securityAnswerAttributeType = tskCase.getBlackboard().getOrAddAttributeType(SAM_SECURITY_ANSWER_3,
2316 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING,
2317 Bundle.Sam_Security_Answer_3_Attribute_Display_Name());
2318 }
catch (BlackboardException ex) {
2319 throw new TskCoreException(String.format(
"Failed to get key attribute %s", SAM_SECURITY_ANSWER_3), ex);
2321 attributes.add(createOsAccountAttribute(securityAnswerAttributeType, value, osAccount, host, regFile));
2324 value = userInfo.get(PASSWORD_HINT);
2325 if (value !=
null && !value.isEmpty()) {
2326 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_HINT,
2327 value, osAccount, host, regFile));
2330 value = userInfo.get(PWD_FAILE_KEY);
2331 if (value !=
null && !value.isEmpty() && !value.equals(NEVER_DATE)) {
2332 Long time = parseRegRipTime(value);
2334 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_DATETIME_PASSWORD_FAIL,
2335 time, osAccount, host, regFile));
2339 String settingString = getSettingsFromMap(PASSWORD_SETTINGS_FLAGS, userInfo);
2340 if (!settingString.isEmpty()) {
2341 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_PASSWORD_SETTINGS,
2342 settingString, osAccount, host, regFile));
2345 settingString = getSettingsFromMap(ACCOUNT_SETTINGS_FLAGS, userInfo);
2346 if (!settingString.isEmpty()) {
2347 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_ACCOUNT_SETTINGS,
2348 settingString, osAccount, host, regFile));
2351 settingString = getSettingsFromMap(ACCOUNT_TYPE_FLAGS, userInfo);
2352 if (!settingString.isEmpty()) {
2353 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_FLAG,
2354 settingString, osAccount, host, regFile));
2357 if (groupList !=
null && groupList.isEmpty()) {
2358 String groups = groupList.stream()
2359 .map(String::valueOf)
2360 .collect(Collectors.joining(
", "));
2362 attributes.add(createOsAccountAttribute(ATTRIBUTE_TYPE.TSK_GROUPS,
2363 groups, osAccount, host, regFile));
2367 OsAccountManager accountMgr = tskCase.getOsAccountManager();
2368 accountMgr.addExtendedOsAccountAttributes(osAccount, attributes);
2371 accountMgr.updateCoreWindowsOsAccountAttributes(osAccount,
null, loginName,
null, host);
2374 accountMgr.updateStandardOsAccountAttributes(osAccount, fullName,
null,
null, creationTime);
2386 private String getSettingsFromMap(String[] keys, Map<String, String> map) {
2387 List<String> settingsList =
new ArrayList<>();
2388 for (String setting : keys) {
2389 if (map.containsKey(setting)) {
2390 settingsList.add(setting);
2394 if (!settingsList.isEmpty()) {
2395 return settingsList.stream()
2396 .map(String::valueOf)
2397 .collect(Collectors.joining(
", "));
2414 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.Type type, String value, OsAccount osAccount, Host host, AbstractFile file) {
2415 return osAccount.new OsAccountAttribute(type, value, osAccount, host, file);
2429 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.ATTRIBUTE_TYPE type, String value, OsAccount osAccount, Host host, AbstractFile file) {
2430 return osAccount.new OsAccountAttribute(
new BlackboardAttribute.Type(type), value, osAccount, host, file);
2444 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.ATTRIBUTE_TYPE type, Long value, OsAccount osAccount, Host host, AbstractFile file) {
2445 return osAccount.new OsAccountAttribute(
new BlackboardAttribute.Type(type), value, osAccount, host, file);
2459 private OsAccountAttribute createOsAccountAttribute(BlackboardAttribute.ATTRIBUTE_TYPE type, Integer value, OsAccount osAccount, Host host, AbstractFile file) {
2460 return osAccount.new OsAccountAttribute(
new BlackboardAttribute.Type(type), value, osAccount, host, file);
2473 private void addAccountInstance(OsAccountManager accountMgr, OsAccount osAccount, DataSource dataSource)
throws TskCoreException {
2474 accountMgr.newOsAccountInstance(osAccount, dataSource, OsAccountInstance.OsAccountInstanceType.LAUNCHED);
2482 private void addSIDToSAMList(String sid) {
2483 String relativeID = stripRelativeIdentifierFromSID(sid);
2484 if (!relativeID.isEmpty() && !samDomainIDsList.contains(relativeID)) {
2485 samDomainIDsList.add(relativeID);
2497 private boolean isDomainIdInSAMList(String osAccountSID) {
2498 String relativeID = stripRelativeIdentifierFromSID(osAccountSID);
2499 return samDomainIDsList.contains(relativeID);
2518 void createOSInfo() {
2521 ArrayList<BlackboardArtifact> results = tskCase.getBlackboardArtifacts(ARTIFACT_TYPE.TSK_OS_INFO, context.getDataSource().getId());
2523 if (results.isEmpty()) {
2524 Collection<BlackboardAttribute> bbattributes =
new ArrayList<>();
2525 if (compName !=
null && !compName.isEmpty()) {
2526 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME, parentModuleName, compName));
2528 if (domain !=
null && !domain.isEmpty()) {
2529 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN, parentModuleName, domain));
2531 if (progName !=
null && !progName.isEmpty()) {
2532 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME, parentModuleName, progName));
2534 if (processorArchitecture !=
null && !processorArchitecture.isEmpty()) {
2535 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROCESSOR_ARCHITECTURE, parentModuleName, processorArchitecture));
2537 if (tempDir !=
null && !tempDir.isEmpty()) {
2538 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_TEMP_DIR, parentModuleName, tempDir));
2540 if (installtime !=
null) {
2541 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME, parentModuleName, installtime));
2543 if (systemRoot !=
null && !systemRoot.isEmpty()) {
2544 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH, parentModuleName, systemRoot));
2546 if (productId !=
null && !productId.isEmpty()) {
2547 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PRODUCT_ID, parentModuleName, productId));
2549 if (regOwner !=
null && !regOwner.isEmpty()) {
2550 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_OWNER, parentModuleName, regOwner));
2552 if (regOrg !=
null && !regOrg.isEmpty()) {
2553 bbattributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ORGANIZATION, parentModuleName, regOrg));
2556 postArtifact(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_OS_INFO, context.getDataSource(), bbattributes));
2558 }
catch (TskCoreException ex) {
2559 logger.log(Level.SEVERE,
"Failed to create default OS_INFO artifact", ex);
2563 void setCompName(String compName) {
2564 if(this.compName ==
null || this.compName.isEmpty()) {
2565 this.compName = compName;
2569 void setOsName(String progName) {
2570 if(progName !=
null && !progName.isEmpty()) {
2571 this.progName = progName;
2575 void setProcessorArchitecture(String processorArchitecture) {
2576 if(this.processorArchitecture ==
null || this.processorArchitecture.isEmpty()) {
2577 this.processorArchitecture = processorArchitecture;
2581 void setTempDir(String tempDir) {
2582 if(this.tempDir ==
null || this.tempDir.isEmpty()) {
2583 this.tempDir = tempDir;
2587 void setDomain(String domain) {
2588 if(this.domain ==
null || this.domain.isEmpty()) {
2589 this.domain = domain;
2593 void setInstalltime(Long installtime) {
2594 if(this.domain ==
null) {
2595 this.installtime = installtime;
2599 void setSystemRoot(String systemRoot) {
2600 if(this.systemRoot ==
null || this.systemRoot.isEmpty()) {
2601 this.systemRoot = systemRoot;
2605 void setProductId(String productId) {
2606 if(this.productId ==
null || this.productId.isEmpty()) {
2607 this.productId = productId;
2611 void setRegOwner(String regOwner) {
2612 if(this.regOwner ==
null || this.regOwner.isEmpty()) {
2613 this.regOwner = regOwner;
2617 void setRegOrg(String regOrg) {
2618 if(this.regOrg ==
null || this.regOrg.isEmpty()) {
2619 this.regOrg = regOrg;
List< AbstractFile > findFiles(String fileName)
static int execute(ProcessBuilder processBuilder)
synchronized static Logger getLogger(String name)
static DocumentBuilder getDocumentBuilder()
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)