Autopsy  4.17.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 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  moduleName = 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  for (RoleKey key : roles.keySet()) {
276  if (context.dataSourceIngestIsCancelled()) {
277  return;
278  }
279 
280  DomainRole role = roles.get(key);
281 
282  AbstractFile file = tskCase.getAbstractFileById(role.getArtifact().getObjectID());
283  if (file == null) {
284  continue;
285  }
286 
287  String desc = role.getRole().getDesc() + " (" + role.getPlatform() + ")"; // NON-NLS
288 
289  Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
290  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN,
291  NbBundle.getMessage(this.getClass(),
292  "ExtractWebAccountType.parentModuleName"), role.getDomain()));
293  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT,
294  NbBundle.getMessage(this.getClass(),
295  "ExtractWebAccountType.parentModuleName"), desc));
296  bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL,
297  NbBundle.getMessage(this.getClass(),
298  "ExtractWebAccountType.parentModuleName"), role.getUrl()));
299 
300  postArtifact(createArtifactWithAttributes(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_ACCOUNT_TYPE, file, bbattributes));
301  }
302  } catch (TskCoreException ex) {
303  logger.log(Level.SEVERE, "Error creating web accounts", ex);
304  }
305  }
306  }
307 
311  @NbBundle.Messages({
312  "ExtractWebAccountType.role.user=User role",
313  "ExtractWebAccountType.role.moderator=Moderator role",
314  "ExtractWebAccountType.role.admin=Administrator role"
315  })
316  private enum Role {
317  USER(Bundle.ExtractWebAccountType_role_user(), 0),
318  MOD(Bundle.ExtractWebAccountType_role_moderator(), 1),
319  ADMIN(Bundle.ExtractWebAccountType_role_admin(), 2);
320 
321  private final String desc;
322  private final int rank;
323 
324  Role(String desc, int rank) {
325  this.desc = desc;
326  this.rank = rank;
327  }
328 
329  String getDesc() {
330  return desc;
331  }
332 
333  int getRank() {
334  return rank;
335  }
336  }
337 
341  private class RoleKey {
342 
343  private final String domain;
344  private final String platform;
345 
346  RoleKey(String domain, String platform) {
347  this.domain = domain;
348  this.platform = platform;
349  }
350 
351  @Override
352  public boolean equals(Object other) {
353  if (!(other instanceof RoleKey)) {
354  return false;
355  }
356 
357  RoleKey otherKey = (RoleKey) other;
358  return (domain.equals(otherKey.domain)
359  && platform.equals(otherKey.platform));
360  }
361 
362  @Override
363  public int hashCode() {
364  int hash = 7;
365  hash = 79 * hash + Objects.hashCode(this.domain);
366  hash = 79 * hash + Objects.hashCode(this.platform);
367  return hash;
368  }
369  }
370 
374  private class DomainRole {
375 
376  final String domain;
377  final String platform;
378  final Role role;
379  final String url;
380  final BlackboardArtifact artifact;
381 
382  DomainRole(String domain, String platform, Role role, String url, BlackboardArtifact artifact) {
383  this.domain = domain;
384  this.role = role;
385  this.platform = platform;
386  this.url = url;
387  this.artifact = artifact;
388  }
389 
390  String getDomain() {
391  return domain;
392  }
393 
394  String getPlatform() {
395  return platform;
396  }
397 
398  Role getRole() {
399  return role;
400  }
401 
402  String getUrl() {
403  return url;
404  }
405 
406  BlackboardArtifact getArtifact() {
407  return artifact;
408  }
409  }
410 }

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