Autopsy  4.19.0
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 
47  ExtractWebAccountType() {
48  super(NbBundle.getMessage(ExtractWebAccountType.class, "ExtractWebAccountType.moduleName.text"));
49  }
50 
51  private static final List<BlackboardArtifact.Type> QUERY_ARTIFACTS = Arrays.asList(
52  new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY),
53  new BlackboardArtifact.Type(BlackboardArtifact.ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT)
54  );
55 
56  private void extractDomainRoles(Content dataSource, IngestJobContext context) {
57  try {
58  // Get web history blackboard artifacts
59  Collection<BlackboardArtifact> listArtifacts = currentCase.getSleuthkitCase().getBlackboard().getArtifacts(
60  QUERY_ARTIFACTS, Arrays.asList(dataSource.getId()));
61 
62  logger.log(Level.INFO, "Processing {0} blackboard artifacts.", listArtifacts.size()); //NON-NLS
63 
64  // Set up collector for roles
65  RoleProcessor roleProcessor = new RoleProcessor(context);
66 
67  // Process each URL
68  for (BlackboardArtifact artifact : listArtifacts) {
69  if (context.dataSourceIngestIsCancelled()) {
70  return;
71  }
72 
73  findRolesForUrl(artifact, roleProcessor);
74  }
75 
76  // Create artifacts
77  roleProcessor.createArtifacts();
78 
79  } catch (TskCoreException e) {
80  logger.log(Level.SEVERE, "Encountered error retrieving artifacts for domain role analysis", e); //NON-NLS
81  }
82  }
83 
92  private void findRolesForUrl(BlackboardArtifact artifact, RoleProcessor roleProcessor) throws TskCoreException {
93 
94  BlackboardAttribute urlAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
95  if (urlAttr == null) {
96  return;
97  }
98 
99  BlackboardAttribute domainAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN));
100  if (domainAttr == null) {
101  return;
102  }
103 
104  String url = urlAttr.getValueString().toLowerCase();
105  String domain = domainAttr.getValueString().toLowerCase();
106 
107  boolean roleFound = false;
108  roleFound = findMyBbRole(url, domain, artifact, roleProcessor) || roleFound;
109  roleFound = findPhpBbRole(url, domain, artifact, roleProcessor) || roleFound;
110  roleFound = findJoomlaRole(url, domain, artifact, roleProcessor) || roleFound;
111  roleFound = findWordPressRole(url, domain, artifact, roleProcessor) || roleFound;
112 
113  // if no other role for this url was found and it is a TSK_SERVICE_ACCOUNT, add a general user role.
114  if (!roleFound && artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT.getTypeID()) {
115  roleProcessor.addRole(domain, domain, Role.USER, url, artifact);
116  }
117  }
118 
119 
129  private boolean findMyBbRole(String url, String domain, BlackboardArtifact artifact, RoleProcessor roleProcessor) {
130  String platformName = "myBB platform"; // NON-NLS
131 
132  if (url.contains("/admin/index.php")) {
133  roleProcessor.addRole(domain, platformName, Role.ADMIN, url, artifact);
134  return true;
135  } else if (url.contains("/modcp.php")) {
136  roleProcessor.addRole(domain, platformName, Role.MOD, url, artifact);
137  return true;
138  } else if (url.contains("/usercp.php")) {
139  roleProcessor.addRole(domain, platformName, Role.USER, url, artifact);
140  return true;
141  } else {
142  return false;
143  }
144  }
145 
155  private boolean findPhpBbRole(String url, String domain, BlackboardArtifact artifact, RoleProcessor roleProcessor) {
156  String platformName = "phpBB platform"; // NON-NLS
157 
158  if (url.contains("/adm/index.php")) {
159  roleProcessor.addRole(domain, platformName, Role.ADMIN, url, artifact);
160  return true;
161  } else if (url.contains("/mcp.php")) {
162  roleProcessor.addRole(domain, platformName, Role.MOD, url, artifact);
163  return true;
164  } else if (url.contains("/ucp.php")) {
165  roleProcessor.addRole(domain, platformName, Role.USER, url, artifact);
166  return true;
167  } else {
168  return false;
169  }
170  }
171 
181  private boolean findJoomlaRole(String url, String domain, BlackboardArtifact artifact, RoleProcessor roleProcessor) {
182  String platformName = "Joomla platform"; // NON-NLS
183 
184  if (url.contains("/administrator/index.php")) { // NON-NLS
185  roleProcessor.addRole(domain, platformName, Role.ADMIN, url, artifact);
186  return true;
187  } else {
188  return false;
189  }
190  }
191 
201  private boolean findWordPressRole(String url, String domain, BlackboardArtifact artifact, RoleProcessor roleProcessor) {
202  String platformName = "WordPress platform"; // NON-NLS
203 
204  // For WordPress, any logged in user can get to /wp-admin/, /wp-admin/index.php and /wp-admin/profile.php, so
205  // assume that any other .php file will indicate an administrator
206  if (url.contains("/wp-admin/")) {
207 
208  if (url.endsWith("/wp-admin/")
209  || url.contains("/wp-admin/index.php")
210  || url.contains("/wp-admin/profile.php")) {
211  roleProcessor.addRole(domain, platformName, Role.USER, url, artifact);
212  return true;
213  } else {
214  roleProcessor.addRole(domain, platformName, Role.ADMIN, url, artifact);
215  return true;
216  }
217  } else {
218  return false;
219  }
220  }
221 
222  @Override
223  void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
224  extractDomainRoles(dataSource, context);
225  }
226 
234  private class RoleProcessor {
235 
236  private final IngestJobContext context;
237  private final Map<RoleKey, DomainRole> roles = new HashMap<>();
238 
240  this.context = context;
241  }
242 
254  void addRole(String domain, String platform, Role role, String url, BlackboardArtifact artifact) {
255  RoleKey key = new RoleKey(domain, platform);
256  if ((!roles.containsKey(key))
257  || (roles.containsKey(key) && (role.getRank() > roles.get(key).getRole().getRank()))) {
258  roles.put(key, new DomainRole(domain, platform, role, url, artifact));
259  }
260  }
261 
265  void createArtifacts() {
266 
267  if (roles.isEmpty()) {
268  logger.log(Level.INFO, "Didn't find any web accounts.");
269  return;
270  } else {
271  logger.log(Level.INFO, "Found {0} web accounts.", roles.keySet().size());
272  }
273 
274  try {
275  List<BlackboardArtifact> artifactList = new ArrayList<>();
276  for (RoleKey key : roles.keySet()) {
277  if (context.dataSourceIngestIsCancelled()) {
278  return;
279  }
280 
281  DomainRole role = roles.get(key);
282 
283  AbstractFile file = tskCase.getAbstractFileById(role.getArtifact().getObjectID());
284  if (file == null) {
285  continue;
286  }
287 
288  String desc = role.getRole().getDesc() + " (" + role.getPlatform() + ")"; // NON-NLS
289 
290  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
291  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN,
292  NbBundle.getMessage(this.getClass(),
293  "ExtractWebAccountType.parentModuleName"), role.getDomain()));
294  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT,
295  NbBundle.getMessage(this.getClass(),
296  "ExtractWebAccountType.parentModuleName"), desc));
297  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL,
298  NbBundle.getMessage(this.getClass(),
299  "ExtractWebAccountType.parentModuleName"), role.getUrl()));
300 
301  artifactList.add(createArtifactWithAttributes(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_ACCOUNT_TYPE, file, bbattributes));
302  }
303 
304  if (!context.dataSourceIngestIsCancelled()) {
305  postArtifacts(artifactList);
306  }
307  } catch (TskCoreException ex) {
308  logger.log(Level.SEVERE, "Error creating web accounts", ex);
309  }
310  }
311  }
312 
316  @NbBundle.Messages({
317  "ExtractWebAccountType.role.user=User role",
318  "ExtractWebAccountType.role.moderator=Moderator role",
319  "ExtractWebAccountType.role.admin=Administrator role"
320  })
321  private enum Role {
322  USER(Bundle.ExtractWebAccountType_role_user(), 0),
323  MOD(Bundle.ExtractWebAccountType_role_moderator(), 1),
324  ADMIN(Bundle.ExtractWebAccountType_role_admin(), 2);
325 
326  private final String desc;
327  private final int rank;
328 
329  Role(String desc, int rank) {
330  this.desc = desc;
331  this.rank = rank;
332  }
333 
334  String getDesc() {
335  return desc;
336  }
337 
338  int getRank() {
339  return rank;
340  }
341  }
342 
346  private class RoleKey {
347 
348  private final String domain;
349  private final String platform;
350 
351  RoleKey(String domain, String platform) {
352  this.domain = domain;
353  this.platform = platform;
354  }
355 
356  @Override
357  public boolean equals(Object other) {
358  if (!(other instanceof RoleKey)) {
359  return false;
360  }
361 
362  RoleKey otherKey = (RoleKey) other;
363  return (domain.equals(otherKey.domain)
364  && platform.equals(otherKey.platform));
365  }
366 
367  @Override
368  public int hashCode() {
369  int hash = 7;
370  hash = 79 * hash + Objects.hashCode(this.domain);
371  hash = 79 * hash + Objects.hashCode(this.platform);
372  return hash;
373  }
374  }
375 
379  private class DomainRole {
380 
381  final String domain;
382  final String platform;
383  final Role role;
384  final String url;
385  final BlackboardArtifact artifact;
386 
387  DomainRole(String domain, String platform, Role role, String url, BlackboardArtifact artifact) {
388  this.domain = domain;
389  this.role = role;
390  this.platform = platform;
391  this.url = url;
392  this.artifact = artifact;
393  }
394 
395  String getDomain() {
396  return domain;
397  }
398 
399  String getPlatform() {
400  return platform;
401  }
402 
403  Role getRole() {
404  return role;
405  }
406 
407  String getUrl() {
408  return url;
409  }
410 
411  BlackboardArtifact getArtifact() {
412  return artifact;
413  }
414  }
415 }

Copyright © 2012-2021 Basis Technology. Generated on: Fri Aug 6 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.