mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
file upload
This commit is contained in:
parent
b16cbe6c1d
commit
8809569567
@ -21,17 +21,13 @@ package com.basistech.df.cybertriage.autopsy.ctapi;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.util.ObjectMapperUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.Authenticator;
|
||||
import java.net.InetAddress;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -41,13 +37,7 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
@ -64,7 +54,9 @@ 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.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;
|
||||
@ -175,10 +167,14 @@ public class CTCloudHttpClient {
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
LOGGER.log(Level.INFO, "Response Received. - Status OK");
|
||||
// Parse Response
|
||||
HttpEntity entity = response.getEntity();
|
||||
String entityStr = EntityUtils.toString(entity);
|
||||
O respObj = mapper.readValue(entityStr, classType);
|
||||
return respObj;
|
||||
if (classType != null) {
|
||||
HttpEntity entity = response.getEntity();
|
||||
String entityStr = EntityUtils.toString(entity);
|
||||
O respObj = mapper.readValue(entityStr, classType);
|
||||
return respObj;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
LOGGER.log(Level.WARNING, "Response Received. - Status Error {}", response.getStatusLine());
|
||||
handleNonOKResponse(response, "");
|
||||
@ -198,6 +194,40 @@ public class CTCloudHttpClient {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void doFileUploadPost(String urlPath, String fileName, InputStream fileIs) throws CTCloudException {
|
||||
|
||||
try (CloseableHttpClient httpclient = createConnection(getProxySettings(), sslContext)) {
|
||||
HttpPost post = new HttpPost(urlPath);
|
||||
configureRequestTimeout(post);
|
||||
|
||||
post.addHeader("Connection", "keep-alive");
|
||||
|
||||
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)) {
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_NO_CONTENT) {
|
||||
LOGGER.log(Level.INFO, "Response Received. - Status OK");
|
||||
} else {
|
||||
LOGGER.log(Level.WARNING, MessageFormat.format("Response Received. - Status Error {0}", response.getStatusLine()));
|
||||
handleNonOKResponse(response, fileName);
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "IO Exception raised when connecting to Reversing Labs for file content upload ", ex);
|
||||
throw new CTCloudException(CTCloudException.ErrorCode.NETWORK_ERROR, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic way to handle the HTTP response - when the response code is NOT
|
||||
|
@ -27,7 +27,9 @@ 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.LicenseRequest;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.LicenseResponse;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.MetadataUploadRequest;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.util.CTHostIDGenerationUtil;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -44,6 +46,8 @@ public class CTApiDAO {
|
||||
private static final String LICENSE_REQUEST_PATH = "/_ah/api/license/v1/activate";
|
||||
private static final String AUTH_TOKEN_REQUEST_PATH = "/_ah/api/auth/v2/generate_token";
|
||||
private static final String CTCLOUD_SERVER_HASH_PATH = "/_ah/api/reputation/v1/query/file/hash/md5?query_types=CORRELATION,MALWARE";
|
||||
private static final String CTCLOUD_UPLOAD_FILE_METADATA_PATH = "/_ah/api/reputation/v1/upload/meta";
|
||||
|
||||
private static final String AUTOPSY_PRODUCT = "AUTOPSY";
|
||||
|
||||
private static final CTApiDAO instance = new CTApiDAO();
|
||||
@ -72,15 +76,27 @@ public class CTApiDAO {
|
||||
}
|
||||
|
||||
public AuthTokenResponse getAuthToken(DecryptedLicenseResponse decrypted) throws CTCloudException {
|
||||
return getAuthToken(decrypted, false);
|
||||
}
|
||||
|
||||
public AuthTokenResponse getAuthToken(DecryptedLicenseResponse decrypted, boolean fileUpload) throws CTCloudException {
|
||||
AuthTokenRequest authTokenRequest = new AuthTokenRequest()
|
||||
.setAutopsyVersion(getAppVersion())
|
||||
.setRequestFileUpload(false)
|
||||
.setRequestFileUpload(fileUpload)
|
||||
.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 uploadMeta(AuthenticatedRequestData authenticatedRequestData, MetadataUploadRequest metaRequest) throws CTCloudException {
|
||||
httpClient.doPost(AUTH_TOKEN_REQUEST_PATH, getAuthParams(authenticatedRequestData), metaRequest, null);
|
||||
}
|
||||
|
||||
private static Map<String, String> getAuthParams(AuthenticatedRequestData authenticatedRequestData) {
|
||||
return new HashMap<String, String>() {
|
||||
{
|
||||
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class MetadataUploadRequest {
|
||||
|
||||
@JsonProperty("file_upload_url")
|
||||
private String fileUploadUrl;
|
||||
|
||||
@JsonProperty("sha1")
|
||||
private String sha1;
|
||||
|
||||
@JsonProperty("sha256")
|
||||
private String sha256;
|
||||
|
||||
@JsonProperty("md5")
|
||||
private String md5;
|
||||
|
||||
@JsonProperty("filePath")
|
||||
private String filePath;
|
||||
|
||||
@JsonProperty("fileSize")
|
||||
private long fileSizeBytes;
|
||||
|
||||
@JsonProperty("createdDate")
|
||||
private long createdDate;
|
||||
|
||||
public String getFileUploadUrl() {
|
||||
return fileUploadUrl;
|
||||
}
|
||||
|
||||
public MetadataUploadRequest setFileUploadUrl(String fileUploadUrl) {
|
||||
this.fileUploadUrl = fileUploadUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSha1() {
|
||||
return sha1;
|
||||
}
|
||||
|
||||
public MetadataUploadRequest setSha1(String sha1) {
|
||||
this.sha1 = sha1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSha256() {
|
||||
return sha256;
|
||||
}
|
||||
|
||||
public MetadataUploadRequest setSha256(String sha256) {
|
||||
this.sha256 = sha256;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMd5() {
|
||||
return md5;
|
||||
}
|
||||
|
||||
public MetadataUploadRequest setMd5(String md5) {
|
||||
this.md5 = md5;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public MetadataUploadRequest setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getFileSizeBytes() {
|
||||
return fileSizeBytes;
|
||||
}
|
||||
|
||||
public MetadataUploadRequest setFileSizeBytes(long fileSizeBytes) {
|
||||
this.fileSizeBytes = fileSizeBytes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getCreatedDate() {
|
||||
return createdDate;
|
||||
}
|
||||
|
||||
public MetadataUploadRequest setCreatedDate(long createdDate) {
|
||||
this.createdDate = createdDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.basistech.df.cybertriage.autopsy.ctapi.CTApiDAO;
|
||||
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.DecryptedLicenseResponse;
|
||||
import com.basistech.df.cybertriage.autopsy.ctapi.json.MetadataUploadRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Handles uploading of files that are unknown.
|
||||
*/
|
||||
public class FileUpload {
|
||||
|
||||
private final CTApiDAO ctApiDAO = CTApiDAO.getInstance();
|
||||
|
||||
private boolean isUnknown(CTCloudBean cloudBean) {
|
||||
|
||||
}
|
||||
|
||||
private boolean isUploadable(AbstractFile af) {
|
||||
|
||||
}
|
||||
|
||||
public boolean tryUpload(SleuthkitCase skCase, CTCloudBean cloudBean, long objId) {
|
||||
|
||||
}
|
||||
|
||||
private boolean upload(DecryptedLicenseResponse decrypted, AbstractFile af) throws CTCloudException, TskCoreException {
|
||||
// get auth token / file upload url
|
||||
AuthTokenResponse authTokenResponse = ctApiDAO.getAuthToken(decrypted, true);
|
||||
if (StringUtils.isBlank(authTokenResponse.getFileUploadUrl())) {
|
||||
throw new CTCloudException(CTCloudException.ErrorCode.NETWORK_ERROR);
|
||||
}
|
||||
|
||||
// upload bytes
|
||||
ReadContentInputStream fileInputStream = new ReadContentInputStream(af);
|
||||
ctApiDAO.uploadFile(authTokenResponse.getFileUploadUrl(), af.getName(), fileInputStream);
|
||||
|
||||
// upload metadata
|
||||
MetadataUploadRequest metaRequest = new MetadataUploadRequest()
|
||||
.setCreatedDate(af.getCrtime())
|
||||
.setFilePath(af.getUniquePath())
|
||||
.setFileSizeBytes(af.getSize())
|
||||
.setFileUploadUrl(authTokenResponse.getFileUploadUrl())
|
||||
.setMd5(af.getMd5Hash())
|
||||
.setSha1(af.getSha1Hash())
|
||||
.setSha256(af.getSha256Hash());
|
||||
|
||||
ctApiDAO.uploadMeta(new AuthenticatedRequestData(decrypted, authTokenResponse), metaRequest);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user