mirror of https://github.com/CIRCL/lookyloo
new: Initial commit to mark body responses as legitimate/malicious
parent
fc7cb77002
commit
c5aabcf4a3
|
@ -114,21 +114,22 @@ class Indexing():
|
||||||
|
|
||||||
pipeline = self.redis.pipeline()
|
pipeline = self.redis.pipeline()
|
||||||
for urlnode in crawled_tree.root_hartree.url_tree.traverse():
|
for urlnode in crawled_tree.root_hartree.url_tree.traverse():
|
||||||
if not urlnode.empty_response:
|
if urlnode.empty_response:
|
||||||
pipeline.zincrby('body_hashes', 1, urlnode.body_hash)
|
continue
|
||||||
pipeline.zincrby(f'bh|{urlnode.body_hash}', 1, urlnode.hostname)
|
pipeline.zincrby('body_hashes', 1, urlnode.body_hash)
|
||||||
# set of all captures with this hash
|
pipeline.zincrby(f'bh|{urlnode.body_hash}', 1, urlnode.hostname)
|
||||||
pipeline.sadd(f'bh|{urlnode.body_hash}|captures', crawled_tree.uuid)
|
# set of all captures with this hash
|
||||||
# ZSet of all urlnode_UUIDs|full_url
|
pipeline.sadd(f'bh|{urlnode.body_hash}|captures', crawled_tree.uuid)
|
||||||
pipeline.zincrby(f'bh|{urlnode.body_hash}|captures|{crawled_tree.uuid}', 1, f'{urlnode.uuid}|{urlnode.hostnode_uuid}|{urlnode.name}')
|
# ZSet of all urlnode_UUIDs|full_url
|
||||||
if hasattr(urlnode, 'embedded_ressources') and urlnode.embedded_ressources:
|
pipeline.zincrby(f'bh|{urlnode.body_hash}|captures|{crawled_tree.uuid}', 1, f'{urlnode.uuid}|{urlnode.hostnode_uuid}|{urlnode.name}')
|
||||||
for mimetype, blobs in urlnode.embedded_ressources.items():
|
if hasattr(urlnode, 'embedded_ressources') and urlnode.embedded_ressources:
|
||||||
for h, body in blobs:
|
for mimetype, blobs in urlnode.embedded_ressources.items():
|
||||||
pipeline.zincrby('body_hashes', 1, h)
|
for h, body in blobs:
|
||||||
pipeline.zincrby(f'bh|{h}', 1, urlnode.hostname)
|
pipeline.zincrby('body_hashes', 1, h)
|
||||||
pipeline.sadd(f'bh|{h}|captures', crawled_tree.uuid)
|
pipeline.zincrby(f'bh|{h}', 1, urlnode.hostname)
|
||||||
pipeline.zincrby(f'bh|{h}|captures|{crawled_tree.uuid}', 1,
|
pipeline.sadd(f'bh|{h}|captures', crawled_tree.uuid)
|
||||||
f'{urlnode.uuid}|{urlnode.hostnode_uuid}|{urlnode.name}')
|
pipeline.zincrby(f'bh|{h}|captures|{crawled_tree.uuid}', 1,
|
||||||
|
f'{urlnode.uuid}|{urlnode.hostnode_uuid}|{urlnode.name}')
|
||||||
|
|
||||||
pipeline.execute()
|
pipeline.execute()
|
||||||
|
|
||||||
|
@ -146,6 +147,54 @@ class Indexing():
|
||||||
def get_body_hash_domains(self, body_hash: str) -> List[Tuple[str, float]]:
|
def get_body_hash_domains(self, body_hash: str) -> List[Tuple[str, float]]:
|
||||||
return self.redis.zrevrange(f'bh|{body_hash}', 0, -1, withscores=True)
|
return self.redis.zrevrange(f'bh|{body_hash}', 0, -1, withscores=True)
|
||||||
|
|
||||||
|
def legitimate_capture(self, crawled_tree: CrawledTree) -> None:
|
||||||
|
pipeline = self.redis.pipeline()
|
||||||
|
for urlnode in crawled_tree.root_hartree.url_tree.traverse():
|
||||||
|
if urlnode.empty_response:
|
||||||
|
continue
|
||||||
|
pipeline.sadd(f'bh|{urlnode.body_hash}|legitimate', urlnode.hostname)
|
||||||
|
pipeline.execute()
|
||||||
|
|
||||||
|
def legitimate_hostnode(self, hostnode: HostNode) -> None:
|
||||||
|
pipeline = self.redis.pipeline()
|
||||||
|
for urlnode in hostnode.urls:
|
||||||
|
if urlnode.empty_response:
|
||||||
|
continue
|
||||||
|
pipeline.sadd(f'bh|{urlnode.body_hash}|legitimate', urlnode.hostname)
|
||||||
|
pipeline.execute()
|
||||||
|
|
||||||
|
def legitimate_urlnode(self, urlnode: URLNode) -> None:
|
||||||
|
if urlnode.empty_response:
|
||||||
|
return
|
||||||
|
self.redis.sadd(f'bh|{urlnode.body_hash}|legitimate', urlnode.hostname)
|
||||||
|
|
||||||
|
def is_legitimate(self, urlnode: URLNode) -> Optional[bool]:
|
||||||
|
hostnames = self.redis.smembers(f'bh|{urlnode.body_hash}|legitimate')
|
||||||
|
if hostnames:
|
||||||
|
if urlnode.hostname in hostnames:
|
||||||
|
return True # Legitimate
|
||||||
|
return False # Malicious
|
||||||
|
elif self.redis.sismember('bh|malicious', urlnode.body_hash):
|
||||||
|
return False
|
||||||
|
return None # Unknown
|
||||||
|
|
||||||
|
def malicious_node(self, urlnode: URLNode) -> None:
|
||||||
|
if urlnode.empty_response:
|
||||||
|
return None
|
||||||
|
self.redis.sadd('bh|malicious', urlnode.body_hash)
|
||||||
|
|
||||||
|
def is_malicious(self, urlnode: URLNode) -> Optional[bool]:
|
||||||
|
if urlnode.empty_response:
|
||||||
|
return None
|
||||||
|
if self.redis.sismember('bh|malicious', urlnode.body_hash):
|
||||||
|
return True
|
||||||
|
legitimate = self.is_legitimate(urlnode)
|
||||||
|
if legitimate is True:
|
||||||
|
return False
|
||||||
|
if legitimate is False:
|
||||||
|
return True
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class Lookyloo():
|
class Lookyloo():
|
||||||
|
|
||||||
|
@ -259,6 +308,31 @@ class Lookyloo():
|
||||||
|
|
||||||
return ct
|
return ct
|
||||||
|
|
||||||
|
def add_to_legitimate(self, capture_uuid: str, hostnode_uuid: Optional[str]=None, urlnode_uuid: Optional[str]=None):
|
||||||
|
ct = self.get_crawled_tree(capture_uuid)
|
||||||
|
if not hostnode_uuid and not urlnode_uuid:
|
||||||
|
self.indexing.legitimate_capture(ct)
|
||||||
|
return
|
||||||
|
|
||||||
|
if hostnode_uuid:
|
||||||
|
hostnode = ct.root_hartree.get_host_node_by_uuid(hostnode_uuid)
|
||||||
|
self.indexing.legitimate_hostnode(hostnode)
|
||||||
|
if urlnode_uuid:
|
||||||
|
urlnode = ct.root_hartree.get_url_node_by_uuid(urlnode_uuid)
|
||||||
|
self.indexing.legitimate_urlnode(urlnode)
|
||||||
|
|
||||||
|
def bodies_legitimacy_check(self, tree: CrawledTree) -> CrawledTree:
|
||||||
|
hostnodes_with_malicious_content = set()
|
||||||
|
for urlnode in tree.root_hartree.url_tree.traverse():
|
||||||
|
malicious = self.indexing.is_malicious(urlnode)
|
||||||
|
if malicious is not None:
|
||||||
|
urlnode.add_feature('malicious', malicious)
|
||||||
|
hostnodes_with_malicious_content.add(urlnode.hostnode_uuid)
|
||||||
|
for hostnode_with_malicious_content in hostnodes_with_malicious_content:
|
||||||
|
hostnode = tree.root_hartree.get_host_node_by_uuid(hostnode_with_malicious_content)
|
||||||
|
hostnode.add_feature('malicious', malicious)
|
||||||
|
return tree
|
||||||
|
|
||||||
def load_tree(self, capture_uuid: str) -> Tuple[str, str, str, str, Dict[str, str]]:
|
def load_tree(self, capture_uuid: str) -> Tuple[str, str, str, str, Dict[str, str]]:
|
||||||
capture_dir = self.lookup_capture_dir(capture_uuid)
|
capture_dir = self.lookup_capture_dir(capture_uuid)
|
||||||
if not capture_dir:
|
if not capture_dir:
|
||||||
|
@ -268,6 +342,7 @@ class Lookyloo():
|
||||||
with open((capture_dir / 'meta'), 'r') as f:
|
with open((capture_dir / 'meta'), 'r') as f:
|
||||||
meta = json.load(f)
|
meta = json.load(f)
|
||||||
ct = self.get_crawled_tree(capture_uuid)
|
ct = self.get_crawled_tree(capture_uuid)
|
||||||
|
ct = self.bodies_legitimacy_check(ct)
|
||||||
return ct.to_json(), ct.start_time.isoformat(), ct.user_agent, ct.root_url, meta
|
return ct.to_json(), ct.start_time.isoformat(), ct.user_agent, ct.root_url, meta
|
||||||
|
|
||||||
def remove_pickle(self, capture_uuid: str) -> None:
|
def remove_pickle(self, capture_uuid: str) -> None:
|
||||||
|
|
|
@ -140,7 +140,7 @@ description = "Foreign Function Interface for Python calling C code."
|
||||||
name = "cffi"
|
name = "cffi"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "1.14.1"
|
version = "1.14.2"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pycparser = "*"
|
pycparser = "*"
|
||||||
|
@ -580,7 +580,7 @@ description = "Library for building powerful interactive command lines in Python
|
||||||
name = "prompt-toolkit"
|
name = "prompt-toolkit"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6.1"
|
python-versions = ">=3.6.1"
|
||||||
version = "3.0.5"
|
version = "3.0.6"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
wcwidth = "*"
|
wcwidth = "*"
|
||||||
|
@ -1186,34 +1186,34 @@ certifi = [
|
||||||
{file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"},
|
{file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"},
|
||||||
]
|
]
|
||||||
cffi = [
|
cffi = [
|
||||||
{file = "cffi-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:66dd45eb9530e3dde8f7c009f84568bc7cac489b93d04ac86e3111fb46e470c2"},
|
{file = "cffi-1.14.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:da9d3c506f43e220336433dffe643fbfa40096d408cb9b7f2477892f369d5f82"},
|
||||||
{file = "cffi-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:4f53e4128c81ca3212ff4cf097c797ab44646a40b42ec02a891155cd7a2ba4d8"},
|
{file = "cffi-1.14.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23e44937d7695c27c66a54d793dd4b45889a81b35c0751ba91040fe825ec59c4"},
|
||||||
{file = "cffi-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:833401b15de1bb92791d7b6fb353d4af60dc688eaa521bd97203dcd2d124a7c1"},
|
{file = "cffi-1.14.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:0da50dcbccd7cb7e6c741ab7912b2eff48e85af217d72b57f80ebc616257125e"},
|
||||||
{file = "cffi-1.14.1-cp27-cp27m-win32.whl", hash = "sha256:26f33e8f6a70c255767e3c3f957ccafc7f1f706b966e110b855bfe944511f1f9"},
|
{file = "cffi-1.14.2-cp27-cp27m-win32.whl", hash = "sha256:76ada88d62eb24de7051c5157a1a78fd853cca9b91c0713c2e973e4196271d0c"},
|
||||||
{file = "cffi-1.14.1-cp27-cp27m-win_amd64.whl", hash = "sha256:b87dfa9f10a470eee7f24234a37d1d5f51e5f5fa9eeffda7c282e2b8f5162eb1"},
|
{file = "cffi-1.14.2-cp27-cp27m-win_amd64.whl", hash = "sha256:15a5f59a4808f82d8ec7364cbace851df591c2d43bc76bcbe5c4543a7ddd1bf1"},
|
||||||
{file = "cffi-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:effd2ba52cee4ceff1a77f20d2a9f9bf8d50353c854a282b8760ac15b9833168"},
|
{file = "cffi-1.14.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e4082d832e36e7f9b2278bc774886ca8207346b99f278e54c9de4834f17232f7"},
|
||||||
{file = "cffi-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bac0d6f7728a9cc3c1e06d4fcbac12aaa70e9379b3025b27ec1226f0e2d404cf"},
|
{file = "cffi-1.14.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:57214fa5430399dffd54f4be37b56fe22cedb2b98862550d43cc085fb698dc2c"},
|
||||||
{file = "cffi-1.14.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d6033b4ffa34ef70f0b8086fd4c3df4bf801fee485a8a7d4519399818351aa8e"},
|
{file = "cffi-1.14.2-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:6843db0343e12e3f52cc58430ad559d850a53684f5b352540ca3f1bc56df0731"},
|
||||||
{file = "cffi-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8416ed88ddc057bab0526d4e4e9f3660f614ac2394b5e019a628cdfff3733849"},
|
{file = "cffi-1.14.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:577791f948d34d569acb2d1add5831731c59d5a0c50a6d9f629ae1cefd9ca4a0"},
|
||||||
{file = "cffi-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:892daa86384994fdf4856cb43c93f40cbe80f7f95bb5da94971b39c7f54b3a9c"},
|
{file = "cffi-1.14.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:8662aabfeab00cea149a3d1c2999b0731e70c6b5bac596d95d13f643e76d3d4e"},
|
||||||
{file = "cffi-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:c991112622baee0ae4d55c008380c32ecfd0ad417bcd0417ba432e6ba7328caa"},
|
{file = "cffi-1.14.2-cp35-cp35m-win32.whl", hash = "sha256:837398c2ec00228679513802e3744d1e8e3cb1204aa6ad408b6aff081e99a487"},
|
||||||
{file = "cffi-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:fcf32bf76dc25e30ed793145a57426064520890d7c02866eb93d3e4abe516948"},
|
{file = "cffi-1.14.2-cp35-cp35m-win_amd64.whl", hash = "sha256:bf44a9a0141a082e89c90e8d785b212a872db793a0080c20f6ae6e2a0ebf82ad"},
|
||||||
{file = "cffi-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f960375e9823ae6a07072ff7f8a85954e5a6434f97869f50d0e41649a1c8144f"},
|
{file = "cffi-1.14.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:29c4688ace466a365b85a51dcc5e3c853c1d283f293dfcc12f7a77e498f160d2"},
|
||||||
{file = "cffi-1.14.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a6d28e7f14ecf3b2ad67c4f106841218c8ab12a0683b1528534a6c87d2307af3"},
|
{file = "cffi-1.14.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:99cc66b33c418cd579c0f03b77b94263c305c389cb0c6972dac420f24b3bf123"},
|
||||||
{file = "cffi-1.14.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:cda422d54ee7905bfc53ee6915ab68fe7b230cacf581110df4272ee10462aadc"},
|
{file = "cffi-1.14.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:65867d63f0fd1b500fa343d7798fa64e9e681b594e0a07dc934c13e76ee28fb1"},
|
||||||
{file = "cffi-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:4a03416915b82b81af5502459a8a9dd62a3c299b295dcdf470877cb948d655f2"},
|
{file = "cffi-1.14.2-cp36-cp36m-win32.whl", hash = "sha256:f5033952def24172e60493b68717792e3aebb387a8d186c43c020d9363ee7281"},
|
||||||
{file = "cffi-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:4ce1e995aeecf7cc32380bc11598bfdfa017d592259d5da00fc7ded11e61d022"},
|
{file = "cffi-1.14.2-cp36-cp36m-win_amd64.whl", hash = "sha256:7057613efefd36cacabbdbcef010e0a9c20a88fc07eb3e616019ea1692fa5df4"},
|
||||||
{file = "cffi-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e23cb7f1d8e0f93addf0cae3c5b6f00324cccb4a7949ee558d7b6ca973ab8ae9"},
|
{file = "cffi-1.14.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6539314d84c4d36f28d73adc1b45e9f4ee2a89cdc7e5d2b0a6dbacba31906798"},
|
||||||
{file = "cffi-1.14.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ddff0b2bd7edcc8c82d1adde6dbbf5e60d57ce985402541cd2985c27f7bec2a0"},
|
{file = "cffi-1.14.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:672b539db20fef6b03d6f7a14b5825d57c98e4026401fce838849f8de73fe4d4"},
|
||||||
{file = "cffi-1.14.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f90c2267101010de42f7273c94a1f026e56cbc043f9330acd8a80e64300aba33"},
|
{file = "cffi-1.14.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:95e9094162fa712f18b4f60896e34b621df99147c2cee216cfa8f022294e8e9f"},
|
||||||
{file = "cffi-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:3cd2c044517f38d1b577f05927fb9729d3396f1d44d0c659a445599e79519792"},
|
{file = "cffi-1.14.2-cp37-cp37m-win32.whl", hash = "sha256:b9aa9d8818c2e917fa2c105ad538e222a5bce59777133840b93134022a7ce650"},
|
||||||
{file = "cffi-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fa72a52a906425416f41738728268072d5acfd48cbe7796af07a923236bcf96"},
|
{file = "cffi-1.14.2-cp37-cp37m-win_amd64.whl", hash = "sha256:e4b9b7af398c32e408c00eb4e0d33ced2f9121fd9fb978e6c1b57edd014a7d15"},
|
||||||
{file = "cffi-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:267adcf6e68d77ba154334a3e4fc921b8e63cbb38ca00d33d40655d4228502bc"},
|
{file = "cffi-1.14.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e613514a82539fc48291d01933951a13ae93b6b444a88782480be32245ed4afa"},
|
||||||
{file = "cffi-1.14.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:d3148b6ba3923c5850ea197a91a42683f946dba7e8eb82dfa211ab7e708de939"},
|
{file = "cffi-1.14.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:9b219511d8b64d3fa14261963933be34028ea0e57455baf6781fe399c2c3206c"},
|
||||||
{file = "cffi-1.14.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:98be759efdb5e5fa161e46d404f4e0ce388e72fbf7d9baf010aff16689e22abe"},
|
{file = "cffi-1.14.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c0b48b98d79cf795b0916c57bebbc6d16bb43b9fc9b8c9f57f4cf05881904c75"},
|
||||||
{file = "cffi-1.14.1-cp38-cp38-win32.whl", hash = "sha256:6923d077d9ae9e8bacbdb1c07ae78405a9306c8fd1af13bfa06ca891095eb995"},
|
{file = "cffi-1.14.2-cp38-cp38-win32.whl", hash = "sha256:15419020b0e812b40d96ec9d369b2bc8109cc3295eac6e013d3261343580cc7e"},
|
||||||
{file = "cffi-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:b1d6ebc891607e71fd9da71688fcf332a6630b7f5b7f5549e6e631821c0e5d90"},
|
{file = "cffi-1.14.2-cp38-cp38-win_amd64.whl", hash = "sha256:12a453e03124069b6896107ee133ae3ab04c624bb10683e1ed1c1663df17c13c"},
|
||||||
{file = "cffi-1.14.1.tar.gz", hash = "sha256:b2a2b0d276a136146e012154baefaea2758ef1f56ae9f4e01c612b0831e0bd2f"},
|
{file = "cffi-1.14.2.tar.gz", hash = "sha256:ae8f34d50af2c2154035984b8b5fc5d9ed63f32fe615646ab435b05b132ca91b"},
|
||||||
]
|
]
|
||||||
chardet = [
|
chardet = [
|
||||||
{file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"},
|
{file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"},
|
||||||
|
@ -1453,8 +1453,8 @@ pluggy = [
|
||||||
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
|
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
|
||||||
]
|
]
|
||||||
prompt-toolkit = [
|
prompt-toolkit = [
|
||||||
{file = "prompt_toolkit-3.0.5-py3-none-any.whl", hash = "sha256:df7e9e63aea609b1da3a65641ceaf5bc7d05e0a04de5bd45d05dbeffbabf9e04"},
|
{file = "prompt_toolkit-3.0.6-py3-none-any.whl", hash = "sha256:683397077a64cd1f750b71c05afcfc6612a7300cb6932666531e5a54f38ea564"},
|
||||||
{file = "prompt_toolkit-3.0.5.tar.gz", hash = "sha256:563d1a4140b63ff9dd587bda9557cffb2fe73650205ab6f4383092fb882e7dc8"},
|
{file = "prompt_toolkit-3.0.6.tar.gz", hash = "sha256:7630ab85a23302839a0f26b31cc24f518e6155dea1ed395ea61b42c45941b6a6"},
|
||||||
]
|
]
|
||||||
protego = [
|
protego = [
|
||||||
{file = "Protego-0.1.16.tar.gz", hash = "sha256:a682771bc7b51b2ff41466460896c1a5a653f9a1e71639ef365a72e66d8734b4"},
|
{file = "Protego-0.1.16.tar.gz", hash = "sha256:a682771bc7b51b2ff41466460896c1a5a653f9a1e71639ef365a72e66d8734b4"},
|
||||||
|
|
|
@ -492,6 +492,16 @@ def body_hash_details(body_hash: str):
|
||||||
return render_template('body_hash.html', body_hash=body_hash, domains=domains, captures=captures)
|
return render_template('body_hash.html', body_hash=body_hash, domains=domains, captures=captures)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/tree/<string:tree_uuid>/mark_as_legitimate', methods=['POST'])
|
||||||
|
def mark_as_legitimate(tree_uuid: str):
|
||||||
|
if request.data:
|
||||||
|
legitimate_entries = request.get_json(force=True)
|
||||||
|
lookyloo.add_to_legitimate(tree_uuid, **legitimate_entries)
|
||||||
|
else:
|
||||||
|
lookyloo.add_to_legitimate(tree_uuid)
|
||||||
|
return jsonify({'message': 'Legitimate entry added.'})
|
||||||
|
|
||||||
|
|
||||||
# Query API
|
# Query API
|
||||||
|
|
||||||
@app.route('/json/<string:tree_uuid>/redirects', methods=['GET'])
|
@app.route('/json/<string:tree_uuid>/redirects', methods=['GET'])
|
||||||
|
|
|
@ -161,6 +161,13 @@ function UnflagAllNodes() {
|
||||||
.on('mouseout', () => d3.select('#tooltip').style('opacity', 0));
|
.on('mouseout', () => d3.select('#tooltip').style('opacity', 0));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function MarkAsLegitimate(capture_uuid, hostnode_uuid=null, urlnode_uuid=null) {
|
||||||
|
let data = {};
|
||||||
|
if (hostnode_uuid != null) { data['hostnode_uuid'] = hostnode_uuid; };
|
||||||
|
if (urlnode_uuid != null) { data['urlnode_uuid'] = urlnode_uuid; };
|
||||||
|
$.post(`/tree/${capture_uuid}/mark_as_legitimate`, data);
|
||||||
|
};
|
||||||
|
|
||||||
function UnflagHostNode(hostnode_uuid) {
|
function UnflagHostNode(hostnode_uuid) {
|
||||||
d3.select(`#node_${hostnode_uuid}`).select('rect').style('fill', 'white');
|
d3.select(`#node_${hostnode_uuid}`).select('rect').style('fill', 'white');
|
||||||
d3.select(`#node_${hostnode_uuid}`).select('text').style('fill', 'black');
|
d3.select(`#node_${hostnode_uuid}`).select('text').style('fill', 'black');
|
||||||
|
@ -320,15 +327,13 @@ function update(root, computed_node_width=0) {
|
||||||
// Set background based on the computed width and height
|
// Set background based on the computed width and height
|
||||||
let background = main_svg.insert('rect', ':first-child')
|
let background = main_svg.insert('rect', ':first-child')
|
||||||
.attr('y', 0)
|
.attr('y', 0)
|
||||||
// FIXME: + 200 doesn't make much sense...
|
.attr('width', newWidth + (margin.right + margin.left)*2)
|
||||||
.attr('width', newWidth + margin.right + margin.left + 200)
|
|
||||||
.attr('height', newHeight + margin.top + margin.bottom)
|
.attr('height', newHeight + margin.top + margin.bottom)
|
||||||
.style('fill', "url(#backstripes)");
|
.style('fill', "url(#backstripes)");
|
||||||
|
|
||||||
// Update size
|
// Update size
|
||||||
d3.select("body svg")
|
main_svg
|
||||||
// FIXME: + 200 doesn't make much sense...
|
.attr("width", newWidth + (margin.right + margin.left)*2)
|
||||||
.attr("width", newWidth + margin.right + margin.left + 200)
|
|
||||||
.attr("height", newHeight + margin.top + margin.bottom)
|
.attr("height", newHeight + margin.top + margin.bottom)
|
||||||
|
|
||||||
// Update pattern
|
// Update pattern
|
||||||
|
@ -445,14 +450,14 @@ function update(root, computed_node_width=0) {
|
||||||
})
|
})
|
||||||
.on('mouseout', () => d3.select('#tooltip').style('opacity', 0));
|
.on('mouseout', () => d3.select('#tooltip').style('opacity', 0));
|
||||||
|
|
||||||
|
const http_icon_size = 24;
|
||||||
if (d.data.http_content) {
|
if (d.data.http_content) {
|
||||||
const icon_size = 24;
|
|
||||||
// set lock insecure connection
|
// set lock insecure connection
|
||||||
d3.select(this).append("svg").append('rect')
|
d3.select(this).append("svg").append('rect')
|
||||||
.attr('x', selected_node_bbox.width - 22)
|
.attr('x', selected_node_bbox.width - 22)
|
||||||
.attr('y', selected_node_bbox.height - 13)
|
.attr('y', selected_node_bbox.height - 13)
|
||||||
.attr('width', icon_size)
|
.attr('width', http_icon_size)
|
||||||
.attr('height', icon_size)
|
.attr('height', http_icon_size)
|
||||||
.attr('fill', 'white')
|
.attr('fill', 'white')
|
||||||
.attr('stroke', 'black');
|
.attr('stroke', 'black');
|
||||||
|
|
||||||
|
@ -460,8 +465,8 @@ function update(root, computed_node_width=0) {
|
||||||
.attr('x', selected_node_bbox.width - 22)
|
.attr('x', selected_node_bbox.width - 22)
|
||||||
.attr('y', selected_node_bbox.height - 13)
|
.attr('y', selected_node_bbox.height - 13)
|
||||||
.attr('id', 'insecure_image')
|
.attr('id', 'insecure_image')
|
||||||
.attr("width", icon_size)
|
.attr("width", http_icon_size)
|
||||||
.attr("height", icon_size)
|
.attr("height", http_icon_size)
|
||||||
.attr("xlink:href", '/static/insecure.svg')
|
.attr("xlink:href", '/static/insecure.svg')
|
||||||
.on('mouseover', () => {
|
.on('mouseover', () => {
|
||||||
d3.select('#tooltip')
|
d3.select('#tooltip')
|
||||||
|
@ -472,6 +477,33 @@ function update(root, computed_node_width=0) {
|
||||||
})
|
})
|
||||||
.on('mouseout', () => d3.select('#tooltip').style('opacity', 0));
|
.on('mouseout', () => d3.select('#tooltip').style('opacity', 0));
|
||||||
};
|
};
|
||||||
|
const malicious_icon_size = 24;
|
||||||
|
if (d.data.malicious) {
|
||||||
|
// set lock insecure connection
|
||||||
|
d3.select(this).append("svg").append('rect')
|
||||||
|
.attr('x', selected_node_bbox.width - 22 - http_icon_size)
|
||||||
|
.attr('y', selected_node_bbox.height - 13)
|
||||||
|
.attr('width', malicious_icon_size)
|
||||||
|
.attr('height', malicious_icon_size)
|
||||||
|
.attr('fill', 'white')
|
||||||
|
.attr('stroke', 'black');
|
||||||
|
|
||||||
|
d3.select(this).append('image')
|
||||||
|
.attr('x', selected_node_bbox.width - 22 - http_icon_size)
|
||||||
|
.attr('y', selected_node_bbox.height - 13)
|
||||||
|
.attr('id', 'insecure_image')
|
||||||
|
.attr("width", malicious_icon_size)
|
||||||
|
.attr("height", malicious_icon_size)
|
||||||
|
.attr("xlink:href", '/static/bomb.svg')
|
||||||
|
.on('mouseover', () => {
|
||||||
|
d3.select('#tooltip')
|
||||||
|
.style('opacity', 1)
|
||||||
|
.style('left', `${d3.event.pageX + 10}px`)
|
||||||
|
.style('top', `${d3.event.pageY + 10}px`)
|
||||||
|
.text('This node containts known malicious content');
|
||||||
|
})
|
||||||
|
.on('mouseout', () => d3.select('#tooltip').style('opacity', 0));
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
return node_group;
|
return node_group;
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li>
|
<li>
|
||||||
<a href="#unflag" role="button" onclick="UnflagAllNodes();">Unflag all nodes</a>
|
<a href="#/" role="button" onclick="UnflagAllNodes();">Unflag all nodes</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('image', tree_uuid=tree_uuid) }}" role="button">Download screenshot</a>
|
<a href="{{ url_for('image', tree_uuid=tree_uuid) }}" role="button">Download screenshot</a>
|
||||||
|
@ -101,6 +101,9 @@
|
||||||
<li>
|
<li>
|
||||||
<a href="#screenshotModal" data-toggle="modal" data-target="#screenshotModal" role="button">Show screenshot</a>
|
<a href="#screenshotModal" data-toggle="modal" data-target="#screenshotModal" role="button">Show screenshot</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#/" role="button" onclick="MarkAsLegitimate('{{ tree_uuid }}');">Mark capture as legitimate</a>
|
||||||
|
</li>
|
||||||
{% if enable_mail_notification %}
|
{% if enable_mail_notification %}
|
||||||
<li>
|
<li>
|
||||||
<a href="#emailModal" data-toggle="modal" data-target="#emailModal" role="button">Notify by mail</a>
|
<a href="#emailModal" data-toggle="modal" data-target="#emailModal" role="button">Notify by mail</a>
|
||||||
|
|
Loading…
Reference in New Issue