Skip to content

Commit d20075c

Browse files
committed
Fix sample reputation override example
1 parent da746eb commit d20075c

File tree

1 file changed

+104
-83
lines changed

1 file changed

+104
-83
lines changed

TitaniumCloud/sample_management.ipynb

Lines changed: 104 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,12 @@
4141
},
4242
{
4343
"cell_type": "code",
44-
"execution_count": 2,
45-
"metadata": {
46-
"ExecuteTime": {
47-
"end_time": "2024-06-24T13:00:18.771975493Z",
48-
"start_time": "2024-06-24T13:00:18.731201662Z"
49-
}
50-
},
44+
"execution_count": null,
45+
"metadata": {},
5146
"outputs": [],
5247
"source": [
53-
"from ReversingLabs.SDK.ticloud import FileUpload, FileDownload, ReanalyzeFile, DeleteFile"
48+
"from ReversingLabs.SDK.ticloud import FileUpload, FileDownload, ReanalyzeFile, DeleteFile, FileReputationUserOverride, FileReputation, calculate_hash\n",
49+
"from ReversingLabs.SDK.helper import SHA1, SHA256, MD5"
5450
]
5551
},
5652
{
@@ -66,13 +62,8 @@
6662
},
6763
{
6864
"cell_type": "code",
69-
"execution_count": 3,
70-
"metadata": {
71-
"ExecuteTime": {
72-
"end_time": "2024-06-24T13:00:25.846033807Z",
73-
"start_time": "2024-06-24T13:00:25.842115172Z"
74-
}
75-
},
65+
"execution_count": null,
66+
"metadata": {},
7667
"outputs": [],
7768
"source": [
7869
"import json\n",
@@ -99,24 +90,11 @@
9990
},
10091
{
10192
"cell_type": "code",
102-
"execution_count": 4,
103-
"metadata": {
104-
"ExecuteTime": {
105-
"end_time": "2024-06-24T13:01:24.894826465Z",
106-
"start_time": "2024-06-24T13:01:24.346445039Z"
107-
}
108-
},
109-
"outputs": [
110-
{
111-
"name": "stdout",
112-
"output_type": "stream",
113-
"text": [
114-
"200\n"
115-
]
116-
}
117-
],
93+
"execution_count": null,
94+
"metadata": {},
95+
"outputs": [],
11896
"source": [
119-
"FILE_NAME = \"file_name_placeholder\"\n",
97+
"FILE_NAME = \"README.md\"\n",
12098
"\n",
12199
"file_upload = FileUpload(\n",
122100
" host=\"https://data.reversinglabs.com\",\n",
@@ -125,10 +103,20 @@
125103
" user_agent=USER_AGENT\n",
126104
")\n",
127105
"\n",
106+
"with open(FILE_NAME, \"rb\") as sample:\n",
107+
" sample_md5 = calculate_hash(data_input=sample, hashing_algorithm=MD5)\n",
108+
" sample.seek(0)\n",
109+
" sample_sha1 = calculate_hash(data_input=sample, hashing_algorithm=SHA1)\n",
110+
" sample.seek(0)\n",
111+
" sample_sha256 = calculate_hash(data_input=sample, hashing_algorithm=SHA256)\n",
112+
"\n",
128113
"upload_response = file_upload.upload_sample_from_path(file_path=FILE_NAME)\n",
129114
"\n",
130115
"status_code = upload_response.status_code\n",
131-
"print(status_code)"
116+
"print(status_code)\n",
117+
"print(\"md5\", sample_md5)\n",
118+
"print(\"sha1\", sample_sha1)\n",
119+
"print(\"sha256\", sample_sha256)"
132120
]
133121
},
134122
{
@@ -154,7 +142,7 @@
154142
"metadata": {},
155143
"outputs": [],
156144
"source": [
157-
"FILE_HASH = \"sha1_hash_placeholder\"\n",
145+
"FILE_HASH = \"8e21cde3f269b7f359eb8903a130ab11e060325069e16c0ba1674c141d6c9d01\"\n",
158146
"\n",
159147
"file_download = FileDownload(\n",
160148
" host=\"https://data.reversinglabs.com\",\n",
@@ -188,22 +176,9 @@
188176
},
189177
{
190178
"cell_type": "code",
191-
"execution_count": 7,
192-
"metadata": {
193-
"ExecuteTime": {
194-
"end_time": "2024-06-24T13:15:51.128618407Z",
195-
"start_time": "2024-06-24T13:15:51.049367153Z"
196-
}
197-
},
198-
"outputs": [
199-
{
200-
"name": "stdout",
201-
"output_type": "stream",
202-
"text": [
203-
"Sample sent for rescanning\n"
204-
]
205-
}
206-
],
179+
"execution_count": null,
180+
"metadata": {},
181+
"outputs": [],
207182
"source": [
208183
"reanalyze = ReanalyzeFile(\n",
209184
" host=\"https://data.reversinglabs.com\",\n",
@@ -228,9 +203,9 @@
228203
"`Sample sent for rescanning`\n",
229204
"\n",
230205
"\n",
231-
"### 6. Delete file\n",
232-
"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",
233-
"To delete a file from the TitaniumCloud, we will use the `DeleteFile` class."
206+
"### 6. Sample reputation override\n",
207+
"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",
208+
"But before we do that let's see if our sample already has an override on its classification."
234209
]
235210
},
236211
{
@@ -239,17 +214,12 @@
239214
"metadata": {},
240215
"outputs": [],
241216
"source": [
242-
"delete_file = DeleteFile(\n",
217+
"file_reputation_override = FileReputationUserOverride(\n",
243218
" host=\"https://data.reversinglabs.com\",\n",
244219
" username=USERNAME,\n",
245220
" password=PASSWORD,\n",
246221
" user_agent=USER_AGENT\n",
247-
")\n",
248-
"\n",
249-
"delete_response = delete_file.delete_samples(sample_hashes=FILE_HASH)\n",
250-
"\n",
251-
"response_text = delete_response.text\n",
252-
"print(response_text)"
222+
")"
253223
]
254224
},
255225
{
@@ -258,53 +228,112 @@
258228
"collapsed": false
259229
},
260230
"source": [
261-
"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."
231+
"We do this by requesting a collection of all sample hashes of a specific hash type.\n",
232+
"In this example we use the SHA256 algorithm.\n",
233+
"We check the first page to see if our sample is present."
262234
]
263235
},
264236
{
265237
"cell_type": "code",
266-
"execution_count": null,
267238
"outputs": [],
268239
"source": [
269240
"file_override_response = file_reputation_override.list_active_overrides(\"sha256\")\n",
270-
"print(file_override_response.text)\n",
241+
"count = len(file_override_response.json()[\"rl\"][\"user_override\"][\"hash_values\"])\n",
242+
"has_more = \"more\" if file_override_response.json()[\"rl\"][\"user_override\"].get(\"has_next\") else \"no more\"\n",
243+
"print(f\"Found {count} samples with overridden classification, there are {has_more} such samples\")\n",
271244
"is_in = \"in\" if file_override_response.text.find(sample_sha256) != -1 else \"not in\"\n",
272-
"print(\"\")\n",
273245
"print(f\"Sample is {is_in} the returned response page\")"
274246
],
247+
"metadata": {
248+
"collapsed": false
249+
},
250+
"execution_count": null
251+
},
252+
{
253+
"cell_type": "markdown",
254+
"source": [
255+
"Now we will add override the reputation to be malicious.\n",
256+
"We will then retrieve it from TiCloud and see how our change affects the output."
257+
],
258+
"metadata": {
259+
"collapsed": false
260+
}
261+
},
262+
{
263+
"cell_type": "code",
264+
"outputs": [],
265+
"source": [
266+
"file_reputation_override_response = file_reputation_override.override_classification(\n",
267+
" override_samples=[{\n",
268+
" \"md5\": sample_md5,\n",
269+
" \"sha1\": sample_sha1,\n",
270+
" \"sha256\": sample_sha256,\n",
271+
" \"status\": \"MALICIOUS\"\n",
272+
" }]\n",
273+
")\n",
274+
"print(file_reputation_override_response.status_code)\n",
275+
"print(json.dumps(file_reputation_override_response.json(), indent=1))"
276+
],
277+
"metadata": {
278+
"collapsed": false
279+
},
280+
"execution_count": null
281+
},
282+
{
283+
"cell_type": "markdown",
284+
"source": [
285+
"You might need to give TiCloud a moment to propagate the new classification through the system."
286+
],
275287
"metadata": {
276288
"collapsed": false
277289
}
278290
},
291+
{
292+
"cell_type": "code",
293+
"outputs": [],
294+
"source": [
295+
"file_reputation = FileReputation(\n",
296+
" host=\"https://data.reversinglabs.com\",\n",
297+
" username=USERNAME,\n",
298+
" password=PASSWORD,\n",
299+
" user_agent=USER_AGENT \n",
300+
")\n",
301+
"reputation_response = file_reputation.get_file_reputation(sample_sha256)\n",
302+
"print(reputation_response.status_code)\n",
303+
"print(json.dumps(reputation_response.json(), indent=1))"
304+
],
305+
"metadata": {
306+
"collapsed": false
307+
},
308+
"execution_count": null
309+
},
279310
{
280311
"cell_type": "markdown",
281312
"source": [
282-
"Cleaning up the override classification is easy. We do it using the same method as before."
313+
"Cleaning up the classification override is easy. We do it using the same method as before."
283314
],
284315
"metadata": {
285316
"collapsed": false
286317
}
287318
},
288319
{
289320
"cell_type": "code",
290-
"execution_count": null,
291321
"outputs": [],
292322
"source": [
293323
"cleanup_response = file_reputation_override.override_classification(\n",
294-
" remove_override=[\n",
295-
" {\n",
296-
" \"md5\": sample_md5,\n",
297-
" \"sha1\": sample_sha1,\n",
298-
" \"sha256\": sample_sha256\n",
299-
" }\n",
300-
" ]\n",
324+
" remove_override=[{\n",
325+
" \"md5\": sample_md5,\n",
326+
" \"sha1\": sample_sha1,\n",
327+
" \"sha256\": sample_sha256\n",
328+
" }]\n",
301329
")\n",
302330
"print(cleanup_response.status_code)\n",
303-
"print(cleanup_response.text)"
331+
"print(json.dumps(cleanup_response.json(), indent=1))"
304332
],
305333
"metadata": {
306334
"collapsed": false
307-
}
335+
},
336+
"execution_count": null
308337
},
309338
{
310339
"cell_type": "markdown",
@@ -319,7 +348,6 @@
319348
},
320349
{
321350
"cell_type": "code",
322-
"execution_count": null,
323351
"outputs": [],
324352
"source": [
325353
"delete_file = DeleteFile(\n",
@@ -388,13 +416,6 @@
388416
"print(cleanup_response.text)"
389417
]
390418
},
391-
{
392-
"cell_type": "markdown",
393-
"source": [],
394-
"metadata": {
395-
"collapsed": false
396-
}
397-
},
398419
{
399420
"cell_type": "markdown",
400421
"metadata": {

0 commit comments

Comments
 (0)