mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Merge branch 'sleuthkit:develop' into develop
This commit is contained in:
commit
443bedba91
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.core/10
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
|
||||
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml
|
||||
OpenIDE-Module-Implementation-Version: 37
|
||||
OpenIDE-Module-Implementation-Version: 38
|
||||
OpenIDE-Module-Requires: org.openide.windows.WindowManager
|
||||
AutoUpdate-Show-In-Client: true
|
||||
AutoUpdate-Essential-Module: true
|
||||
|
@ -85,8 +85,8 @@ file.reference.Rejistry-1.1-SNAPSHOT.jar=release/modules/ext/Rejistry-1.1-SNAPSH
|
||||
file.reference.serializer-2.7.2.jar=release/modules/ext/serializer-2.7.2.jar
|
||||
file.reference.sevenzipjbinding-AllPlatforms.jar=release/modules/ext/sevenzipjbinding-AllPlatforms.jar
|
||||
file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
|
||||
file.reference.sleuthkit-4.12.0.jar=release/modules/ext/sleuthkit-4.12.0.jar
|
||||
file.reference.sleuthkit-caseuco-4.12.0.jar=release/modules/ext/sleuthkit-caseuco-4.12.0.jar
|
||||
file.reference.sleuthkit-4.12.1.jar=release/modules/ext/sleuthkit-4.12.1.jar
|
||||
file.reference.sleuthkit-caseuco-4.12.1.jar=release/modules/ext/sleuthkit-caseuco-4.12.1.jar
|
||||
file.reference.slf4j-api-1.7.36.jar=release/modules/ext/slf4j-api-1.7.36.jar
|
||||
file.reference.snakeyaml-2.0.jar=release/modules/ext/snakeyaml-2.0.jar
|
||||
file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar
|
||||
@ -107,4 +107,4 @@ license.file=../LICENSE-2.0.txt
|
||||
nbm.homepage=http://www.sleuthkit.org/
|
||||
nbm.module.author=Brian Carrier
|
||||
nbm.needs.restart=true
|
||||
spec.version.base=10.24
|
||||
spec.version.base=10.25
|
||||
|
@ -718,12 +718,12 @@
|
||||
<binary-origin>release/modules/ext/sevenzipjbinding.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-4.12.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-4.12.0.jar</binary-origin>
|
||||
<runtime-relative-path>ext/sleuthkit-4.12.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-4.12.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/sleuthkit-caseuco-4.12.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.12.0.jar</binary-origin>
|
||||
<runtime-relative-path>ext/sleuthkit-caseuco-4.12.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.12.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/slf4j-api-1.7.36.jar</runtime-relative-path>
|
||||
|
@ -25,6 +25,7 @@ import com.basistech.df.cybertriage.autopsy.ctapi.json.CTCloudBean;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.CTCloudBeanResponse;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.DecryptedLicenseResponse;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.FileReputationRequest;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.FileUploadRequest;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseRequest;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseResponse;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.MetadataUploadRequest;
|
||||
@ -78,21 +79,22 @@ public class CTApiDAO {
|
||||
}
|
||||
|
||||
public AuthTokenResponse getAuthToken(DecryptedLicenseResponse decrypted) throws CTCloudException {
|
||||
return getAuthToken(decrypted, false);
|
||||
return getAuthToken(decrypted, null);
|
||||
}
|
||||
|
||||
public AuthTokenResponse getAuthToken(DecryptedLicenseResponse decrypted, boolean fileUpload) throws CTCloudException {
|
||||
public AuthTokenResponse getAuthToken(DecryptedLicenseResponse decrypted, Long fileUploadSize) throws CTCloudException {
|
||||
AuthTokenRequest authTokenRequest = new AuthTokenRequest()
|
||||
.setAutopsyVersion(getAppVersion())
|
||||
.setRequestFileUpload(fileUpload)
|
||||
.setRequestFileUpload(fileUploadSize != null && fileUploadSize > 0)
|
||||
.setFileUploadSize(fileUploadSize != null && fileUploadSize > 0 ? fileUploadSize : null)
|
||||
.setBoostLicenseId(decrypted.getBoostLicenseId())
|
||||
.setHostId(decrypted.getLicenseHostId());
|
||||
|
||||
return httpClient.doPost(AUTH_TOKEN_REQUEST_PATH, authTokenRequest, AuthTokenResponse.class);
|
||||
}
|
||||
|
||||
public void uploadFile(String url, String fileName, InputStream fileIs) throws CTCloudException {
|
||||
httpClient.doFileUploadPost(url, fileName, fileIs);
|
||||
public void uploadFile(FileUploadRequest fileUploadRequest) throws CTCloudException {
|
||||
httpClient.doFileUploadPut(fileUploadRequest);
|
||||
}
|
||||
|
||||
public void uploadMeta(AuthenticatedRequestData authenticatedRequestData, MetadataUploadRequest metaRequest) throws CTCloudException {
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package com.basistech.df.cybertriage.autopsy.ctapi;
|
||||
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.CTCloudException.ErrorCode;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.FileUploadRequest;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.util.ObjectMapperUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.IOException;
|
||||
@ -55,13 +57,14 @@ import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.InputStreamEntity;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
@ -155,16 +158,23 @@ class CTCloudHttpClient {
|
||||
// Parse Response
|
||||
if (classType != null) {
|
||||
HttpEntity entity = response.getEntity();
|
||||
String entityStr = EntityUtils.toString(entity);
|
||||
O respObj = mapper.readValue(entityStr, classType);
|
||||
return respObj;
|
||||
} else {
|
||||
return null;
|
||||
if (entity != null) {
|
||||
String entityStr = EntityUtils.toString(entity);
|
||||
if (StringUtils.isNotBlank(entityStr)) {
|
||||
O respObj = mapper.readValue(entityStr, classType);
|
||||
return respObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
} else {
|
||||
LOGGER.log(Level.WARNING, "Response Received. - Status Error {}", response.getStatusLine());
|
||||
handleNonOKResponse(response, "");
|
||||
}
|
||||
// transform all non-CTCloudException's into a CTCloudException
|
||||
} catch (CTCloudException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
LOGGER.log(Level.WARNING, "Error when parsing response from CyberTriage Cloud", ex);
|
||||
throw new CTCloudException(CTCloudException.parseUnknownException(ex), ex);
|
||||
@ -184,10 +194,23 @@ class CTCloudHttpClient {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void doFileUploadPost(String fullUrlPath, String fileName, InputStream fileIs) throws CTCloudException {
|
||||
URI postUri;
|
||||
public void doFileUploadPut(FileUploadRequest fileUploadRequest) throws CTCloudException {
|
||||
if (fileUploadRequest == null) {
|
||||
throw new CTCloudException(ErrorCode.BAD_REQUEST, new IllegalArgumentException("fileUploadRequest cannot be null"));
|
||||
}
|
||||
|
||||
String fullUrlPath = fileUploadRequest.getFullUrlPath();
|
||||
String fileName = fileUploadRequest.getFileName();
|
||||
InputStream fileInputStream = fileUploadRequest.getFileInputStream();
|
||||
Long contentLength = fileUploadRequest.getContentLength();
|
||||
|
||||
if (StringUtils.isBlank(fullUrlPath) || fileInputStream == null || contentLength == null || contentLength <= 0) {
|
||||
throw new CTCloudException(ErrorCode.BAD_REQUEST, new IllegalArgumentException("fullUrlPath, fileInputStream, contentLength must not be empty, null or less than 0"));
|
||||
}
|
||||
|
||||
URI putUri;
|
||||
try {
|
||||
postUri = new URI(fullUrlPath);
|
||||
putUri = new URI(fullUrlPath);
|
||||
} catch (URISyntaxException ex) {
|
||||
LOGGER.log(Level.WARNING, "Wrong URL syntax for CT Cloud " + fullUrlPath, ex);
|
||||
throw new CTCloudException(CTCloudException.ErrorCode.UNKNOWN, ex);
|
||||
@ -195,23 +218,13 @@ class CTCloudHttpClient {
|
||||
|
||||
try (CloseableHttpClient httpclient = createConnection(proxySelector, sslContext)) {
|
||||
LOGGER.log(Level.INFO, "initiating http post request to ctcloud server " + fullUrlPath);
|
||||
HttpPost post = new HttpPost(postUri);
|
||||
configureRequestTimeout(post);
|
||||
HttpPut put = new HttpPut(putUri);
|
||||
configureRequestTimeout(put);
|
||||
|
||||
post.addHeader("Connection", "keep-alive");
|
||||
put.addHeader("Connection", "keep-alive");
|
||||
put.setEntity(new InputStreamEntity(fileInputStream, contentLength, ContentType.APPLICATION_OCTET_STREAM));
|
||||
|
||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||
builder.addBinaryBody(
|
||||
"file",
|
||||
fileIs,
|
||||
ContentType.APPLICATION_OCTET_STREAM,
|
||||
fileName
|
||||
);
|
||||
|
||||
HttpEntity multipart = builder.build();
|
||||
post.setEntity(multipart);
|
||||
|
||||
try (CloseableHttpResponse response = httpclient.execute(post)) {
|
||||
try (CloseableHttpResponse response = httpclient.execute(put)) {
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_NO_CONTENT) {
|
||||
LOGGER.log(Level.INFO, "Response Received. - Status OK");
|
||||
@ -381,7 +394,7 @@ class CTCloudHttpClient {
|
||||
HttpClientBuilder builder;
|
||||
|
||||
if (ProxySettings.getProxyType() != ProxySettings.DIRECT_CONNECTION
|
||||
&& StringUtils.isBlank(ProxySettings.getAuthenticationUsername())
|
||||
&& StringUtils.isBlank(ProxySettings.getAuthenticationUsername())
|
||||
&& ArrayUtils.isEmpty(ProxySettings.getAuthenticationPassword())
|
||||
&& WinHttpClients.isWinAuthAvailable()) {
|
||||
|
||||
|
@ -34,6 +34,9 @@ public class AuthTokenRequest {
|
||||
@JsonProperty("requestFileUpload")
|
||||
private boolean requestFileUpload;
|
||||
|
||||
@JsonProperty("fileUploadSize")
|
||||
private Long fileUploadSize;
|
||||
|
||||
@JsonProperty("host_id")
|
||||
private String hostId;
|
||||
|
||||
@ -64,6 +67,16 @@ public class AuthTokenRequest {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getFileUploadSize() {
|
||||
return fileUploadSize;
|
||||
}
|
||||
|
||||
public AuthTokenRequest setFileUploadSize(Long fileUploadSize) {
|
||||
this.fileUploadSize = fileUploadSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public String getHostId() {
|
||||
return hostId;
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.ctapi.json;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Data for a file upload request.
|
||||
*/
|
||||
public class FileUploadRequest {
|
||||
|
||||
private String fullUrlPath;
|
||||
private String fileName;
|
||||
private InputStream fileInputStream;
|
||||
private Long contentLength;
|
||||
|
||||
public String getFullUrlPath() {
|
||||
return fullUrlPath;
|
||||
}
|
||||
|
||||
public FileUploadRequest setFullUrlPath(String fullUrlPath) {
|
||||
this.fullUrlPath = fullUrlPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public FileUploadRequest setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InputStream getFileInputStream() {
|
||||
return fileInputStream;
|
||||
}
|
||||
|
||||
public FileUploadRequest setFileInputStream(InputStream fileInputStream) {
|
||||
this.fileInputStream = fileInputStream;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Long getContentLength() {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
public FileUploadRequest setContentLength(Long contentLength) {
|
||||
this.contentLength = contentLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -32,18 +32,21 @@ public class LicenseResponse {
|
||||
private final Boolean hostChanged;
|
||||
private final Long hostChangesRemaining;
|
||||
private final BoostLicenseResponse boostLicense;
|
||||
private final String errorMsg;
|
||||
|
||||
@JsonCreator
|
||||
public LicenseResponse(
|
||||
@JsonProperty("success") Boolean success,
|
||||
@JsonProperty("hostChanged") Boolean hostChanged,
|
||||
@JsonProperty("hostChangesRemaining") Long hostChangesRemaining,
|
||||
@JsonProperty("boostLicense") BoostLicenseResponse boostLicense
|
||||
@JsonProperty("boostLicense") BoostLicenseResponse boostLicense,
|
||||
@JsonProperty("errorMsg") String errorMsg
|
||||
) {
|
||||
this.success = success;
|
||||
this.hostChanged = hostChanged;
|
||||
this.hostChangesRemaining = hostChangesRemaining;
|
||||
this.boostLicense = boostLicense;
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
public Boolean isSuccess() {
|
||||
@ -61,4 +64,8 @@ public class LicenseResponse {
|
||||
public BoostLicenseResponse getBoostLicense() {
|
||||
return boostLicense;
|
||||
}
|
||||
|
||||
public String getErrorMsg() {
|
||||
return errorMsg;
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
@ -42,6 +43,7 @@ import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Decrypts the payload of boost license.
|
||||
@ -58,12 +60,12 @@ public class LicenseDecryptorUtil {
|
||||
|
||||
private LicenseDecryptorUtil() {
|
||||
}
|
||||
|
||||
|
||||
public LicenseInfo createLicenseInfo(LicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException {
|
||||
if (licenseResponse == null || licenseResponse.getBoostLicense() == null) {
|
||||
throw new InvalidLicenseException("License or boost license are null");
|
||||
if (licenseResponse == null) {
|
||||
throw new InvalidLicenseException("License is null");
|
||||
}
|
||||
|
||||
|
||||
DecryptedLicenseResponse decrypted = parseLicenseJSON(licenseResponse.getBoostLicense());
|
||||
return new LicenseInfo(licenseResponse, decrypted);
|
||||
}
|
||||
@ -78,6 +80,9 @@ public class LicenseDecryptorUtil {
|
||||
* com.basistech.df.cybertriage.autopsy.ctapi.util.LicenseDecryptorUtil.InvalidLicenseException
|
||||
*/
|
||||
public DecryptedLicenseResponse parseLicenseJSON(BoostLicenseResponse licenseResponse) throws JsonProcessingException, InvalidLicenseException {
|
||||
if (licenseResponse == null) {
|
||||
throw new InvalidLicenseException("Boost license is null");
|
||||
}
|
||||
|
||||
String decryptedJsonResponse;
|
||||
try {
|
||||
@ -101,6 +106,12 @@ public class LicenseDecryptorUtil {
|
||||
}
|
||||
|
||||
private String decryptLicenseString(String encryptedJson, String ivBase64, String encryptedKey, String version) throws IOException, GeneralSecurityException, InvalidLicenseException {
|
||||
if (ObjectUtils.anyNull(encryptedJson, ivBase64, encryptedKey, version)) {
|
||||
throw new InvalidLicenseException(MessageFormat.format(
|
||||
"encryptedJson: {0}, iv: {1}, encryptedKey: {2}, version: {3} must all be non-null",
|
||||
encryptedJson, ivBase64, encryptedKey, version));
|
||||
}
|
||||
|
||||
if (!"1.0".equals(version)) {
|
||||
throw new InvalidLicenseException("Unexpected file version: " + version);
|
||||
}
|
||||
|
@ -26,12 +26,12 @@ import java.beans.PropertyChangeListener;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.swing.JPanel;
|
||||
import org.netbeans.spi.options.OptionsPanelController;
|
||||
import org.openide.util.Lookup;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
CTLicenseDialog.title=Add a License...
|
||||
CTLicenseDialog.licenseNumberLabel.text=License Number:
|
||||
CTLicenseDialog.licenseNumberTextField.text=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
CTLicenseDialog.licenseNumberTextField.text=
|
||||
CTLicenseDialog.cancelButton.text=Cancel
|
||||
CTLicenseDialog.okButton.text=Ok
|
||||
CTLicenseDialog.warningLabel.text=
|
||||
@ -25,3 +25,4 @@ EULADialog.title=Cyber Triage End User License Agreement
|
||||
CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text=
|
||||
CTMalwareScannerOptionsPanel.disclaimer.text=<html>The Cyber Triage Malware Scanner module uses 40+ malware scanning engines to identify if Windows executables are malicious. It requires a paid subscription to use.</html>
|
||||
CTMalwareScannerOptionsPanel.purchaseFromLabel.text=For licensing information, visit
|
||||
CTLicenseDialog.licenseNumberTextField.toolTipText=AUT-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
CTLicenseDialog.title=Add a License...
|
||||
CTLicenseDialog.licenseNumberLabel.text=License Number:
|
||||
CTLicenseDialog.licenseNumberTextField.text=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
CTLicenseDialog.licenseNumberTextField.text=
|
||||
CTLicenseDialog.cancelButton.text=Cancel
|
||||
CTLicenseDialog.okButton.text=Ok
|
||||
CTLicenseDialog.warningLabel.text=
|
||||
CTLicenseDialog_verifyInput_licenseNumberError=<html>Please verify license number format of 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'</html>
|
||||
CTLicenseDialog_verifyInput_licenseNumberError=<html>Please enter a license number</html>
|
||||
CTMalwareScannerOptionsPanel.hashLookupsRemainingLabel.text=
|
||||
CTMalwareScannerOptionsPanel.countersResetLabel.text=
|
||||
CTMalwareScannerOptionsPanel.maxFileUploadsLabel.text=
|
||||
@ -31,6 +31,8 @@ CTMalwareScannerOptionsPanel_licenseAddDialogEnteredErr_title=License Number Alr
|
||||
CTMalwareScannerOptionsPanel_licenseAddDialogPatternErr_desc=Please verify that license number is of format 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
|
||||
CTMalwareScannerOptionsPanel_licenseAddDialogPatternErr_title=Invalid License Number
|
||||
CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title=Server Error
|
||||
# {0} - licenseCode
|
||||
CTMalwareScannerOptionsPanel_LicenseFetcher_defaultErrMsg_desc=Error activating boost license {0}
|
||||
CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_desc=A general error occurred while fetching license information. Please try again later.
|
||||
CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_title=General Error
|
||||
# {0} - expiresDate
|
||||
@ -63,3 +65,4 @@ EULADialog.title=Cyber Triage End User License Agreement
|
||||
CTMalwareScannerOptionsPanel.licenseInfoMessageLabel.text=
|
||||
CTMalwareScannerOptionsPanel.disclaimer.text=<html>The Cyber Triage Malware Scanner module uses 40+ malware scanning engines to identify if Windows executables are malicious. It requires a paid subscription to use.</html>
|
||||
CTMalwareScannerOptionsPanel.purchaseFromLabel.text=For licensing information, visit
|
||||
CTLicenseDialog.licenseNumberTextField.toolTipText=AUT-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
|
@ -127,6 +127,9 @@
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTLicenseDialog.licenseNumberTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/ctoptions/ctcloud/Bundle.properties" key="CTLicenseDialog.licenseNumberTextField.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
|
@ -18,18 +18,20 @@
|
||||
*/
|
||||
package com.basistech.df.cybertriage.autopsy.ctoptions.ctcloud;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.corecomponents.TextPrompt;
|
||||
|
||||
/**
|
||||
* License dialog
|
||||
*/
|
||||
class CTLicenseDialog extends javax.swing.JDialog {
|
||||
|
||||
private static final Pattern LICENSE_PATTERN = Pattern.compile("^\\s*[a-zA-Z0-9\\-]+?\\s*$");
|
||||
private static final Pattern LICENSE_PATTERN = Pattern.compile("^\\s*[a-zA-Z0-9-_]+?\\s*$");
|
||||
private String licenseString = null;
|
||||
|
||||
/**
|
||||
@ -38,6 +40,7 @@ class CTLicenseDialog extends javax.swing.JDialog {
|
||||
public CTLicenseDialog(java.awt.Frame parent, boolean modal) {
|
||||
super(parent, modal);
|
||||
initComponents();
|
||||
configureHintText();
|
||||
this.licenseNumberTextField.getDocument().putProperty("filterNewlines", Boolean.TRUE);
|
||||
this.licenseNumberTextField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
@ -56,13 +59,23 @@ class CTLicenseDialog extends javax.swing.JDialog {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void configureHintText() {
|
||||
TextPrompt textPrompt = new TextPrompt(
|
||||
StringUtils.defaultString(this.licenseNumberTextField.getToolTipText()),
|
||||
this.licenseNumberTextField);
|
||||
|
||||
textPrompt.setForeground(Color.LIGHT_GRAY);
|
||||
float alpha = 0.9f; // Mostly opaque
|
||||
textPrompt.changeAlpha(alpha);
|
||||
}
|
||||
|
||||
String getValue() {
|
||||
return licenseString;
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"CTLicenseDialog_verifyInput_licenseNumberError=<html>Please verify license number format of 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'</html>"
|
||||
"CTLicenseDialog_verifyInput_licenseNumberError=<html>Please enter a license number</html>"
|
||||
})
|
||||
private void verifyInput() {
|
||||
String licenseInput = StringUtils.defaultString(this.licenseNumberTextField.getText());
|
||||
@ -165,6 +178,7 @@ class CTLicenseDialog extends javax.swing.JDialog {
|
||||
getContentPane().add(cancelButton, gridBagConstraints);
|
||||
|
||||
licenseNumberTextField.setText(org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.licenseNumberTextField.text")); // NOI18N
|
||||
licenseNumberTextField.setToolTipText(org.openide.util.NbBundle.getMessage(CTLicenseDialog.class, "CTLicenseDialog.licenseNumberTextField.toolTipText")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 1;
|
||||
@ -177,7 +191,8 @@ class CTLicenseDialog extends javax.swing.JDialog {
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
|
||||
this.licenseString = this.licenseNumberTextField.getText();
|
||||
String inputText = this.licenseNumberTextField.getText();
|
||||
this.licenseString = inputText == null ? null : inputText.trim();
|
||||
this.dispose();
|
||||
}//GEN-LAST:event_okButtonActionPerformed
|
||||
|
||||
|
@ -40,7 +40,6 @@ import java.util.Optional;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
@ -51,6 +50,7 @@ import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Options panel to be displayed in the CTOptionsPanel for settings regarding
|
||||
@ -608,6 +608,8 @@ public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel {
|
||||
@NbBundle.Messages({
|
||||
"CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title=Server Error",
|
||||
"CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_title=General Error",
|
||||
"# {0} - licenseCode",
|
||||
"CTMalwareScannerOptionsPanel_LicenseFetcher_defaultErrMsg_desc=Error activating boost license {0}",
|
||||
"CTMalwareScannerOptionsPanel_LicenseFetcher_localErr_desc=A general error occurred while fetching license information. Please try again later.",})
|
||||
private class LicenseFetcher extends SwingWorker<LicenseResponse, Void> {
|
||||
|
||||
@ -629,10 +631,9 @@ public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel {
|
||||
protected void done() {
|
||||
try {
|
||||
LicenseResponse licenseResponse = get();
|
||||
if (licenseResponse != null && licenseResponse.isSuccess()) {
|
||||
SwingUtilities.invokeLater(() -> acceptEula(licenseResponse));
|
||||
} else {
|
||||
logger.log(Level.WARNING, "An API error occurred while fetching license information. License fetch was not successful");
|
||||
// if no result, show unauthorized
|
||||
if (licenseResponse == null) {
|
||||
logger.log(Level.WARNING, "An API error occurred while fetching license information. License fetch returned no result.");
|
||||
JOptionPane.showMessageDialog(
|
||||
CTMalwareScannerOptionsPanel.this,
|
||||
CTCloudException.ErrorCode.UN_AUTHORIZED.getDescription(),
|
||||
@ -640,7 +641,30 @@ public class CTMalwareScannerOptionsPanel extends CTOptionsSubPanel {
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
setLicenseDisplay(licenseInfo, null);
|
||||
loadMalwareScansInfo(licenseInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
// if not successful response
|
||||
if (!Boolean.TRUE.equals(licenseResponse.isSuccess())) {
|
||||
logger.log(Level.WARNING, "An API error occurred while fetching license information. License fetch was not successful");
|
||||
// use default message unless error message specified
|
||||
String message = Bundle.CTMalwareScannerOptionsPanel_LicenseFetcher_defaultErrMsg_desc(licenseText);
|
||||
if (!StringUtils.isBlank(licenseResponse.getErrorMsg())) {
|
||||
message = licenseResponse.getErrorMsg();
|
||||
}
|
||||
JOptionPane.showMessageDialog(
|
||||
CTMalwareScannerOptionsPanel.this,
|
||||
message,
|
||||
Bundle.CTMalwareScannerOptionsPanel_LicenseFetcher_apiErr_title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
setLicenseDisplay(licenseInfo, null);
|
||||
loadMalwareScansInfo(licenseInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, load
|
||||
SwingUtilities.invokeLater(() -> acceptEula(licenseResponse));
|
||||
|
||||
} catch (InterruptedException | CancellationException ex) {
|
||||
// ignore cancellation; just load current license
|
||||
setLicenseDisplay(licenseInfo, null);
|
||||
|
@ -12,3 +12,5 @@ CTIncidentImportOptionsPanel.border.title_1=Incident Importer
|
||||
CTIncidentImportOptionsPanel.incidentTextLabel.text=The Cyber Triage Incident Import module allows you to open data collected by Cyber Triage in Autopsy. To use this feature you must install the Cyber Triage Import Module.
|
||||
CTincidentImportOptionsPanel.instructionsTextLabel.text=
|
||||
CTIncidentImportOptionsPanel.instructionsTextLabel.text=For instructions on obtaining the module refer to:
|
||||
CTIncidentImportOptionsPanel.importModule.text=Cyber Triage Import Module:
|
||||
CTIncidentImportOptionsPanel.importModuleDetected.text=
|
||||
|
@ -12,3 +12,7 @@ CTIncidentImportOptionsPanel.border.title_1=Incident Importer
|
||||
CTIncidentImportOptionsPanel.incidentTextLabel.text=The Cyber Triage Incident Import module allows you to open data collected by Cyber Triage in Autopsy. To use this feature you must install the Cyber Triage Import Module.
|
||||
CTincidentImportOptionsPanel.instructionsTextLabel.text=
|
||||
CTIncidentImportOptionsPanel.instructionsTextLabel.text=For instructions on obtaining the module refer to:
|
||||
CTIncidentImportOptionsPanel.importModule.text=Cyber Triage Import Module:
|
||||
CTIncidentImportOptionsPanel.importModuleDetected.text=
|
||||
CTIncidentImportOptionsPanel_setModuleDetected_detected=Detected
|
||||
CTIncidentImportOptionsPanel_setModuleDetected_notDetected=Not Detected
|
||||
|
@ -42,7 +42,35 @@
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="importModule">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties" key="CTIncidentImportOptionsPanel.importModule.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="3" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="importModuleDetected">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/basistech/df/cybertriage/autopsy/incidentoptions/Bundle.properties" key="CTIncidentImportOptionsPanel.importModuleDetected.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="0" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
@ -68,7 +96,7 @@
|
||||
</AccessibilityProperties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
@ -86,7 +114,7 @@
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
|
@ -1,16 +1,21 @@
|
||||
/** *************************************************************************
|
||||
** This data and information is proprietary to, and a valuable trade secret
|
||||
** of, Sleuth Kit Labs. It is given in confidence by Sleuth Kit Labs
|
||||
** and may only be used as permitted under the license agreement under which
|
||||
** it has been distributed, and in no other way.
|
||||
**
|
||||
** Copyright (c) 2023 Sleuth Kit Labs, LLC. All rights reserved
|
||||
**
|
||||
** The technical data and information provided herein are provided with
|
||||
** `limited rights', and the computer software provided herein is provided
|
||||
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||
** 7-104.9(a).
|
||||
************************************************************************** */
|
||||
/*
|
||||
* 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.incidentoptions;
|
||||
|
||||
import com.basistech.df.cybertriage.autopsy.ctoptions.subpanel.CTOptionsSubPanel;
|
||||
@ -19,15 +24,20 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.netbeans.spi.options.OptionsPanelController;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.casemodule.AutopsyContentProvider;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.guiutils.JFileChooserFactory;
|
||||
|
||||
@ -41,6 +51,8 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
|
||||
|
||||
private static final String CT_IMPORTER_DOC_LINK = "https://docs.cybertriage.com/en/latest/chapters/integrations/autopsy.html";
|
||||
|
||||
private static final String CT_STANDARD_CONTENT_PROVIDER_NAME = "CTStandardContentProvider";
|
||||
|
||||
private final JFileChooserFactory fileRepoChooserFactory = new JFileChooserFactory();
|
||||
private final CTSettingsPersistence ctPersistence = CTSettingsPersistence.getInstance();
|
||||
|
||||
@ -88,8 +100,23 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
|
||||
public synchronized void loadSettings() {
|
||||
CTSettings ctSettings = ctPersistence.loadCTSettings();
|
||||
setCTSettingsDisplay(ctSettings);
|
||||
setModuleDetected();
|
||||
setEnabledItems(Case.isCaseOpen());
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"CTIncidentImportOptionsPanel_setModuleDetected_detected=Detected",
|
||||
"CTIncidentImportOptionsPanel_setModuleDetected_notDetected=Not Detected"
|
||||
})
|
||||
private void setModuleDetected() {
|
||||
Collection<? extends AutopsyContentProvider> contentProviders = Lookup.getDefault().lookupAll(AutopsyContentProvider.class);
|
||||
boolean detected = ((Collection<? extends AutopsyContentProvider>) (contentProviders != null ? contentProviders : Collections.emptyList())).stream()
|
||||
.anyMatch(p -> p != null && StringUtils.defaultString(p.getName()).toUpperCase().startsWith(CT_STANDARD_CONTENT_PROVIDER_NAME.toUpperCase()));
|
||||
|
||||
this.importModuleDetected.setText(detected
|
||||
? Bundle.CTIncidentImportOptionsPanel_setModuleDetected_detected()
|
||||
: Bundle.CTIncidentImportOptionsPanel_setModuleDetected_notDetected());
|
||||
}
|
||||
|
||||
private void setEnabledItems(boolean caseOpen) {
|
||||
this.caseOpenWarningLabel.setVisible(caseOpen);
|
||||
@ -122,6 +149,8 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
|
||||
|
||||
incidentTextPanel = new javax.swing.JPanel();
|
||||
incidentTextLabel = new javax.swing.JLabel();
|
||||
javax.swing.JLabel importModule = new javax.swing.JLabel();
|
||||
importModuleDetected = new javax.swing.JLabel();
|
||||
instructionsPanel = new javax.swing.JPanel();
|
||||
instructionsTextLabel = new javax.swing.JLabel();
|
||||
instructionsLinkLabel = new javax.swing.JLabel();
|
||||
@ -140,10 +169,28 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
|
||||
incidentTextPanel.add(incidentTextLabel, gridBagConstraints);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(importModule, org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.importModule.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 3);
|
||||
incidentTextPanel.add(importModule, gridBagConstraints);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(importModuleDetected, org.openide.util.NbBundle.getMessage(CTIncidentImportOptionsPanel.class, "CTIncidentImportOptionsPanel.importModuleDetected.text")); // NOI18N
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 5);
|
||||
incidentTextPanel.add(importModuleDetected, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
@ -156,7 +203,7 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
|
||||
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 0);
|
||||
instructionsPanel.add(instructionsTextLabel, gridBagConstraints);
|
||||
instructionsTextLabel.getAccessibleContext().setAccessibleName("For instructions on obtaining the module refer to:");
|
||||
|
||||
@ -171,7 +218,7 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
|
||||
instructionsPanel.add(instructionsLinkLabel, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
@ -278,6 +325,7 @@ public class CTIncidentImportOptionsPanel extends CTOptionsSubPanel {
|
||||
private javax.swing.JLabel caseOpenWarningLabel;
|
||||
private javax.swing.JButton fileRepoBrowseButton;
|
||||
private javax.swing.JTextField fileRepoPathField;
|
||||
private javax.swing.JLabel importModuleDetected;
|
||||
private javax.swing.JLabel incidentTextLabel;
|
||||
private javax.swing.JPanel incidentTextPanel;
|
||||
private javax.swing.JLabel instructionsLinkLabel;
|
||||
|
@ -1,16 +1,21 @@
|
||||
/** *************************************************************************
|
||||
** This data and information is proprietary to, and a valuable trade secret
|
||||
** of, Sleuth Kit Labs. It is given in confidence by Sleuth Kit Labs
|
||||
** and may only be used as permitted under the license agreement under which
|
||||
** it has been distributed, and in no other way.
|
||||
**
|
||||
** Copyright (c) 2023 Sleuth Kit Labs, LLC. All rights reserved
|
||||
**
|
||||
** The technical data and information provided herein are provided with
|
||||
** `limited rights', and the computer software provided herein is provided
|
||||
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||
** 7-104.9(a).
|
||||
************************************************************************** */
|
||||
/*
|
||||
* 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.incidentoptions;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -19,35 +24,60 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.modules.Places;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
|
||||
/**
|
||||
* CT settings that don't include license information. This code must be kept in-sync with code in
|
||||
* CT Autopsy Importer NBM.
|
||||
* CT settings that don't include license information. This code must be kept
|
||||
* in-sync with code in CT Autopsy Importer NBM.
|
||||
*/
|
||||
public class CTSettings {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CTSettings.class.getCanonicalName());
|
||||
private static final String DEFAULT_FILE_REPO_PATH = getAppDataLocalDirectory();
|
||||
|
||||
// taken from com.basistech.df.cybertriage.utils.SystemProperties
|
||||
private static String getAppDataLocalDirectory() {
|
||||
private static final String CYBERTRIAGE_FOLDER = "cybertriage";
|
||||
private static final String CYBERTRIAGE_DOT_FOLDER = "." + CYBERTRIAGE_FOLDER;
|
||||
|
||||
Logger LOGGER = java.util.logging.Logger.getLogger(CTSettings.class.getCanonicalName());
|
||||
// based on com.basistech.df.cybertriage.utils.SystemProperties
|
||||
private static String getAppDataLocalDirectory() {
|
||||
if (Objects.nonNull(Places.getUserDirectory()) && Places.getUserDirectory().getAbsolutePath().endsWith("testuserdir")) { // APP is in testing .. this should return the test path
|
||||
LOGGER.log(Level.INFO, "Application Data (test mode) Path: " + Places.getUserDirectory().getAbsolutePath());
|
||||
return Places.getUserDirectory().getAbsolutePath();
|
||||
} else {
|
||||
Path localAppPath = Paths.get(System.getenv("LOCALAPPDATA"), "cybertriage");
|
||||
}
|
||||
|
||||
// try to use LOCALAPPDATA on windows
|
||||
String localDataStr = System.getenv("LOCALAPPDATA");
|
||||
if (StringUtils.isNotBlank(localDataStr)) {
|
||||
Path localAppPath = Paths.get(localDataStr, CYBERTRIAGE_FOLDER);
|
||||
try {
|
||||
Files.createDirectories(localAppPath);
|
||||
LOGGER.log(Level.INFO, "Application Data Path: " + localAppPath.toString());
|
||||
return localAppPath.toString();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, "IO Error, defaulting to user dir", ex);
|
||||
return Places.getUserDirectory().getAbsolutePath(); // In case of an IO Error
|
||||
LOGGER.log(Level.SEVERE, "IO Error using " + localAppPath.toString(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
// try to use ~/.cybertriage anywhere else
|
||||
if (!PlatformUtil.isWindowsOS()) {
|
||||
String homePathStr = System.getenv("HOME");
|
||||
if (StringUtils.isNotBlank(homePathStr)) {
|
||||
Path localAppPath = Paths.get(homePathStr, CYBERTRIAGE_DOT_FOLDER);
|
||||
try {
|
||||
Files.createDirectories(localAppPath);
|
||||
LOGGER.log(Level.INFO, "Non-windows Application Data Path: " + localAppPath.toString());
|
||||
return localAppPath.toString();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, "IO Error using " + localAppPath.toString(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// defer to user directory otherwise
|
||||
return Places.getUserDirectory().getAbsolutePath(); // In case of an IO Error
|
||||
}
|
||||
|
||||
public static String getDefaultFileRepoPath() {
|
||||
|
@ -1,16 +1,21 @@
|
||||
/** *************************************************************************
|
||||
** This data and information is proprietary to, and a valuable trade secret
|
||||
** of, Sleuth Kit Labs. It is given in confidence by Sleuth Kit Labs
|
||||
** and may only be used as permitted under the license agreement under which
|
||||
** it has been distributed, and in no other way.
|
||||
**
|
||||
** Copyright (c) 2023 Sleuth Kit Labs, LLC. All rights reserved
|
||||
**
|
||||
** The technical data and information provided herein are provided with
|
||||
** `limited rights', and the computer software provided herein is provided
|
||||
** with `restricted rights' as those terms are defined in DAR and ASPR
|
||||
** 7-104.9(a).
|
||||
************************************************************************** */
|
||||
/*
|
||||
* 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.incidentoptions;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
@ -23,6 +23,7 @@ import com.basistech.df.cybertriage.autopsy.ctapi.CTCloudException;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.AuthTokenResponse;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.AuthenticatedRequestData;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.CTCloudBean;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.FileUploadRequest;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseInfo;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.MalwareResultBean.Status;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.MetadataUploadRequest;
|
||||
@ -112,8 +113,10 @@ class MalwareScanIngestModule implements FileIngestModule {
|
||||
//minimum file uploads left before issuing warning
|
||||
private static final long LOW_UPLOADS_REMAINING = 25;
|
||||
|
||||
// min and max upload size in bytes
|
||||
private static final long MIN_UPLOAD_SIZE = 1;
|
||||
private static final long MAX_UPLOAD_SIZE = 1_000_000_000;
|
||||
private static final long MAX_UPLOAD_SIZE = 100_000_000; // 100MB
|
||||
|
||||
private static final int NUM_FILE_UPLOAD_RETRIES = 7;
|
||||
private static final long FILE_UPLOAD_RETRY_SLEEP_MILLIS = 60 * 1000;
|
||||
|
||||
@ -131,8 +134,7 @@ class MalwareScanIngestModule implements FileIngestModule {
|
||||
"application/x-msdos-program"//NON-NLS
|
||||
).collect(Collectors.toSet());
|
||||
|
||||
private static final String MALWARE_TYPE_NAME = "TSK_MALWARE";
|
||||
private static final String MALWARE_CONFIG = "Cyber Triage Cloud";
|
||||
private static final String MALWARE_CONFIG = ""; // NOTE: Adding a configuration complicates NTL branch UI
|
||||
|
||||
private static final Logger logger = Logger.getLogger(MalwareScanIngestModule.class.getName());
|
||||
|
||||
@ -232,18 +234,13 @@ class MalwareScanIngestModule implements FileIngestModule {
|
||||
|
||||
// setup necessary variables for processing
|
||||
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
BlackboardArtifact.Type malwareType = tskCase.getBlackboard().getOrAddArtifactType(
|
||||
MALWARE_TYPE_NAME,
|
||||
Bundle.MalwareScanIngestModule_malwareTypeDisplayName(),
|
||||
BlackboardArtifact.Category.ANALYSIS_RESULT);
|
||||
|
||||
return new IngestJobState(
|
||||
context,
|
||||
tskCase,
|
||||
new PathNormalizer(tskCase),
|
||||
new FileTypeDetector(),
|
||||
licenseInfoOpt.get(),
|
||||
malwareType,
|
||||
BlackboardArtifact.Type.TSK_MALWARE,
|
||||
uploadFiles,
|
||||
true
|
||||
);
|
||||
@ -640,7 +637,7 @@ class MalwareScanIngestModule implements FileIngestModule {
|
||||
}
|
||||
|
||||
// get auth token / file upload url
|
||||
AuthTokenResponse authTokenResponse = ctApiDAO.getAuthToken(ingestJobState.getLicenseInfo().getDecryptedLicense(), true);
|
||||
AuthTokenResponse authTokenResponse = ctApiDAO.getAuthToken(ingestJobState.getLicenseInfo().getDecryptedLicense(), af.getSize());
|
||||
if (StringUtils.isBlank(authTokenResponse.getFileUploadUrl())) {
|
||||
throw new CTCloudException(CTCloudException.ErrorCode.NETWORK_ERROR);
|
||||
} else if (remaining(authTokenResponse.getFileUploadLimit(), authTokenResponse.getFileUploadCount()) <= 0) {
|
||||
@ -658,7 +655,13 @@ class MalwareScanIngestModule implements FileIngestModule {
|
||||
|
||||
// upload bytes
|
||||
ReadContentInputStream fileInputStream = new ReadContentInputStream(af);
|
||||
ctApiDAO.uploadFile(authTokenResponse.getFileUploadUrl(), af.getName(), fileInputStream);
|
||||
|
||||
ctApiDAO.uploadFile(new FileUploadRequest()
|
||||
.setContentLength(af.getSize())
|
||||
.setFileInputStream(fileInputStream)
|
||||
.setFileName(af.getName())
|
||||
.setFullUrlPath(authTokenResponse.getFileUploadUrl())
|
||||
);
|
||||
|
||||
// upload metadata
|
||||
MetadataUploadRequest metaRequest = new MetadataUploadRequest()
|
||||
@ -700,6 +703,7 @@ class MalwareScanIngestModule implements FileIngestModule {
|
||||
Bundle.MalwareScanIngestModule_longPollForNotFound_fileLookupPolling_title(),
|
||||
Bundle.MalwareScanIngestModule_longPollForNotFound_fileLookupPolling_desc()
|
||||
);
|
||||
logger.log(Level.INFO, "Begin polling for malware status of file uploads.");
|
||||
|
||||
Map<String, List<Long>> remaining = new HashMap<>(ingestJobState.getUnidentifiedHashes());
|
||||
|
||||
@ -735,6 +739,9 @@ class MalwareScanIngestModule implements FileIngestModule {
|
||||
|
||||
// exponential backoff before trying again
|
||||
long waitMultiplier = ((long) Math.pow(2, retry));
|
||||
|
||||
logger.log(Level.INFO, MessageFormat.format("Waiting {0} milliseconds before polling again for malware status of file uploads.", (waitMultiplier * FILE_UPLOAD_RETRY_SLEEP_MILLIS)));
|
||||
|
||||
for (int i = 0; i < waitMultiplier; i++) {
|
||||
if (!ingestJobState.isDoFileLookups() || ingestJobState.getIngestJobContext().fileIngestIsCancelled()) {
|
||||
return;
|
||||
|
@ -66,8 +66,8 @@ Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the
|
||||
Case.open.msgDlg.updated.title=Case Database Schema Update
|
||||
Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\
|
||||
this case are missing. Would you like to search for them now?\n\
|
||||
Previously, the image was located at:\n\
|
||||
{0}\n\
|
||||
Previously, the image with host, {0}, was located at:\n\
|
||||
{1}\n\
|
||||
Please note that you will still be able to browse directories and generate reports\n\
|
||||
if you choose No, but you will not be able to view file content or run the ingest process.
|
||||
Case.checkImgExist.confDlg.doesntExist.title=Missing Image
|
||||
|
@ -253,8 +253,8 @@ Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the
|
||||
Case.open.msgDlg.updated.title=Case Database Schema Update
|
||||
Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\
|
||||
this case are missing. Would you like to search for them now?\n\
|
||||
Previously, the image was located at:\n\
|
||||
{0}\n\
|
||||
Previously, the image with host, {0}, was located at:\n\
|
||||
{1}\n\
|
||||
Please note that you will still be able to browse directories and generate reports\n\
|
||||
if you choose No, but you will not be able to view file content or run the ingest process.
|
||||
Case.checkImgExist.confDlg.doesntExist.title=Missing Image
|
||||
|
@ -194,6 +194,8 @@ public class Case {
|
||||
private final SleuthkitEventListener sleuthkitEventListener;
|
||||
private CollaborationMonitor collaborationMonitor;
|
||||
private Services caseServices;
|
||||
// matches something like '\\.\PHYSICALDRIVE0'
|
||||
private static final String PLACEHOLDER_DS_PATH_REGEX = "^\\s*\\\\\\\\\\.\\\\PHYSICALDRIVE\\d*\\s*$";
|
||||
|
||||
private volatile boolean hasDataSource = false;
|
||||
private volatile boolean hasData = false;
|
||||
@ -1303,9 +1305,18 @@ public class Case {
|
||||
for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
|
||||
long obj_id = entry.getKey();
|
||||
String path = entry.getValue();
|
||||
boolean fileExists = (new File(path).isFile() || DriveUtils.driveExists(path));
|
||||
boolean fileExists = (new File(path).exists()|| DriveUtils.driveExists(path));
|
||||
if (!fileExists) {
|
||||
// CT-7336: ignore relocating datasources if file provider is present and placeholder path is used.
|
||||
if (newCurrentCase.getMetadata() != null
|
||||
&& !StringUtils.isBlank(newCurrentCase.getMetadata().getContentProviderName())
|
||||
&& (path == null || path.matches(PLACEHOLDER_DS_PATH_REGEX))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
DataSource ds = newCurrentCase.getSleuthkitCase().getDataSource(obj_id);
|
||||
String hostName = StringUtils.defaultString(ds.getHost() == null ? "" : ds.getHost().getName());
|
||||
// Using invokeAndWait means that the dialog will
|
||||
// open on the EDT but this thread will wait for an
|
||||
// answer. Using invokeLater would cause this loop to
|
||||
@ -1315,7 +1326,7 @@ public class Case {
|
||||
public void run() {
|
||||
int response = JOptionPane.showConfirmDialog(
|
||||
mainFrame,
|
||||
NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.msg", path),
|
||||
NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.msg", hostName, path),
|
||||
NbBundle.getMessage(Case.class, "Case.checkImgExist.confDlg.doesntExist.title"),
|
||||
JOptionPane.YES_NO_OPTION);
|
||||
if (response == JOptionPane.YES_OPTION) {
|
||||
@ -1327,7 +1338,7 @@ public class Case {
|
||||
}
|
||||
|
||||
});
|
||||
} catch (InterruptedException | InvocationTargetException ex) {
|
||||
} catch (InterruptedException | InvocationTargetException | TskCoreException | TskDataException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to show missing image confirmation dialog", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_INTERESTING_IT
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_TL_EVENT;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_ASSOCIATED_OBJECT;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_KEYWORD_HIT;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_MALWARE;
|
||||
|
||||
/**
|
||||
* Classes for creating nodes for BlackboardArtifacts.
|
||||
@ -73,10 +74,6 @@ public class Artifacts {
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST
|
||||
= EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED);
|
||||
|
||||
// this is currently a custom TSK artifact type, created in MalwareScanIngestModule
|
||||
private static BlackboardArtifact.Type MALWARE_ARTIFACT_TYPE = null;
|
||||
private static final String MALWARE_HITS = "TSK_MALWARE";
|
||||
|
||||
/**
|
||||
* Base class for a parent node of artifacts.
|
||||
*/
|
||||
@ -247,15 +244,6 @@ public class Artifacts {
|
||||
@SuppressWarnings("deprecation")
|
||||
private static TypeNodeKey getTypeKey(BlackboardArtifact.Type type, SleuthkitCase skCase, long dsObjId) {
|
||||
|
||||
// Get the custom TSK_MALWARE artifact type from case database
|
||||
if (MALWARE_ARTIFACT_TYPE == null) {
|
||||
try {
|
||||
MALWARE_ARTIFACT_TYPE = skCase.getArtifactType(MALWARE_HITS);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get TSK_MALWARE artifact type from database : ", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
int typeId = type.getTypeID();
|
||||
if (TSK_EMAIL_MSG.getTypeID() == typeId) {
|
||||
EmailExtracted.RootNode emailNode = new EmailExtracted(skCase, dsObjId).new RootNode();
|
||||
@ -281,9 +269,9 @@ public class Artifacts {
|
||||
} else if (TSK_HASHSET_HIT.getTypeID() == typeId) {
|
||||
HashsetHits.RootNode hashsetHits = new HashsetHits(skCase, dsObjId).new RootNode();
|
||||
return new TypeNodeKey(hashsetHits, TSK_HASHSET_HIT);
|
||||
} else if (MALWARE_ARTIFACT_TYPE != null && MALWARE_ARTIFACT_TYPE.getTypeID() == typeId) {
|
||||
} else if (TSK_MALWARE.getTypeID() == typeId) {
|
||||
MalwareHits.RootNode malwareHits = new MalwareHits(skCase, dsObjId).new RootNode();
|
||||
return new TypeNodeKey(malwareHits, MALWARE_ARTIFACT_TYPE);
|
||||
return new TypeNodeKey(malwareHits, TSK_MALWARE);
|
||||
} else {
|
||||
return new TypeNodeKey(type, dsObjId);
|
||||
}
|
||||
|
@ -44,12 +44,12 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode;
|
||||
import org.sleuthkit.datamodel.AnalysisResult;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.Type.TSK_MALWARE;
|
||||
import org.sleuthkit.datamodel.Score;
|
||||
|
||||
/**
|
||||
@ -57,9 +57,6 @@ import org.sleuthkit.datamodel.Score;
|
||||
*/
|
||||
public class MalwareHits implements AutopsyVisitableItem {
|
||||
|
||||
private static final String MALWARE_HITS = "TSK_MALWARE"; // this is currently a custom TSK artifact type, created in MalwareScanIngestModule
|
||||
private static BlackboardArtifact.Type MALWARE_ARTIFACT_TYPE = null;
|
||||
private static String DISPLAY_NAME;
|
||||
private static final Logger logger = Logger.getLogger(MalwareHits.class.getName());
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED);
|
||||
private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestModuleEvent.DATA_ADDED);
|
||||
@ -126,20 +123,9 @@ public class MalwareHits implements AutopsyVisitableItem {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the custom TSK_MALWARE artifact type from case database
|
||||
if (MALWARE_ARTIFACT_TYPE == null) {
|
||||
try {
|
||||
MALWARE_ARTIFACT_TYPE = skCase.getArtifactType(MALWARE_HITS);
|
||||
DISPLAY_NAME = MALWARE_ARTIFACT_TYPE.getDisplayName();
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get TSK_MALWARE artifact type from database : ", ex); //NON-NLS
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String query = "SELECT blackboard_artifacts.artifact_obj_id " //NON-NLS
|
||||
+ "FROM blackboard_artifacts,tsk_analysis_results WHERE " //NON-NLS
|
||||
+ "blackboard_artifacts.artifact_type_id=" + MALWARE_ARTIFACT_TYPE.getTypeID() //NON-NLS
|
||||
+ "blackboard_artifacts.artifact_type_id=" + TSK_MALWARE.getTypeID() //NON-NLS
|
||||
+ " AND tsk_analysis_results.artifact_obj_id=blackboard_artifacts.artifact_obj_id" //NON-NLS
|
||||
+ " AND (tsk_analysis_results.significance=" + Score.Significance.NOTABLE.getId() //NON-NLS
|
||||
+ " OR tsk_analysis_results.significance=" + Score.Significance.LIKELY_NOTABLE.getId() + " )"; //NON-NLS
|
||||
@ -182,7 +168,7 @@ public class MalwareHits implements AutopsyVisitableItem {
|
||||
* oldValue if the event is a remote event.
|
||||
*/
|
||||
ModuleDataEvent eventData = (ModuleDataEvent) evt.getOldValue();
|
||||
if (null != eventData && eventData.getBlackboardArtifactType().getTypeID() == MALWARE_ARTIFACT_TYPE.getTypeID()) {
|
||||
if (null != eventData && eventData.getBlackboardArtifactType().getTypeID() == TSK_MALWARE.getTypeID()) {
|
||||
malwareResults.update();
|
||||
}
|
||||
} catch (NoCurrentCaseException notUsed) {
|
||||
@ -248,13 +234,13 @@ public class MalwareHits implements AutopsyVisitableItem {
|
||||
public class RootNode extends UpdatableCountTypeNode {
|
||||
|
||||
public RootNode() {
|
||||
super(Children.create(new HitFactory(DISPLAY_NAME), true),
|
||||
Lookups.singleton(DISPLAY_NAME),
|
||||
DISPLAY_NAME,
|
||||
super(Children.create(new HitFactory(TSK_MALWARE.getDisplayName()), true),
|
||||
Lookups.singleton(TSK_MALWARE.getDisplayName()),
|
||||
TSK_MALWARE.getDisplayName(),
|
||||
filteringDSObjId,
|
||||
MALWARE_ARTIFACT_TYPE);
|
||||
TSK_MALWARE);
|
||||
|
||||
super.setName(MALWARE_HITS);
|
||||
super.setName(TSK_MALWARE.getTypeName());
|
||||
// TODO make an icon
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/artifact-icon.png");
|
||||
}
|
||||
@ -297,7 +283,7 @@ public class MalwareHits implements AutopsyVisitableItem {
|
||||
*/
|
||||
@Override
|
||||
void updateDisplayName() {
|
||||
super.setDisplayName(DISPLAY_NAME + " (" + malwareResults.getArtifactIds().size() + ")");
|
||||
super.setDisplayName(TSK_MALWARE.getDisplayName() + " (" + malwareResults.getArtifactIds().size() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
Manifest-Version: 1.0
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.corelibs/3
|
||||
OpenIDE-Module-Implementation-Version: 7
|
||||
OpenIDE-Module-Implementation-Version: 8
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/corelibs/Bundle.properties
|
||||
OpenIDE-Module-Specification-Version: 1.4
|
||||
AutoUpdate-Show-In-Client: true
|
||||
|
@ -144,7 +144,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.24</specification-version>
|
||||
<specification-version>10.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -162,7 +162,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>6</release-version>
|
||||
<specification-version>6.6</specification-version>
|
||||
<specification-version>6.7</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
|
@ -127,7 +127,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.24</specification-version>
|
||||
<specification-version>10.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -1,7 +1,7 @@
|
||||
Manifest-Version: 1.0
|
||||
AutoUpdate-Show-In-Client: true
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.keywordsearch/6
|
||||
OpenIDE-Module-Implementation-Version: 23
|
||||
OpenIDE-Module-Implementation-Version: 24
|
||||
OpenIDE-Module-Install: org/sleuthkit/autopsy/keywordsearch/Installer.class
|
||||
OpenIDE-Module-Layer: org/sleuthkit/autopsy/keywordsearch/layer.xml
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/keywordsearch/Bundle.properties
|
||||
|
@ -48,4 +48,4 @@ javac.compilerargs=-Xlint -Xlint:-serial
|
||||
license.file=../LICENSE-2.0.txt
|
||||
nbm.homepage=http://www.sleuthkit.org/autopsy/
|
||||
nbm.needs.restart=true
|
||||
spec.version.base=6.6
|
||||
spec.version.base=6.7
|
||||
|
@ -128,7 +128,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.24</specification-version>
|
||||
<specification-version>10.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
4
NEWS.txt
4
NEWS.txt
@ -9,7 +9,7 @@ Library Updates
|
||||
Ingest Module Updates:
|
||||
- Recent Activity checks for malicious Chrome extensions from list provided by https://github.com/randomaccess3/detections
|
||||
- Keyword Search module now can search without needing to index text into Solr.
|
||||
- New Cyber Triage Malware Scanner module that uses Reversing Labs (requires license)
|
||||
- New Cyber Triage Malware Scanner module that uses Reversing Labs (requires license). https://www.cybertriage.com/autopsy-malware-module/
|
||||
|
||||
Add Data Source Updates:
|
||||
- Timestamps for logical files can be added. Issue https://github.com/sleuthkit/autopsy/issues/5852, https://github.com/sleuthkit/autopsy/issues/1788
|
||||
@ -24,7 +24,7 @@ Bugs:
|
||||
- Fix exporting of CSV files. Issue https://github.com/sleuthkit/autopsy/issues/6717
|
||||
|
||||
Misc:
|
||||
- Added File Repository concept for data source files that are in a central location
|
||||
- Added File Repository concept for data source files that are in a central location. Required for Cyber Triage import feature.
|
||||
- Added Spanish language support, contributor https://github.com/AburtoArielPM
|
||||
|
||||
---------------- VERSION 4.20.0 --------------
|
||||
|
@ -1,6 +1,6 @@
|
||||
Manifest-Version: 1.0
|
||||
OpenIDE-Module: org.sleuthkit.autopsy.recentactivity/6
|
||||
OpenIDE-Module-Implementation-Version: 19
|
||||
OpenIDE-Module-Implementation-Version: 20
|
||||
OpenIDE-Module-Layer: org/sleuthkit/autopsy/recentactivity/layer.xml
|
||||
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/recentactivity/Bundle.properties
|
||||
OpenIDE-Module-Requires:
|
||||
|
@ -1,3 +1,3 @@
|
||||
<project name="TSK_VERSION">
|
||||
<property name="TSK_VERSION" value="4.12.0"/>
|
||||
<property name="TSK_VERSION" value="4.12.1"/>
|
||||
</project>
|
||||
|
@ -47,7 +47,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.24</specification-version>
|
||||
<specification-version>10.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -73,7 +73,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>6</release-version>
|
||||
<specification-version>6.6</specification-version>
|
||||
<specification-version>6.7</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
|
@ -9,18 +9,23 @@ The Cyber Triage Malware Scanner module will use the malware scanning infrastruc
|
||||
|
||||
This module requires a commercial license from Cyber Triage.
|
||||
|
||||
For more information on obtaining a license, refer to [CyberTriage.com](https://cybertriage.com/autopsy-malware-module). The remainder of this page is about the use of the module once it is licensed.
|
||||
For more information on what the module does or obtaining a license, refer to [CyberTriage.com](https://cybertriage.com/autopsy-malware-module). The remainder of this page is about the use of the module once it is licensed.
|
||||
|
||||
|
||||
Configuration
|
||||
=======
|
||||
==============
|
||||
|
||||
Once you have a license, you must add it on the Options panel. Choose the 'Cyber Triage' tab and choose 'Add License'.
|
||||
You will need to first get a paid or eval license from the above URL. The code will come in via email. Example license formats include:
|
||||
|
||||
- AUT-8ed86eb5-17fc-4b3a-9b75-ce638c11b070
|
||||
- b826a555-951f-42ca-86ce-439a81106688
|
||||
|
||||
\image html Malware-scanner-global-options-panel-no-license.png
|
||||
Once you have a license, you must add it on the Autopsy Options panel.
|
||||
Choose the 'Cyber Triage' tab and choose 'Add License'.
|
||||
|
||||
After you enter the license number that you should have received from your email, you will then need to review and agree to the license terms.
|
||||
\image html malware-scanner-global-options-panel-no-license.png
|
||||
|
||||
After you enter the license number from your email, you will then need to review and agree to the license terms.
|
||||
|
||||
|
||||
The options panel should now display information about the lookup limits. You can always refer back to here about what your limits are and when they reset.
|
||||
@ -35,7 +40,7 @@ Using the Module
|
||||
Ingest Settings
|
||||
------
|
||||
|
||||
For each data source, you select if you want files to be uploaded if they have not already been analyzed. By default, they are uploaded. You can choose to not upload them though.
|
||||
For each data source, you select if you want files to be uploaded if they have not already been analyzed. By default, they are uploaded. You can choose to not upload them though. Refer to the main [website](https://cybertriage.com/autopsy-malware-module) for details on what happens when files are uploaded.
|
||||
|
||||
\image html malware-scanner-ingest-panel.png
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<hr/>
|
||||
<p><i>Copyright © 2012-2022 Basis Technology. Generated on $date<br/>
|
||||
<p><i>Copyright © 2012-2023 BasisTech. Generated on $date<br/>
|
||||
This work is licensed under a
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/us/">Creative Commons Attribution-Share Alike 3.0 United States License</a>.
|
||||
</i></p>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 55 KiB |
Binary file not shown.
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 78 KiB |
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 59 KiB |
@ -4,7 +4,7 @@ app.title=Autopsy
|
||||
### lowercase version of above
|
||||
app.name=${branding.token}
|
||||
### if left unset, version will default to today's date
|
||||
app.version=4.20.0
|
||||
app.version=4.21.0
|
||||
### build.type must be one of: DEVELOPMENT, RELEASE
|
||||
#build.type=RELEASE
|
||||
build.type=DEVELOPMENT
|
||||
|
@ -33,7 +33,7 @@ sub main {
|
||||
update_core_project_xml();
|
||||
update_unix_setup();
|
||||
|
||||
print "Files updated. You need to commit and push them\n";
|
||||
print "Files updated and added to git. You need to commit (no -a) and push.\n";
|
||||
}
|
||||
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>10</release-version>
|
||||
<specification-version>10.24</specification-version>
|
||||
<specification-version>10.25</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
# NOTE: update_sleuthkit_version.pl updates this value and relies
|
||||
# on it keeping the same name and whitespace. Don't change it.
|
||||
TSK_VERSION=4.12.0
|
||||
TSK_VERSION=4.12.1
|
||||
|
||||
|
||||
usage() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user