mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
updates for sha1 hashing
This commit is contained in:
parent
3e2bbc6421
commit
2dd82a21ea
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2023 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.basistech.df.cybertriage.autopsy.malwarescan;
|
||||||
|
|
||||||
|
import com.google.common.net.InetAddresses;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to anonymize username in paths also anonymizes hostname / ip
|
||||||
|
* from UNC paths
|
||||||
|
*/
|
||||||
|
public class UsernameAnonymizer {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(UsernameAnonymizer.class.getName());
|
||||||
|
|
||||||
|
private final String USER_PATH_FORWARD_SLASH_REGEX = "(?<!all )([/]{0,1}\\Qusers\\E/)(?!(public|Default|defaultAccount|All Users))([^/]+)(/){0,1}";
|
||||||
|
private final String USER_PATH_BACK_SLASH_REGEX = "(?<!all )([\\\\]{0,1}\\Qusers\\E\\\\)(?!(public|Default|defaultAccount|All Users))([^\\\\]+)([\\\\]){0,1}";
|
||||||
|
|
||||||
|
private final double WINDOWS_VERSION;
|
||||||
|
private final double DEFAULT_WINDOWS_VERSION = 10.0;
|
||||||
|
private final String USER_PATH_FORWARD_SLASH_REGEX_XP = "([/]{0,1}\\Qdocuments and settings\\E/)(?!(Default User|All Users))([^/]+)(/){0,1}";
|
||||||
|
private final String USER_PATH_BACK_SLASH_REGEX_XP = "([\\\\]{0,1}\\Qdocuments and settings\\E\\\\)(?!(Default User|All Users))([^\\\\]+)(\\\\){0,1}";
|
||||||
|
|
||||||
|
private final Pattern UNC_PATH_FORWARD_SLASH_PATTERN = Pattern.compile("(//)([^/]+)(/){0,1}");
|
||||||
|
private final Pattern UNC_PATH_BACK_SLASH_PATTERN = Pattern.compile("(\\\\\\\\)([^\\\\]+)(\\\\){0,1}");
|
||||||
|
|
||||||
|
public UsernameAnonymizer() {
|
||||||
|
// This constructor was added for the unit tests
|
||||||
|
// For most purposes, the other constructor should be used so we get the collection info such as users and windows version
|
||||||
|
|
||||||
|
WINDOWS_VERSION = DEFAULT_WINDOWS_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String anonymousUsername(String inputString) {
|
||||||
|
if (StringUtils.isBlank(inputString)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String anonymousString = anonymizeUserFromPathsWithForwardSlashes(inputString);
|
||||||
|
anonymousString = anonymizeUserFromPathsWithBackSlashes(anonymousString);
|
||||||
|
anonymousString = anonymizeServerFromUNCPath(anonymousString);
|
||||||
|
|
||||||
|
return anonymousString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String anonymizeUserFromPathsWithForwardSlashes(String stringWithUsername) {
|
||||||
|
Pattern pattern = WINDOWS_VERSION < 6 ? Pattern.compile(USER_PATH_FORWARD_SLASH_REGEX_XP, Pattern.CASE_INSENSITIVE) : Pattern.compile(USER_PATH_FORWARD_SLASH_REGEX, Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher matcher = pattern.matcher(stringWithUsername.toLowerCase(Locale.ENGLISH));
|
||||||
|
String replacement = "";
|
||||||
|
while (matcher.find()) {
|
||||||
|
replacement = String.format("$1%s$4", "<user>");
|
||||||
|
}
|
||||||
|
String anonymousString = matcher.replaceAll(replacement);
|
||||||
|
|
||||||
|
return anonymousString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Most paths in CyberTriage are normalized with forward slashes
|
||||||
|
// but there can still be strings containing paths that are not normalized such paths contained in arguments or event log payloads
|
||||||
|
private String anonymizeUserFromPathsWithBackSlashes(String stringWithUsername) {
|
||||||
|
Pattern pattern = WINDOWS_VERSION < 6 ? Pattern.compile(USER_PATH_BACK_SLASH_REGEX_XP, Pattern.CASE_INSENSITIVE) : Pattern.compile(USER_PATH_BACK_SLASH_REGEX, Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher matcher = pattern.matcher(stringWithUsername.toLowerCase(Locale.ENGLISH));
|
||||||
|
String replacement = "";
|
||||||
|
while (matcher.find()) {
|
||||||
|
replacement = String.format("$1%s$4", "<user>");
|
||||||
|
}
|
||||||
|
String anonymousString = matcher.replaceAll(replacement);
|
||||||
|
|
||||||
|
return anonymousString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String anonymizeServerFromUNCPath(String inputString) {
|
||||||
|
|
||||||
|
Set<String> serverNames = new HashSet<>();
|
||||||
|
String anonymousString = inputString.toLowerCase(Locale.ENGLISH);
|
||||||
|
|
||||||
|
Matcher forwardSlashMatcher = UNC_PATH_FORWARD_SLASH_PATTERN.matcher(anonymousString);
|
||||||
|
while (forwardSlashMatcher.find()) {
|
||||||
|
String serverName = forwardSlashMatcher.group(2);
|
||||||
|
serverNames.add(serverName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matcher backSlashMatcher = UNC_PATH_BACK_SLASH_PATTERN.matcher(anonymousString);
|
||||||
|
while (backSlashMatcher.find()) {
|
||||||
|
String serverName = backSlashMatcher.group(2);
|
||||||
|
serverNames.add(serverName);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String serverName : serverNames) {
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(serverName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InetAddresses.isInetAddress(serverName)) {
|
||||||
|
if (isLocalIP(serverName)) {
|
||||||
|
anonymousString = StringUtils.replace(anonymousString, "\\" + serverName + "\\", "\\<private_ip>\\");
|
||||||
|
anonymousString = StringUtils.replace(anonymousString, "/" + serverName + "/", "/<private_ip>/");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
anonymousString = StringUtils.replace(anonymousString, "\\" + serverName + "\\", "\\<hostname>\\");
|
||||||
|
anonymousString = StringUtils.replace(anonymousString, "/" + serverName + "/", "/<hostname>/");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return anonymousString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if IP Address is Any Local / Site Local / Link Local / Loop
|
||||||
|
* back local. Sample list "0.0.0.0", wildcard addres
|
||||||
|
* "10.1.1.1","10.10.10.10", site local address "127.0.0.0","127.2.2.2",
|
||||||
|
* loopback address "169.254.0.0","169.254.10.10", Link local address
|
||||||
|
* "172.16.0.0","172.31.245.245", site local address
|
||||||
|
*
|
||||||
|
* @param ipAddress
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isLocalIP(String ipAddress) {
|
||||||
|
try {
|
||||||
|
InetAddress a = InetAddresses.forString(ipAddress);
|
||||||
|
return a.isAnyLocalAddress() || a.isSiteLocalAddress()
|
||||||
|
|| a.isLoopbackAddress() || a.isLinkLocalAddress();
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
LOGGER.log(Level.WARNING, "Invalid IP string", ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user