|
41 | 41 | },
|
42 | 42 | {
|
43 | 43 | "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": {}, |
51 | 46 | "outputs": [],
|
52 | 47 | "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" |
54 | 50 | ]
|
55 | 51 | },
|
56 | 52 | {
|
|
66 | 62 | },
|
67 | 63 | {
|
68 | 64 | "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": {}, |
76 | 67 | "outputs": [],
|
77 | 68 | "source": [
|
78 | 69 | "import json\n",
|
|
99 | 90 | },
|
100 | 91 | {
|
101 | 92 | "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": [], |
118 | 96 | "source": [
|
119 |
| - "FILE_NAME = \"file_name_placeholder\"\n", |
| 97 | + "FILE_NAME = \"README.md\"\n", |
120 | 98 | "\n",
|
121 | 99 | "file_upload = FileUpload(\n",
|
122 | 100 | " host=\"https://data.reversinglabs.com\",\n",
|
|
125 | 103 | " user_agent=USER_AGENT\n",
|
126 | 104 | ")\n",
|
127 | 105 | "\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", |
128 | 113 | "upload_response = file_upload.upload_sample_from_path(file_path=FILE_NAME)\n",
|
129 | 114 | "\n",
|
130 | 115 | "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)" |
132 | 120 | ]
|
133 | 121 | },
|
134 | 122 | {
|
|
154 | 142 | "metadata": {},
|
155 | 143 | "outputs": [],
|
156 | 144 | "source": [
|
157 |
| - "FILE_HASH = \"sha1_hash_placeholder\"\n", |
| 145 | + "FILE_HASH = \"8e21cde3f269b7f359eb8903a130ab11e060325069e16c0ba1674c141d6c9d01\"\n", |
158 | 146 | "\n",
|
159 | 147 | "file_download = FileDownload(\n",
|
160 | 148 | " host=\"https://data.reversinglabs.com\",\n",
|
|
188 | 176 | },
|
189 | 177 | {
|
190 | 178 | "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": [], |
207 | 182 | "source": [
|
208 | 183 | "reanalyze = ReanalyzeFile(\n",
|
209 | 184 | " host=\"https://data.reversinglabs.com\",\n",
|
|
228 | 203 | "`Sample sent for rescanning`\n",
|
229 | 204 | "\n",
|
230 | 205 | "\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." |
234 | 209 | ]
|
235 | 210 | },
|
236 | 211 | {
|
|
239 | 214 | "metadata": {},
|
240 | 215 | "outputs": [],
|
241 | 216 | "source": [
|
242 |
| - "delete_file = DeleteFile(\n", |
| 217 | + "file_reputation_override = FileReputationUserOverride(\n", |
243 | 218 | " host=\"https://data.reversinglabs.com\",\n",
|
244 | 219 | " username=USERNAME,\n",
|
245 | 220 | " password=PASSWORD,\n",
|
246 | 221 | " 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 | + ")" |
253 | 223 | ]
|
254 | 224 | },
|
255 | 225 | {
|
|
258 | 228 | "collapsed": false
|
259 | 229 | },
|
260 | 230 | "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." |
262 | 234 | ]
|
263 | 235 | },
|
264 | 236 | {
|
265 | 237 | "cell_type": "code",
|
266 |
| - "execution_count": null, |
267 | 238 | "outputs": [],
|
268 | 239 | "source": [
|
269 | 240 | "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", |
271 | 244 | "is_in = \"in\" if file_override_response.text.find(sample_sha256) != -1 else \"not in\"\n",
|
272 |
| - "print(\"\")\n", |
273 | 245 | "print(f\"Sample is {is_in} the returned response page\")"
|
274 | 246 | ],
|
| 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 | + ], |
275 | 287 | "metadata": {
|
276 | 288 | "collapsed": false
|
277 | 289 | }
|
278 | 290 | },
|
| 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 | + }, |
279 | 310 | {
|
280 | 311 | "cell_type": "markdown",
|
281 | 312 | "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." |
283 | 314 | ],
|
284 | 315 | "metadata": {
|
285 | 316 | "collapsed": false
|
286 | 317 | }
|
287 | 318 | },
|
288 | 319 | {
|
289 | 320 | "cell_type": "code",
|
290 |
| - "execution_count": null, |
291 | 321 | "outputs": [],
|
292 | 322 | "source": [
|
293 | 323 | "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", |
301 | 329 | ")\n",
|
302 | 330 | "print(cleanup_response.status_code)\n",
|
303 |
| - "print(cleanup_response.text)" |
| 331 | + "print(json.dumps(cleanup_response.json(), indent=1))" |
304 | 332 | ],
|
305 | 333 | "metadata": {
|
306 | 334 | "collapsed": false
|
307 |
| - } |
| 335 | + }, |
| 336 | + "execution_count": null |
308 | 337 | },
|
309 | 338 | {
|
310 | 339 | "cell_type": "markdown",
|
|
319 | 348 | },
|
320 | 349 | {
|
321 | 350 | "cell_type": "code",
|
322 |
| - "execution_count": null, |
323 | 351 | "outputs": [],
|
324 | 352 | "source": [
|
325 | 353 | "delete_file = DeleteFile(\n",
|
|
388 | 416 | "print(cleanup_response.text)"
|
389 | 417 | ]
|
390 | 418 | },
|
391 |
| - { |
392 |
| - "cell_type": "markdown", |
393 |
| - "source": [], |
394 |
| - "metadata": { |
395 |
| - "collapsed": false |
396 |
| - } |
397 |
| - }, |
398 | 419 | {
|
399 | 420 | "cell_type": "markdown",
|
400 | 421 | "metadata": {
|
|
0 commit comments