Autopsy  4.19.3
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractWebAccountType.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2020-2021 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.recentactivity;
20 
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Collection;
26 import java.util.List;
27 import java.util.Objects;
28 import java.util.logging.Level;
29 import org.openide.util.NbBundle;
33 import org.sleuthkit.datamodel.AbstractFile;
34 import org.sleuthkit.datamodel.BlackboardArtifact;
35 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
36 import org.sleuthkit.datamodel.BlackboardAttribute;
37 import org.sleuthkit.datamodel.Content;
38 import org.sleuthkit.datamodel.TskCoreException;
39 
43 class ExtractWebAccountType extends Extract {
44 
45  private static final Logger logger = Logger.getLogger(ExtractWebAccountType.class.getName());
46  private final IngestJobContext context;
47 
48  ExtractWebAccountType(IngestJobContext context) {
49  super(NbBundle.getMessage(ExtractWebAccountType.class, "ExtractWebAccountType.moduleName.text"), context);
50  this.context = context;
51  }
52 
53  private static final List<BlackboardArtifact.Type> QUERY_ARTIFACTS = Arrays.asList(
54  new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY),
55  new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT)
56  );
57 
58  private void extractDomainRoles(Content dataSource) {
59  try {
60  // Get web history blackboard artifacts
61  Collection<BlackboardArtifact> listArtifacts = currentCase.getSleuthkitCase().getBlackboard().getArtifacts(
62  QUERY_ARTIFACTS, Arrays.asList(dataSource.getId()));
63 
64  logger.log(Level.INFO, "Processing {0} blackboard artifacts.", listArtifacts.size()); //NON-NLS
65 
66  // Set up collector for roles
67  RoleProcessor roleProcessor = new RoleProcessor(context);
68 
69  // Process each URL
70  for (BlackboardArtifact artifact : listArtifacts) {
71  if (context.dataSourceIngestIsCancelled()) {
72  return;
73  }
74 
75  findRolesForUrl(artifact, roleProcessor);
76  }
77 
78  // Create artifacts
79  roleProcessor.createArtifacts();
80 
81  } catch (TskCoreException e) {
82  logger.log(Level.SEVERE, "Encountered error retrieving artifacts for domain role analysis", e); //NON-NLS
83  }
84  }
85 
94  private void findRolesForUrl(BlackboardArtifact artifact, RoleProcessor roleProcessor) throws TskCoreException {
95 
96  BlackboardAttribute urlAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
97  if (urlAttr == null) {
98  return;
99  }
100 
101  BlackboardAttribute domainAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN));
102  if (domainAttr == null) {
103  return;
104  }
105 
106  String url = urlAttr.getValueString().toLowerCase();
107  String domain = domainAttr.getValueString().toLowerCase();
108 
109  boolean roleFound = false;
110  roleFound = findMyBbRole(url, domain, artifact, roleProcessor) || roleFound;
111  roleFound = findPhpBbRole(url, domain, artifact, roleProcessor) || roleFound;
112  roleFound = findJoomlaRole(url, domain, artifact, roleProcessor) || roleFound;
113  roleFound = findWordPressRole(url, domain, artifact, roleProcessor) || roleFound;
114 
115  // if no other role for this url was found and it is a TSK_SERVICE_ACCOUNT, add a general user role.
116  if (!roleFound && artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT.getTypeID()) {
117  roleProcessor.addRole(domain, domain, Role.USER, url, artifact);
118  }
119  }
120 
131  private boolean findMyBbRole(String url, String domain, BlackboardArtifact artifact, RoleProcessor roleProcessor) {
132  String platformName = "myBB platform"; // NON-NLS
133 
134  if (url.contains("/admin/index.php")) {
135  roleProcessor.addRole(domain, platformName, Role.ADMIN, url, artifact);
136  return true;
137  } else if (url.contains("/modcp.php")) {
138  roleProcessor.addRole(domain, platformName, Role.MOD, url, artifact);
139  return true;
140  } else if (url.contains("/usercp.php")) {
141  roleProcessor.addRole(domain, platformName, Role.USER, url, artifact);
142  return true;
143  } else {
144  return false;
145  }
146  }
147 
158  private boolean findPhpBbRole(String url, String domain, BlackboardArtifact artifact, RoleProcessor roleProcessor) {
159  String platformName = "phpBB platform"; // NON-NLS
160 
161  if (url.contains("/adm/index.php")) {
162  roleProcessor.addRole(domain, platformName, Role.ADMIN, url, artifact);
163  return true;
164  } else if (url.contains("/mcp.php")) {
165  roleProcessor.addRole(domain, platformName, Role.MOD, url, artifact);
166  return true;
167  } else if (url.contains("/ucp.php")) {
168  roleProcessor.addRole(domain, platformName, Role.USER, url, artifact);
169  return true;
170  } else {
171  return false;
172  }
173  }
174 
185  private boolean findJoomlaRole(String url, String domain, BlackboardArtifact artifact, RoleProcessor roleProcessor) {
186  String platformName = "Joomla platform"; // NON-NLS
187 
188  if (url.contains("/administrator/index.php")) { // NON-NLS
189  roleProcessor.addRole(domain, platformName, Role.ADMIN, url, artifact);
190  return true;
191  } else {
192  return false;
193  }
194  }
195 
206  private boolean findWordPressRole(String url, String domain, BlackboardArtifact artifact, RoleProcessor roleProcessor) {
207  String platformName = "WordPress platform"; // NON-NLS
208 
209  // For WordPress, any logged in user can get to /wp-admin/, /wp-admin/index.php and /wp-admin/profile.php, so
210  // assume that any other .php file will indicate an administrator
211  if (url.contains("/wp-admin/")) {
212 
213  if (url.endsWith("/wp-admin/")
214  || url.contains("/wp-admin/index.php")
215  || url.contains("/wp-admin/profile.php")) {
216  roleProcessor.addRole(domain, platformName, Role.USER, url, artifact);
217  return true;
218  } else {
219  roleProcessor.addRole(domain, platformName, Role.ADMIN, url, artifact);
220  return true;
221  }
222  } else {
223  return false;
224  }
225  }
226 
227  @Override
228  void process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
229  extractDomainRoles(dataSource);
230  }
231 
239  private class RoleProcessor {
240 
241  private final IngestJobContext context;
242  private final Map<RoleKey, DomainRole> roles = new HashMap<>();
243 
245  this.context = context;
246  }
247 
259  void addRole(String domain, String platform, Role role, String url, BlackboardArtifact artifact) {
260  RoleKey key = new RoleKey(domain, platform);
261  if ((!roles.containsKey(key))
262  || (roles.containsKey(key) && (role.getRank() > roles.get(key).getRole().getRank()))) {
263  roles.put(key, new DomainRole(domain, platform, role, url, artifact));
264  }
265  }
266 
270  void createArtifacts() {
271 
272  if (roles.isEmpty()) {
273  logger.log(Level.INFO, "Didn't find any web accounts.");
274  return;
275  } else {
276  logger.log(Level.INFO, "Found {0} web accounts.", roles.keySet().size());
277  }
278 
279  try {
280  List<BlackboardArtifact> artifactList = new ArrayList<>();
281  for (RoleKey key : roles.keySet()) {
282  if (context.dataSourceIngestIsCancelled()) {
283  return;
284  }
285 
286  DomainRole role = roles.get(key);
287 
288  AbstractFile file = tskCase.getAbstractFileById(role.getArtifact().getObjectID());
289  if (file == null) {
290  continue;
291  }
292 
293  String desc = role.getRole().getDesc() + " (" + role.getPlatform() + ")"; // NON-NLS
294 
295  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
296  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN,
297  NbBundle.getMessage(this.getClass(),
298  "ExtractWebAccountType.parentModuleName"), role.getDomain()));
299  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT,
300  NbBundle.getMessage(this.getClass(),
301  "ExtractWebAccountType.parentModuleName"), desc));
302  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL,
303  NbBundle.getMessage(this.getClass(),
304  "ExtractWebAccountType.parentModuleName"), role.getUrl()));
305 
306  artifactList.add(createArtifactWithAttributes(BlackboardArtifact.Type.TSK_WEB_ACCOUNT_TYPE, file, bbattributes));
307  }
308 
309  if (!context.dataSourceIngestIsCancelled()) {
310  postArtifacts(artifactList);
311  }
312  } catch (TskCoreException ex) {
313  logger.log(Level.SEVERE, "Error creating web accounts", ex);
314  }
315  }
316  }
317 
321  @NbBundle.Messages({
322  "ExtractWebAccountType.role.user=User role",
323  "ExtractWebAccountType.role.moderator=Moderator role",
324  "ExtractWebAccountType.role.admin=Administrator role"
325  })
326  private enum Role {
327  USER(Bundle.ExtractWebAccountType_role_user(), 0),
328  MOD(Bundle.ExtractWebAccountType_role_moderator(), 1),
329  ADMIN(Bundle.ExtractWebAccountType_role_admin(), 2);
330 
331  private final String desc;
332  private final int rank;
333 
334  Role(String desc, int rank) {
335  this.desc = desc;
336  this.rank = rank;
337  }
338 
339  String getDesc() {
340  return desc;
341  }
342 
343  int getRank() {
344  return rank;
345  }
346  }
347 
351  private class RoleKey {
352 
353  private final String domain;
354  private final String platform;
355 
356  RoleKey(String domain, String platform) {
357  this.domain = domain;
358  this.platform = platform;
359  }
360 
361  @Override
362  public boolean equals(Object other) {
363  if (!(other instanceof RoleKey)) {
364  return false;
365  }
366 
367  RoleKey otherKey = (RoleKey) other;
368  return (domain.equals(otherKey.domain)
369  && platform.equals(otherKey.platform));
370  }
371 
372  @Override
373  public int hashCode() {
374  int hash = 7;
375  hash = 79 * hash + Objects.hashCode(this.domain);
376  hash = 79 * hash + Objects.hashCode(this.platform);
377  return hash;
378  }
379  }
380 
384  private class DomainRole {
385 
386  final String domain;
387  final String platform;
388  final Role role;
389  final String url;
390  final BlackboardArtifact artifact;
391 
392  DomainRole(String domain, String platform, Role role, String url, BlackboardArtifact artifact) {
393  this.domain = domain;
394  this.role = role;
395  this.platform = platform;
396  this.url = url;
397  this.artifact = artifact;
398  }
399 
400  String getDomain() {
401  return domain;
402  }
403 
404  String getPlatform() {
405  return platform;
406  }
407 
408  Role getRole() {
409  return role;
410  }
411 
412  String getUrl() {
413  return url;
414  }
415 
416  BlackboardArtifact getArtifact() {
417  return artifact;
418  }
419  }
420 }

Copyright © 2012-2022 Basis Technology. Generated on: Tue Jun 27 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.