-
Notifications
You must be signed in to change notification settings - Fork 385
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #297 from 0xswitch/develop
New analyser : Google Vision API
- Loading branch information
Showing
5 changed files
with
190 additions
and
0 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
analyzers/GoogleVisionAPI/GoogleVisionAPI_WebDetection.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "GoogleVisionAPI_WebDetection", | ||
"version": "1.0.0", | ||
"author": "CERT-LaPoste", | ||
"url": "https://github.com/TheHive-Project/Cortex-Analyzers", | ||
"license": "AGPL-V3", | ||
"description": "Find look alike image via Google Cloud Vision API using the Web_Detection service ", | ||
"dataTypeList": ["file", "url"], | ||
"command": "GoogleVisionAPI/GoogleVisionAPI_WebDetection.py", | ||
"baseConfig": "GoogleVisionAPI", | ||
"config": { | ||
"service": "get" | ||
}, | ||
"configurationItems": [ | ||
{ | ||
"name": "api_key", | ||
"description": "API key for this service", | ||
"type": "string", | ||
"multi": false, | ||
"required": true | ||
}, | ||
{ | ||
"name": "max_Result", | ||
"description": "Maximum number of url to fetch", | ||
"type": "string", | ||
"multi": false, | ||
"required": false | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#!/usr/bin/python3 | ||
#coding:utf-8 | ||
|
||
from cortexutils.analyzer import Analyzer | ||
from requests import post | ||
from json import dumps, loads | ||
from base64 import b64encode | ||
|
||
class GoogleAPI_Vision(Analyzer): | ||
|
||
def __init__(self): | ||
Analyzer.__init__(self) | ||
self.api_endpoint = "https://vision.googleapis.com/v1/images:annotate" | ||
|
||
def make_api_call(self, url: str, query: str, api_key: str, https_proxy: str, maxResults: int, datatype: str, file=None) -> dict: | ||
|
||
header = { | ||
"Content-Type" : "application/json" | ||
} | ||
|
||
data = { | ||
"requests": [{ | ||
"image": { | ||
"source": { | ||
"imageUri": query | ||
} | ||
}, | ||
"features": [{ | ||
"type": "WEB_DETECTION", | ||
"maxResults": maxResults | ||
}] | ||
}] | ||
} | ||
|
||
if datatype == "file": | ||
try: | ||
query = b64encode(open(file, "rb").read()).decode("utf-8") | ||
except FileNotFoundError: | ||
self.error("Error while reading provided file") | ||
else: | ||
del data["requests"][0]["image"]["source"] | ||
data["requests"][0]["image"]["content"] = query | ||
|
||
try: | ||
api_answser = loads(post(url + "?key=" + api_key, data=dumps(data), headers=header, proxies=https_proxy).text) | ||
except ValueError: | ||
self.error("Cannot parse JSON answer from server") | ||
else: | ||
return api_answser | ||
|
||
def get_artifacts(self, google_results: str) -> list: | ||
return [ item["url"] for item in google_results['responses'][0]["webDetection"]["pagesWithMatchingImages"]] | ||
|
||
def run(self): | ||
query = self.getData() | ||
|
||
if query is None: | ||
self.error("You must provide a file or a valid url to this image") | ||
|
||
api_key = self.getParam("config.api_key") | ||
if api_key is None: | ||
self.error("You need an API key for Google Vision API") | ||
|
||
https_proxy = { "https" : self.getParam("config.proxy_https") } | ||
maxResults = self.getParam("config.max_Result") | ||
maxResults = maxResults if maxResults is not None else 100 | ||
|
||
answer = self.make_api_call(self.api_endpoint, query, api_key, https_proxy, maxResults, self.data_type, file=self.getParam("file")) | ||
self.report({ 'api_full_report' : answer }) | ||
|
||
def summary(self, raw): | ||
|
||
number_of_image_found = self.build_taxonomy("info", "GoogleVisionAPI", "pagesWithMatchingImages", str(len(raw["api_full_report"]["responses"][0]["webDetection"]["pagesWithMatchingImages"]))) | ||
number_of_look_alike = self.build_taxonomy("info", "GoogleVisionAPI", "visuallySimilarImages", str(len(raw["api_full_report"]["responses"][0]["webDetection"]["visuallySimilarImages"]))) | ||
|
||
return { "taxonomies" : [number_of_look_alike, number_of_image_found] } | ||
|
||
|
||
if __name__ == "__main__": | ||
GoogleAPI_Vision().run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cortexutils | ||
requests |
72 changes: 72 additions & 0 deletions
72
thehive-templates/GoogleVisionAPI_WebDetection_1_0_0/long.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<!-- Success --> | ||
<div class="panel panel-primary" ng-if="content.api_full_report.responses[0].webDetection.pagesWithMatchingImages.length > 0"> | ||
<div class="panel-heading"> | ||
Pages with matching images | ||
</div> | ||
<div class="panel-body"> | ||
<dl class="dl-horizontal" > | ||
<strong>Number of pages found : </strong> {{ content.api_full_report.responses[0].webDetection.pagesWithMatchingImages.length }} | ||
<dd> | ||
<div ng-repeat="pages in content.api_full_report.responses[0].webDetection.pagesWithMatchingImages | limitTo:50"> | ||
<span class="wrap"><a ng-href="{{ pages.url }}" target="_blank">{{pages.pageTitle }}</a></span> | ||
</div> | ||
</dd> | ||
</dl> | ||
</div> | ||
</div> | ||
|
||
<div class="panel panel-primary" ng-if="content.api_full_report.responses[0].webDetection.visuallySimilarImages.length > 0"> | ||
<div class="panel-heading"> | ||
Visually Similar Images | ||
</div> | ||
<div class="panel-body"> | ||
<dl class="dl-horizontal" > | ||
<strong>Number of similar image found : </strong> {{ content.api_full_report.responses[0].webDetection.visuallySimilarImages.length }} | ||
<dd> | ||
<div ng-repeat="similar in content.api_full_report.responses[0].webDetection.visuallySimilarImages | limitTo:50"> | ||
<span class="wrap"><a ng-href="{{ similar.url }}" target="_blank">{{similar.url }}</a></span> | ||
</div> | ||
</dd> | ||
</dl> | ||
</div> | ||
</div> | ||
|
||
<div class="panel panel-primary" ng-if="content.api_full_report.responses[0].webDetection.webEntities.length > 0"> | ||
<div class="panel-heading"> | ||
Web Entities | ||
</div> | ||
<div class="panel-body"> | ||
<dd> | ||
<div ng-repeat="entities in content.api_full_report.responses[0].webDetection.webEntities | limitTo:50"> | ||
<span class="wrap" ng-if="entities.description.length >0"><strong>{{ entities.description }} : </strong>{{ entities.score }}</span> | ||
</div> | ||
</dd> | ||
</div> | ||
</div> | ||
|
||
<!-- General error --> | ||
<div class="panel panel-danger" ng-if="content.api_full_report.error"> | ||
<div class="panel-heading"> | ||
<strong>An error occured</strong> | ||
</div> | ||
<div class="panel-body"> | ||
<dl class="dl-horizontal"> | ||
<dt><i class="fa fa-warning"></i> {{ content.api_full_report.error.status }} :</dt> | ||
<dd class="wrap">{{content.api_full_report.error.message}}</dd> | ||
</dl> | ||
</div> | ||
</div> | ||
|
||
<div class="panel panel-danger" ng-if="!content.success"> | ||
<div class="panel-heading"> | ||
<strong>An error occured</strong> | ||
</div> | ||
<div class="panel-body"> | ||
<dl class="dl-horizontal"> | ||
<dt><i class="fa fa-warning"></i> {{ content.errorMessage }} :</dt> | ||
<dd class="wrap">{{content.input}}</dd> | ||
</dl> | ||
</div> | ||
</div> | ||
|
||
|
6 changes: 6 additions & 0 deletions
6
thehive-templates/GoogleVisionAPI_WebDetection_1_0_0/short.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<span class="label" ng-repeat="t in content.taxonomies" | ||
ng-class="{'info': 'label-info', 'safe': 'label-success', | ||
'suspicious': 'label-warning', | ||
'malicious':'label-danger'}[t.level]"> | ||
{{t.namespace}}:{{t.predicate}}={{t.value}} | ||
</span> |