@@ -341,29 +341,96 @@ def get_file_info(self, hashes):
341
341
342
342
.. code-block:: python
343
343
344
- # Determine reputations for file (identified by hashes)
344
+ # Retrieve information for file (identified by hashes)
345
345
file_info_dict = \\
346
346
tie_client.get_file_info({
347
347
HashType.MD5: "f2c7bb8acc97f92e987a2d4087d021b1",
348
348
HashType.SHA1: "7eb0139d2175739b3ccb0d1110067820be6abd29",
349
349
HashType.SHA256: "142e1d688ef0568370c37187fd9f2351d7ddeda574f8bfa9b0fa4ef42db85aa2"
350
350
})
351
351
352
- Sample output + info
352
+ **File**
353
+
354
+ The file that matches one of the hashes is returned as a Python ``dictionary``.
355
+
356
+ An example ``list`` is shown below:
357
+
358
+ .. code-block:: python
359
+ {
360
+ "atdReputation": null,
361
+ "atdReputationLastRefresh": null,
362
+ "badRepCount": null,
363
+ "certEnterpriseReputation": 0,
364
+ "certGtiReputation": 99,
365
+ "certSha1": "49da9a5e21edc4682ad0211c85d552c86c422f13",
366
+ "comment": null,
367
+ "company": null,
368
+ "compositeReputation": " 099|2",
369
+ "ctdReputation": null,
370
+ "ctdReputationLastRefresh": null,
371
+ "detectionCount": null,
372
+ "enterpriseCount": 1,
373
+ "enterpriseReputation": null,
374
+ "enterpriseReputationLastRefresh": null,
375
+ "fileNameCount": null,
376
+ "fileParents": null,
377
+ "filePathCount": null,
378
+ "filePaths": null,
379
+ "fileRules": null,
380
+ "fileType": 16,
381
+ "firstContact": "2016-12-13 15:50:43",
382
+ "firstReference": null,
383
+ "goodRepCount": null,
384
+ "gtiReputation": null,
385
+ "gtiReputationLastRefresh": null,
386
+ "lastAccess": "2017-01-23 15:09:24",
387
+ "lastDetectionName": null,
388
+ "lastUpdate": null,
389
+ "latestRuleId": null,
390
+ "localRepCount": null,
391
+ "localRepLatest": null,
392
+ "localRepMax": null,
393
+ "localRepMin": null,
394
+ "localRepSum": null,
395
+ "md5": "b32189bdff6e577a92baa61ad49264e6",
396
+ "mwgReputation": null,
397
+ "mwgReputationLastRefresh": null,
398
+ "names": [
399
+ "NOTEPAD.EXE"
400
+ ],
401
+ "parentRepCount": null,
402
+ "parentRepMax": null,
403
+ "parentRepMin": null,
404
+ "parentRepSum": null,
405
+ "prevalent": false,
406
+ "productName": null,
407
+ "productVersion": null,
408
+ "profilerFlags": "",
409
+ "promptRepCount": null,
410
+ "promptRepMax": null,
411
+ "promptRepMin": null,
412
+ "promptRepSum": null,
413
+ "sha1": "a7bbc4b4f781e04214ecebe69a766c76681aa7eb",
414
+ "sha256": "933e1778b2760b3a9194c2799d7b76052895959c3caedefb4e9d764cbb6ad3b5",
415
+ "signedBits": null,
416
+ "size": null,
417
+ "urlRep": null,
418
+ "version": null
419
+ }
353
420
354
421
:param hashes: A ``dict`` (dictionary) of hashes that identify the file to retrieve the info for.
355
422
The ``key`` in the dictionary is the `hash type` and the ``value`` is the `hex` representation of the
356
423
hash value. See the :class:`dxltieclient.constants.HashType` class for the list of `hash type`
357
424
constants.
358
- :return:
425
+ :return: a file info dict
359
426
"""
360
427
# Create the request message
361
428
req = Request (TIE_GET_FILE_INFO_TOPIC )
362
429
363
430
# Create a dictionary for the payload
364
431
payload_dict = {"hashes" : []}
365
432
366
- # This topic needs an extra list layer
433
+ # This topic needs an extra list layer in the payload
367
434
payload_dict ["hashes" ].append ([])
368
435
369
436
for key , value in hashes .items ():
@@ -378,8 +445,10 @@ def get_file_info(self, hashes):
378
445
resp_dict = json .loads (response .payload .decode (encoding = "UTF-8" ))
379
446
380
447
# Transform reputations to be simpler to use
381
- if len (resp_dict ) > 0 :
382
- return TieClient ._transform_file_info (resp_dict )
448
+ if "results" in resp_dict and len (resp_dict ["results" ]) > 0 :
449
+ file_info = resp_dict ["results" ][0 ]
450
+ TieClient ._transform_file_info (file_info )
451
+ return file_info
383
452
else :
384
453
return {}
385
454
@@ -391,18 +460,87 @@ def search_files(self, search_string, query_limit=500):
391
460
392
461
.. code-block:: python
393
462
394
- # Determine reputations for file (identified by hashes )
463
+ # Retrieve information for files (identified by (a part of) its name )
395
464
file_search_dict = \\
396
465
tie_client.search_files(
397
466
"bad_file.exe",
398
467
100
399
468
)
400
469
401
- Sample output + info
470
+ **Files**
471
+
472
+ The files that match the search string are returned as a Python ``list``.
473
+
474
+ An example ``list`` is shown below:
475
+
476
+ .. code-block:: python
477
+ [
478
+ {
479
+ "atdReputation": null,
480
+ "atdReputationLastRefresh": null,
481
+ "badRepCount": null,
482
+ "certEnterpriseReputation": 0,
483
+ "certGtiReputation": 99,
484
+ "certSha1": "49da9a5e21edc4682ad0211c85d552c86c422f13",
485
+ "comment": null,
486
+ "company": null,
487
+ "compositeReputation": " 099|2",
488
+ "ctdReputation": null,
489
+ "ctdReputationLastRefresh": null,
490
+ "detectionCount": null,
491
+ "enterpriseCount": 1,
492
+ "enterpriseReputation": null,
493
+ "enterpriseReputationLastRefresh": null,
494
+ "fileNameCount": null,
495
+ "fileParents": null,
496
+ "filePathCount": null,
497
+ "filePaths": null,
498
+ "fileRules": null,
499
+ "fileType": 16,
500
+ "firstContact": "2016-12-13 15:50:43",
501
+ "firstReference": null,
502
+ "goodRepCount": null,
503
+ "gtiReputation": null,
504
+ "gtiReputationLastRefresh": null,
505
+ "lastAccess": "2017-01-23 15:09:24",
506
+ "lastDetectionName": null,
507
+ "lastUpdate": null,
508
+ "latestRuleId": null,
509
+ "localRepCount": null,
510
+ "localRepLatest": null,
511
+ "localRepMax": null,
512
+ "localRepMin": null,
513
+ "localRepSum": null,
514
+ "md5": "b32189bdff6e577a92baa61ad49264e6",
515
+ "mwgReputation": null,
516
+ "mwgReputationLastRefresh": null,
517
+ "names": [
518
+ "NOTEPAD.EXE"
519
+ ],
520
+ "parentRepCount": null,
521
+ "parentRepMax": null,
522
+ "parentRepMin": null,
523
+ "parentRepSum": null,
524
+ "prevalent": false,
525
+ "productName": null,
526
+ "productVersion": null,
527
+ "profilerFlags": "",
528
+ "promptRepCount": null,
529
+ "promptRepMax": null,
530
+ "promptRepMin": null,
531
+ "promptRepSum": null,
532
+ "sha1": "a7bbc4b4f781e04214ecebe69a766c76681aa7eb",
533
+ "sha256": "933e1778b2760b3a9194c2799d7b76052895959c3caedefb4e9d764cbb6ad3b5",
534
+ "signedBits": null,
535
+ "size": null,
536
+ "urlRep": null,
537
+ "version": null
538
+ }
539
+ ]
402
540
403
541
:param search_string: A ``string`` that contains a (part of) the filename to search for
404
542
:param query_limit: The maximum number of results to return
405
- :return:
543
+ :return: a list of file info dicts
406
544
"""
407
545
# Create the request message
408
546
req = Request (TIE_SEARCH_FILE_BY_NAME )
@@ -419,9 +557,11 @@ def search_files(self, search_string, query_limit=500):
419
557
resp_dict = json .loads (response .payload .decode (encoding = "UTF-8" ))
420
558
421
559
if "results" in resp_dict :
422
- return TieClient ._transform_reputations (resp_dict ["results" ])
560
+ file_infos = resp_dict ["results" ]
561
+ TieClient ._transform_file_infos (file_infos )
562
+ return file_infos
423
563
else :
424
- return {}
564
+ return []
425
565
426
566
def get_file_first_references (self , hashes , query_limit = 500 ):
427
567
"""
@@ -834,10 +974,9 @@ def _transform_reputations(reputations):
834
974
@staticmethod
835
975
def _transform_file_infos (file_infos ):
836
976
"""
837
- Transforms a dictionary of file info objects from the standard TIE format to a simplified
977
+ Transforms a list of file info objects from the standard TIE format to a simplified
838
978
form (hex vs base64 hashes, timestamps, etc.)
839
- :param file_infos: The dictionary of file info objects in the standard TIE format
840
- :return: A dictionary file info objects in a simplified form
979
+ :param file_infos: The list of file info objects in the standard TIE format
841
980
"""
842
981
for file_info in file_infos :
843
982
TieClient ._transform_file_info (file_info )
@@ -848,22 +987,29 @@ def _transform_file_info(file_info):
848
987
Transforms a file info object from the standard TIE format to a simplified
849
988
form (hex vs base64 hashes, timestamps, etc.)
850
989
:param file_info: File info in the standard TIE format
851
- :return: The file info in a simplified form
852
990
"""
853
991
# Transform hash values to readable
854
- file_info [HashType .MD5 ] = TieClient ._base64_to_hex (file_info [HashType .MD5 ])
855
- file_info [HashType .SHA256 ] = TieClient ._base64_to_hex (file_info [HashType .SHA256 ])
856
- file_info [HashType .SHA1 ] = TieClient ._base64_to_hex (file_info [HashType .SHA1 ])
992
+ hash_fields = [HashType .MD5 , HashType .SHA256 , HashType .SHA1 , "certSha1" ]
857
993
858
- # Transform Unix timestamp to readable
859
- file_info ["firstContact" ] = TieClient ._transform_unix_to_datetime (file_info ["firstContact" ])
860
- file_info ["lastAccess" ] = TieClient ._transform_unix_to_datetime (file_info ["lastAccess" ])
994
+ for hash_field in hash_fields :
995
+ file_info [hash_field ] = TieClient ._base64_to_hex (file_info [hash_field ])
996
+
997
+ # Transform Unix timestamp to human readable
998
+ timestamp_fields = ["firstContact" , "lastAccess" , "firstReference" , "lastUpdate" , "enterpriseReputationLastRefresh" ,
999
+ "mwgReputationLastRefresh" , "gtiReputationLastRefresh" , "atdReputationLastRefresh" ,
1000
+ "ctdReputationLastRefresh" ]
1001
+
1002
+ for timestamp_field in timestamp_fields :
1003
+ file_info [timestamp_field ] = TieClient ._transform_unix_to_datetime (file_info [timestamp_field ])
861
1004
862
1005
@staticmethod
863
1006
def _transform_unix_to_datetime (unix_timestamp ):
864
1007
"""
865
- Transforms a unix timestamp into a python datetime object
1008
+ Transforms a unix timestamp into a human readable string
866
1009
:param unix_timestamp: The dictionary of reputation in the standard TIE format
867
- :return: The timestamp as a python datetime object
1010
+ :return: The timestamp as a string
868
1011
"""
869
- return datetime .fromtimestamp (int (str (unix_timestamp )[:- 3 ])).strftime ('%Y-%m-%d %H:%M:%S' )
1012
+ if unix_timestamp is not None :
1013
+ return datetime .fromtimestamp (unix_timestamp / 1000 ).strftime ('%Y-%m-%d %H:%M:%S' )
1014
+ else :
1015
+ return None
0 commit comments