From d20075c17f8980a6cfd2a9cc1bd27e469401cbdf Mon Sep 17 00:00:00 2001 From: Antun Kukolja Date: Mon, 24 Jun 2024 17:09:36 +0200 Subject: [PATCH 1/4] Fix sample reputation override example --- TitaniumCloud/sample_management.ipynb | 187 ++++++++++++++------------ 1 file changed, 104 insertions(+), 83 deletions(-) diff --git a/TitaniumCloud/sample_management.ipynb b/TitaniumCloud/sample_management.ipynb index a6bd86f..e67e224 100644 --- a/TitaniumCloud/sample_management.ipynb +++ b/TitaniumCloud/sample_management.ipynb @@ -41,16 +41,12 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": { - "ExecuteTime": { - "end_time": "2024-06-24T13:00:18.771975493Z", - "start_time": "2024-06-24T13:00:18.731201662Z" - } - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ - "from ReversingLabs.SDK.ticloud import FileUpload, FileDownload, ReanalyzeFile, DeleteFile" + "from ReversingLabs.SDK.ticloud import FileUpload, FileDownload, ReanalyzeFile, DeleteFile, FileReputationUserOverride, FileReputation, calculate_hash\n", + "from ReversingLabs.SDK.helper import SHA1, SHA256, MD5" ] }, { @@ -66,13 +62,8 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": { - "ExecuteTime": { - "end_time": "2024-06-24T13:00:25.846033807Z", - "start_time": "2024-06-24T13:00:25.842115172Z" - } - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "import json\n", @@ -99,24 +90,11 @@ }, { "cell_type": "code", - "execution_count": 4, - "metadata": { - "ExecuteTime": { - "end_time": "2024-06-24T13:01:24.894826465Z", - "start_time": "2024-06-24T13:01:24.346445039Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "200\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "FILE_NAME = \"file_name_placeholder\"\n", + "FILE_NAME = \"README.md\"\n", "\n", "file_upload = FileUpload(\n", " host=\"https://data.reversinglabs.com\",\n", @@ -125,10 +103,20 @@ " user_agent=USER_AGENT\n", ")\n", "\n", + "with open(FILE_NAME, \"rb\") as sample:\n", + " sample_md5 = calculate_hash(data_input=sample, hashing_algorithm=MD5)\n", + " sample.seek(0)\n", + " sample_sha1 = calculate_hash(data_input=sample, hashing_algorithm=SHA1)\n", + " sample.seek(0)\n", + " sample_sha256 = calculate_hash(data_input=sample, hashing_algorithm=SHA256)\n", + "\n", "upload_response = file_upload.upload_sample_from_path(file_path=FILE_NAME)\n", "\n", "status_code = upload_response.status_code\n", - "print(status_code)" + "print(status_code)\n", + "print(\"md5\", sample_md5)\n", + "print(\"sha1\", sample_sha1)\n", + "print(\"sha256\", sample_sha256)" ] }, { @@ -154,7 +142,7 @@ "metadata": {}, "outputs": [], "source": [ - "FILE_HASH = \"sha1_hash_placeholder\"\n", + "FILE_HASH = \"8e21cde3f269b7f359eb8903a130ab11e060325069e16c0ba1674c141d6c9d01\"\n", "\n", "file_download = FileDownload(\n", " host=\"https://data.reversinglabs.com\",\n", @@ -188,22 +176,9 @@ }, { "cell_type": "code", - "execution_count": 7, - "metadata": { - "ExecuteTime": { - "end_time": "2024-06-24T13:15:51.128618407Z", - "start_time": "2024-06-24T13:15:51.049367153Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Sample sent for rescanning\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "reanalyze = ReanalyzeFile(\n", " host=\"https://data.reversinglabs.com\",\n", @@ -228,9 +203,9 @@ "`Sample sent for rescanning`\n", "\n", "\n", - "### 6. Delete file\n", - "In case we no longer want a file to be present in the cloud and available for analysis or download, we can delete it.\n", - "To delete a file from the TitaniumCloud, we will use the `DeleteFile` class." + "### 6. Sample reputation override\n", + "In case we wish to override the classification provided to a sample by Titanium Cloud we can use the FileReputationUserOverride class to do so.\n", + "But before we do that let's see if our sample already has an override on its classification." ] }, { @@ -239,17 +214,12 @@ "metadata": {}, "outputs": [], "source": [ - "delete_file = DeleteFile(\n", + "file_reputation_override = FileReputationUserOverride(\n", " host=\"https://data.reversinglabs.com\",\n", " username=USERNAME,\n", " password=PASSWORD,\n", " user_agent=USER_AGENT\n", - ")\n", - "\n", - "delete_response = delete_file.delete_samples(sample_hashes=FILE_HASH)\n", - "\n", - "response_text = delete_response.text\n", - "print(response_text)" + ")" ] }, { @@ -258,28 +228,89 @@ "collapsed": false }, "source": [ - "Again, we used the same file hash. If our file deletion request was successful, the response text will have a non-empty list called `deleted_hashes`. This list carries the hashes of files that have successfully been deleted with this request." + "We do this by requesting a collection of all sample hashes of a specific hash type.\n", + "In this example we use the SHA256 algorithm.\n", + "We check the first page to see if our sample is present." ] }, { "cell_type": "code", - "execution_count": null, "outputs": [], "source": [ "file_override_response = file_reputation_override.list_active_overrides(\"sha256\")\n", - "print(file_override_response.text)\n", + "count = len(file_override_response.json()[\"rl\"][\"user_override\"][\"hash_values\"])\n", + "has_more = \"more\" if file_override_response.json()[\"rl\"][\"user_override\"].get(\"has_next\") else \"no more\"\n", + "print(f\"Found {count} samples with overridden classification, there are {has_more} such samples\")\n", "is_in = \"in\" if file_override_response.text.find(sample_sha256) != -1 else \"not in\"\n", - "print(\"\")\n", "print(f\"Sample is {is_in} the returned response page\")" ], + "metadata": { + "collapsed": false + }, + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "Now we will add override the reputation to be malicious.\n", + "We will then retrieve it from TiCloud and see how our change affects the output." + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "file_reputation_override_response = file_reputation_override.override_classification(\n", + " override_samples=[{\n", + " \"md5\": sample_md5,\n", + " \"sha1\": sample_sha1,\n", + " \"sha256\": sample_sha256,\n", + " \"status\": \"MALICIOUS\"\n", + " }]\n", + ")\n", + "print(file_reputation_override_response.status_code)\n", + "print(json.dumps(file_reputation_override_response.json(), indent=1))" + ], + "metadata": { + "collapsed": false + }, + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "You might need to give TiCloud a moment to propagate the new classification through the system." + ], "metadata": { "collapsed": false } }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "file_reputation = FileReputation(\n", + " host=\"https://data.reversinglabs.com\",\n", + " username=USERNAME,\n", + " password=PASSWORD,\n", + " user_agent=USER_AGENT \n", + ")\n", + "reputation_response = file_reputation.get_file_reputation(sample_sha256)\n", + "print(reputation_response.status_code)\n", + "print(json.dumps(reputation_response.json(), indent=1))" + ], + "metadata": { + "collapsed": false + }, + "execution_count": null + }, { "cell_type": "markdown", "source": [ - "Cleaning up the override classification is easy. We do it using the same method as before." + "Cleaning up the classification override is easy. We do it using the same method as before." ], "metadata": { "collapsed": false @@ -287,24 +318,22 @@ }, { "cell_type": "code", - "execution_count": null, "outputs": [], "source": [ "cleanup_response = file_reputation_override.override_classification(\n", - " remove_override=[\n", - " {\n", - " \"md5\": sample_md5,\n", - " \"sha1\": sample_sha1,\n", - " \"sha256\": sample_sha256\n", - " }\n", - " ]\n", + " remove_override=[{\n", + " \"md5\": sample_md5,\n", + " \"sha1\": sample_sha1,\n", + " \"sha256\": sample_sha256\n", + " }]\n", ")\n", "print(cleanup_response.status_code)\n", - "print(cleanup_response.text)" + "print(json.dumps(cleanup_response.json(), indent=1))" ], "metadata": { "collapsed": false - } + }, + "execution_count": null }, { "cell_type": "markdown", @@ -319,7 +348,6 @@ }, { "cell_type": "code", - "execution_count": null, "outputs": [], "source": [ "delete_file = DeleteFile(\n", @@ -388,13 +416,6 @@ "print(cleanup_response.text)" ] }, - { - "cell_type": "markdown", - "source": [], - "metadata": { - "collapsed": false - } - }, { "cell_type": "markdown", "metadata": { From bb8ff346201b2c94e470f561f57bf9e5dbbd8911 Mon Sep 17 00:00:00 2001 From: Antun Kukolja Date: Mon, 24 Jun 2024 17:12:21 +0200 Subject: [PATCH 2/4] Add missing execution_count property --- TitaniumCloud/sample_management.ipynb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/TitaniumCloud/sample_management.ipynb b/TitaniumCloud/sample_management.ipynb index e67e224..7bf1199 100644 --- a/TitaniumCloud/sample_management.ipynb +++ b/TitaniumCloud/sample_management.ipynb @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -62,7 +62,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -90,7 +90,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -138,7 +138,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -176,7 +176,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -210,7 +210,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -247,7 +247,7 @@ "metadata": { "collapsed": false }, - "execution_count": null + "execution_count": 1 }, { "cell_type": "markdown", @@ -277,7 +277,7 @@ "metadata": { "collapsed": false }, - "execution_count": null + "execution_count": 1 }, { "cell_type": "markdown", @@ -305,7 +305,7 @@ "metadata": { "collapsed": false }, - "execution_count": null + "execution_count": 1 }, { "cell_type": "markdown", @@ -333,7 +333,7 @@ "metadata": { "collapsed": false }, - "execution_count": null + "execution_count": 1 }, { "cell_type": "markdown", @@ -377,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -399,7 +399,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -429,7 +429,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ From d9f952d819fcf8c9f6773c0a9b46ad646a862a65 Mon Sep 17 00:00:00 2001 From: Antun Kukolja Date: Mon, 24 Jun 2024 17:25:38 +0200 Subject: [PATCH 3/4] Remove duplicate cells --- TitaniumCloud/sample_management.ipynb | 103 +++----------------------- 1 file changed, 12 insertions(+), 91 deletions(-) diff --git a/TitaniumCloud/sample_management.ipynb b/TitaniumCloud/sample_management.ipynb index 7bf1199..55a33c0 100644 --- a/TitaniumCloud/sample_management.ipynb +++ b/TitaniumCloud/sample_management.ipynb @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -62,7 +62,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -90,7 +90,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -138,7 +138,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -176,7 +176,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -210,7 +210,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -247,7 +247,7 @@ "metadata": { "collapsed": false }, - "execution_count": 1 + "execution_count": null }, { "cell_type": "markdown", @@ -277,7 +277,7 @@ "metadata": { "collapsed": false }, - "execution_count": 1 + "execution_count": null }, { "cell_type": "markdown", @@ -305,7 +305,7 @@ "metadata": { "collapsed": false }, - "execution_count": 1 + "execution_count": null }, { "cell_type": "markdown", @@ -333,7 +333,7 @@ "metadata": { "collapsed": false }, - "execution_count": 1 + "execution_count": null }, { "cell_type": "markdown", @@ -364,7 +364,8 @@ ], "metadata": { "collapsed": false - } + }, + "execution_count": null }, { "cell_type": "raw", @@ -374,86 +375,6 @@ "metadata": { "collapsed": false } - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "file_override_response = file_reputation_override.list_active_overrides(\"sha256\")\n", - "print(file_override_response.text)\n", - "is_in = \"in\" if file_override_response.text.find(sample_sha256) != -1 else \"not in\"\n", - "print(\"\")\n", - "print(f\"Sample is {is_in} the returned response page\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": false - }, - "source": [ - "Cleaning up the override classification is easy. We do it using the same method as before." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "cleanup_response = file_reputation_override.override_classification(\n", - " remove_override=[\n", - " {\n", - " \"md5\": sample_md5,\n", - " \"sha1\": sample_sha1,\n", - " \"sha256\": sample_sha256\n", - " }\n", - " ]\n", - ")\n", - "print(cleanup_response.status_code)\n", - "print(cleanup_response.text)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "collapsed": false - }, - "source": [ - "### 7. Delete file\n", - "In case we no longer want a file to be present in the cloud and available for analysis or download, we can delete it.\n", - "To delete a file from the TitaniumCloud, we will use the `DeleteFile` class." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "delete_file = DeleteFile(\n", - " host=\"https://data.reversinglabs.com\",\n", - " username=USERNAME,\n", - " password=PASSWORD,\n", - " user_agent=USER_AGENT\n", - ")\n", - "\n", - "delete_response = delete_file.delete_samples(sample_hashes=FILE_HASH)\n", - "\n", - "response_text = delete_response.text\n", - "print(response_text)" - ] - }, - { - "cell_type": "raw", - "metadata": { - "collapsed": false - }, - "source": [ - "Again, we used the same file hash. If our file deletion request was successful, the response text will have a non-empty list called `deleted_hashes`. This list carries the hashes of files that have successfully been deleted with this request." - ] } ], "metadata": { From c640d7cc2c6ce75e94d9c60cf304e14d2d69ef13 Mon Sep 17 00:00:00 2001 From: Antun Kukolja Date: Mon, 24 Jun 2024 17:28:37 +0200 Subject: [PATCH 4/4] Add TiCloud classes to manifest --- TitaniumCloud/sample_management.ipynb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TitaniumCloud/sample_management.ipynb b/TitaniumCloud/sample_management.ipynb index 55a33c0..cecf8f9 100644 --- a/TitaniumCloud/sample_management.ipynb +++ b/TitaniumCloud/sample_management.ipynb @@ -22,6 +22,8 @@ "- **FileUpload** (*TCA-0202-0203 - File Upload*)\n", "- **FileDownload** (*TCA-0201 - File Download*)\n", "- **ReanalyzeFile** (*TCA-0205 - Re-Analyze File*)\n", + "- **FileReputation** (*TCA-0101 - File Reputation (single query)*)\n", + "- **FileReputationOverride** (*TCA-0102 - File Reputation Override*)\n", "- **DeleteFile** (*TCA-0204 - Delete File*)\n", "\n", "### Credentials\n",