1
+ import logging
2
+
3
+ import pymongo
4
+ import pymongo .collection
5
+ import pymongo .database
6
+ import pymongo .results
7
+
1
8
from lib .cuckoo .common import config
9
+ from lib .cuckoo .common .exceptions import CuckooOperationalError
2
10
from lib .cuckoo .core .reporting import api
3
11
12
+ log = logging .getLogger (__name__ )
13
+
4
14
5
15
class MongoDBReports (api .Reports ):
6
16
def __init__ (self , cfg : config .Config ):
7
- pass
17
+ if not hasattr (cfg , "mongodb" ):
18
+ raise CuckooOperationalError ("mongodb must be configured" )
19
+ mongodb_cfg : dict = cfg .mongodb
20
+
21
+ self ._client : pymongo .MongoClient = _pymongo_client (mongodb_cfg )
22
+ dbname = mongodb_cfg .get ("db" , "cuckoo" )
23
+ self ._database : pymongo .database .Database = self ._client [dbname ]
24
+ self ._reports : pymongo .collection .Collection = self ._database [_analysis_coll ]
25
+
26
+ _init_pymongo_logging (mongodb_cfg )
8
27
9
28
def get (self , task_id : int ) -> dict :
10
- pass
29
+ query = {_info_id : task_id }
30
+ report = self ._reports .find_one (filter = query )
31
+ return {} if not report else report
11
32
12
33
def delete (self , task_id : int ) -> bool :
13
- pass
34
+ query = {_info_id : task_id }
35
+ rslt : pymongo .results .DeleteResult = self ._reports .delete_one (filter = query )
36
+ return True if rslt .deleted_count > 0 else False
14
37
15
38
def search (self , term , value , limit = False , projection = None ) -> list :
16
39
pass
@@ -28,10 +51,61 @@ def detections_by_sha256(self, sha256: str) -> dict:
28
51
pass
29
52
30
53
def iocs (self , task_id : int ) -> dict :
31
- pass
54
+ # there's no well-defined representation of iocs data yet; defer to full get
55
+ return self .get (task_id )
32
56
33
57
def summary (self , task_id : int ) -> dict :
34
- pass
58
+ query = {_info_id : task_id }
59
+ projection = {
60
+ _id : 0 ,
61
+ _info : 1 ,
62
+ "target.file.virustotal.summary" : 1 ,
63
+ "url.virustotal.summary" : 1 ,
64
+ "malscore" : 1 ,
65
+ "detections" : 1 ,
66
+ "network.pcap_sha256" : 1 ,
67
+ "mlist_cnt" : 1 ,
68
+ "f_mlist_cnt" : 1 ,
69
+ "target.file.clamav" : 1 ,
70
+ "suri_tls_cnt" : 1 ,
71
+ "suri_alert_cnt" : 1 ,
72
+ "suri_http_cnt" : 1 ,
73
+ "suri_file_cnt" : 1 ,
74
+ "trid" : 1 ,
75
+ }
76
+ report = self ._reports .find_one (filter = query , projection = projection )
77
+ return {} if not report else report
35
78
36
79
def recent_suricata_alerts (self , minutes = 60 ) -> list :
37
80
pass
81
+
82
+
83
+ # Temporarily duped with mongodb_constants
84
+ _analysis_coll = "analysis"
85
+ _calls_coll = "calls"
86
+ _cuckoo_coll = "cuckoo_schema"
87
+ _files_coll = "files"
88
+ _file_key = "sha256"
89
+ _id = "_id"
90
+ _info = "info"
91
+ _info_id = "info.id"
92
+ _target = "target"
93
+ _task_ids_key = "_task_ids"
94
+ _version = "version"
95
+
96
+
97
+ def _pymongo_client (cfg : dict ) -> pymongo .MongoClient :
98
+ return pymongo .MongoClient (
99
+ host = cfg .get ("host" , "127.0.0.1" ),
100
+ port = cfg .get ("port" , 27017 ),
101
+ username = cfg .get ("username" ),
102
+ password = cfg .get ("password" ),
103
+ authSource = cfg .get ("authsource" , "cuckoo" ),
104
+ tlsCAFile = cfg .get ("tlscafile" , None ),
105
+ )
106
+
107
+
108
+ def _init_pymongo_logging (cfg : dict ) -> None :
109
+ mongodb_log_level = cfg .get ("log_level" , "ERROR" )
110
+ level = logging .getLevelName (mongodb_log_level .upper ())
111
+ logging .getLogger ("pymongo" ).setLevel (level )
0 commit comments