diff --git a/frontend/package.json b/frontend/package.json
index 9c01542..f5554aa 100755
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,6 +1,6 @@
{
"name": "frontend",
- "version": "0.2.1",
+ "version": "0.3.1",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
diff --git a/frontend/src/components/Login.vue b/frontend/src/components/Login.vue
index e63c81c..a316db7 100644
--- a/frontend/src/components/Login.vue
+++ b/frontend/src/components/Login.vue
@@ -78,6 +78,12 @@ export default {
},
computed: {
...mapGetters({ auth_status: "auth_status" })
+ },
+
+ beforeMount: function() {
+ if (this.$store.getters["is_authenticated"]) {
+ this.$router.push("/");
+ }
}
};
diff --git a/frontend/src/components/MultipleResourceInput.vue b/frontend/src/components/MultipleResourceInput.vue
index accf386..02d755e 100644
--- a/frontend/src/components/MultipleResourceInput.vue
+++ b/frontend/src/components/MultipleResourceInput.vue
@@ -124,7 +124,13 @@ export default {
preprocess_resources() {
if (!this.resource_list_model) return;
- let values = this.resource_list_model.trim().split("\n");
+ let values = this.resource_list_model
+ .trim()
+ .split("\n")
+ .filter(elem => elem.length > 0);
+
+ values = [...new Set(values)];
+
let classified_resources = [];
values.forEach(element => {
@@ -210,14 +216,10 @@ export default {
send() {
this.preprocess_resources.forEach(new_resource => {
let payload = {
- to_server: {
- url: "/api/create_resource",
- resource_name: new_resource.resource,
- resource_type: new_resource.type
- },
- mutation: "add_resource"
+ resource_name: new_resource.resource,
+ resource_type: new_resource.type
};
- this.$store.dispatch("resource_action", payload);
+ this.$store.dispatch("add_new_resource", payload);
});
},
patch_type(resource, type) {
@@ -240,12 +242,9 @@ export default {
max-height: 500px;
overflow-y: auto;
overflow-x: hidden;
-
}
.v-btn--bottom:not(.v-btn--absolute) {
bottom: 50px;
}
-
-
diff --git a/frontend/src/components/ResourceInput.vue b/frontend/src/components/ResourceInput.vue
deleted file mode 100644
index effcad1..0000000
--- a/frontend/src/components/ResourceInput.vue
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
-
- add
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SUBMIT
-
-
- You have to put a resource and select a resource type
-
-
-
-
-
-
-
diff --git a/frontend/src/components/ResourceListing.vue b/frontend/src/components/ResourceListing.vue
index a0cfaf9..0a7f00b 100644
--- a/frontend/src/components/ResourceListing.vue
+++ b/frontend/src/components/ResourceListing.vue
@@ -90,13 +90,7 @@
-
+
mdi-content-copy
@@ -116,12 +110,12 @@
:class="{ selected: selected_resource._id === item._id }"
>
-
- {{
+
+
+ {{
item[headers[1].value]
- }}
+ }}
+
@@ -144,7 +138,7 @@
- No resources yet.
+ No resources yet
@@ -154,7 +148,6 @@
v-if="a_resource_is_selected"
:resource="selected_resource"
:grid_space="grid_space"
- :resource_list="resourceDescription.resource_list"
:key="component_key"
>
@@ -189,7 +182,7 @@ export default {
return 0;
}
},
- resourceDescription: Object,
+ resourceType: String,
headers: Array,
grid_space: Number
},
@@ -205,10 +198,7 @@ export default {
},
computed: {
resource_list: function() {
- let resources = this.$store.getters.get_resources(
- this.resourceDescription.resource_list
- );
-
+ let resources = this.$store.getters.get_resources(this.resourceType);
this.resource_count = resources.length;
resources = resources.sort(this.sortcriteria);
@@ -236,22 +226,6 @@ export default {
}
},
methods: {
- get_resource_list: function() {
- let payload = {
- to_server: {
- url: "/api/get_resources",
- type: this.resourceDescription.type,
- fields: this.resourceDescription.fields
- },
- mutation: "set_resource_list",
- mutation_args: {
- list_name: this.resourceDescription.resource_list,
- list_values: []
- }
- };
- this.$store.dispatch("resource_action", payload);
- },
-
copy_resource_to_json: async function() {
await navigator.clipboard.writeText(
JSON.stringify(this.selected_resource, null, 2)
@@ -290,16 +264,10 @@ export default {
remove_resource_with_confirmation: function() {
this.remove_resource = false;
let payload = {
- to_server: {
- url: "/api/unlink_resource",
- resource_id: this.selected_resource._id
- },
- mutation: "remove_resource",
- mutation_args: {
- list_name: this.resourceDescription.resource_list
- }
+ resource_id: this.selected_resource._id
};
- this.$store.dispatch("resource_action", payload);
+
+ this.$store.dispatch("remove_resource", payload);
this.selected_resource = {};
},
@@ -309,8 +277,7 @@ export default {
tag_shake: function() {
let payload = {
- resource_id: this.selected_resource._id,
- resource_type: this.selected_resource.resource_type
+ resource_id: this.selected_resource._id
};
this.$store.dispatch("update_resource", payload);
},
@@ -320,9 +287,6 @@ export default {
rerender_component: function() {
this.component_key += 1;
}
- },
- mounted() {
- this.get_resource_list();
}
};
diff --git a/frontend/src/components/Root.vue b/frontend/src/components/Root.vue
index 807c969..224a44c 100644
--- a/frontend/src/components/Root.vue
+++ b/frontend/src/components/Root.vue
@@ -1,46 +1,23 @@
-
+
-
+
- {{ get_opened_project.name }}
-
-
+ >{{ get_opened_project.name }}
+
-
-
- mdi-account-circle-outline
-
+
+ mdi-account-circle-outline
-
+
eject
@@ -50,14 +27,8 @@
-
-
+
+
call
@@ -69,10 +40,7 @@
-
+
-
+
logout
@@ -102,20 +67,12 @@
-
+
-
+
NETWORK
DOMAIN
URL
@@ -132,12 +89,10 @@
-
- IP Address
-
+ IP Address
@@ -146,103 +101,72 @@
-
- Domains
-
+ Domains
-
+
-
- URLs
-
+ URLs
-
+
-
- Hashes
-
+ Hashes
-
+
-
- Emails
-
+ Emails
-
+
-
- Usernames
-
+ Usernames
-
- Flows
-
+ Flows
-
+
@@ -252,10 +176,7 @@
-
+
@@ -291,30 +212,7 @@ export default {
show_apikeys: false,
show_change_password: false,
update_interval: null,
- hash_resource_description: {
- type: "hash",
- resource_list: "hashlist"
- },
- ip_resource_description: {
- type: "ip",
- resource_list: "iplist"
- },
- domain_resource_description: {
- type: "domain",
- resource_list: "domainlist"
- },
- email_resource_description: {
- type: "email",
- resource_list: "emaillist"
- },
- username_resource_description: {
- type: "username",
- resource_list: "usernamelist"
- },
- url_resource_description: {
- type: "url",
- resource_list: "urllist"
- },
+
ip_table_headers: [
{
text: "IP",
@@ -387,7 +285,11 @@ export default {
},
computed: {
- ...mapGetters(["get_opened_project", "is_project_opened", "auth_status"]),
+ ...mapGetters([
+ "get_opened_project",
+ "is_project_opened",
+ "is_authenticated"
+ ]),
username: function() {
return this.$store.getters["username"];
}
@@ -396,14 +298,14 @@ export default {
mounted: function() {
let self = this;
this.update_interval = setInterval(function() {
- if (self.auth_status === "success") {
+ if (self.is_authenticated) {
self.$store.dispatch("update").catch();
}
}, 10000);
},
beforeMount: function() {
- if (this.$store.getters["auth_status"] === "") {
+ if (!this.$store.getters["is_authenticated"]) {
this.$router.push("/login");
}
}
diff --git a/frontend/src/components/StatusBar.vue b/frontend/src/components/StatusBar.vue
index 9720586..8f2cc9a 100644
--- a/frontend/src/components/StatusBar.vue
+++ b/frontend/src/components/StatusBar.vue
@@ -1,17 +1,11 @@
- v{{ version }}
+ v{{ version }}
-
+
- © {{ new Date().getFullYear() }}
+ © {{ new Date().getFullYear() }}
diff --git a/frontend/src/components/templates/pastebin/index.vue b/frontend/src/components/templates/pastebin/index.vue
index 3e55fb0..ef57e74 100644
--- a/frontend/src/components/templates/pastebin/index.vue
+++ b/frontend/src/components/templates/pastebin/index.vue
@@ -12,22 +12,22 @@
- {{
+
+ {{
paste.title
- }}
- Untitled paste
+ }}
+
+ Untitled paste
- User:
+ User:
{{ paste.user }}
No user
- Paste date:
+ Paste date:
{{ from_python_time(paste.date) }}
@@ -55,18 +55,17 @@
- Link:
+ Link:
{{ get_paste_link(paste.paste_key) }}
+ >{{ get_paste_link(paste.paste_key) }}
- Expire:
+ Expire:
{{ paste.expire }}
Never
diff --git a/frontend/src/components/templates/robtex/index.vue b/frontend/src/components/templates/robtex/index.vue
new file mode 100644
index 0000000..9f4a448
--- /dev/null
+++ b/frontend/src/components/templates/robtex/index.vue
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+ AS
+
+
+
+
+ AS:
+ {{ resource.results.as }}
+
+
+ name:
+ {{ resource.results.asname }}
+
+
+ description:
+ {{ resource.results.asdesc }}
+
+
+
+
+
+
+
+
+ BGP Route
+
+
+
+
+ whois-desc:
+ {{ resource.results.whoisdesc }}
+
+
+ route-desc:
+ {{ resource.results.routedesc }}
+
+
+ bgp-route:
+ {{ resource.results.bgproute }}
+
+
+
+
+
+
+
+
+ Geo
+
+
+
+
+ City:
+ {{ resource.results.city }}
+
+
+ Country:
+ {{ resource.results.country }}
+
+
+
+
+
+
+
+
+ Active (forward) DNS
+
+
+
+
+ domain:
+ {{ entry.o }}
+
+
+ timestamp:
+ {{ formatted_time(entry.t) }}
+
+
+
+
+
+
+
+
+ Active DNS history
+
+
+
+
+ domain:
+ {{ entry.o }}
+
+
+ timestamp:
+ {{ formatted_time(entry.t) }}
+
+
+
+
+
+
+
+
+ Pasive DNS
+
+
+
+
+ domain:
+ {{ entry.o }}
+
+
+ timestamp:
+ {{ formatted_time(entry.t) }}
+
+
+
+
+
+
+
+
+ Pasive DNS history
+
+
+
+
+ domain:
+ {{ entry.o }}
+
+
+ timestamp:
+ {{ formatted_time(entry.t) }}
+
+
+
+
+
+
+ Robtex plugin ran but the response status was not ok
+
+
+
+
+
diff --git a/frontend/src/store/modules/project.js b/frontend/src/store/modules/project.js
index 4641264..5c71e35 100644
--- a/frontend/src/store/modules/project.js
+++ b/frontend/src/store/modules/project.js
@@ -24,6 +24,7 @@ const getters = {
const actions = {
[SET_PROJECT]: ({ commit, dispatch }, project) => {
commit(SET_PROJECT, project);
+ dispatch("get_resources", null, { root: true });
},
[RESET_PROJECT]: ({ state, commit, dispatch }) => {
dispatch("reset_resource_lists", null, { root: true });
diff --git a/frontend/src/store/modules/resourcelist.js b/frontend/src/store/modules/resourcelist.js
index 1abc860..11985bb 100644
--- a/frontend/src/store/modules/resourcelist.js
+++ b/frontend/src/store/modules/resourcelist.js
@@ -6,20 +6,44 @@ import api_call from "../../utils/api";
Vue.use(Vuex);
const state = {
- iplist: [],
- domainlist: [],
- emaillist: [],
- hashlist: [],
- urllist: [],
- usernamelist: []
+ resources: []
};
const actions = {
- resource_action: async function({ commit }, payload) {
- await api_call({ ...payload.to_server }).then(resp => {
- payload.server_response = resp.data;
- commit(payload.mutation, { ...payload });
- });
+ get_resources: async function({ commit, getters }) {
+ let url = "/api/get_resources";
+ let project_id = getters.get_opened_project._id;
+
+ await api_call({ url: url, project_id: project_id })
+ .then(resp => {
+ commit("set_resources", resp.data);
+ })
+ .catch(err => console.log(err));
+ },
+
+ add_new_resource: async function({ commit }, payload) {
+ let url = "/api/create_resource";
+ await api_call({
+ url: url,
+ resource_name: payload.resource_name,
+ resource_type: payload.resource_type
+ })
+ .then(resp => {
+ commit("set_resources", resp.data);
+ })
+ .catch(err => console.log(err));
+ },
+
+ remove_resource: async function({ commit }, payload) {
+ let url = "/api/unlink_resource";
+ await api_call({
+ url: url,
+ resource_id: payload.resource_id
+ })
+ .then(_ => {
+ commit("unlink_resource", payload.resource_id);
+ })
+ .catch(err => console.log(err));
},
update: async function({ commit }) {
@@ -46,63 +70,41 @@ const actions = {
};
const mutations = {
- reset_resource_lists: function() {
- Object.keys(state).forEach(el => (state[el] = []));
- },
-
- set_resource_list: function(commit, payload) {
- let resources = [];
- payload.server_response.forEach(resource => {
- resources.push(resource);
+ set_resources: function(commit, resources) {
+ resources.forEach(resource => {
+ if (state.resources.some(el => el._id === resource._id)) {
+ return;
+ } else {
+ state.resources.push(resource);
+ }
});
- state[payload.mutation_args.list_name] = resources;
},
- remove_resource: function(commit, payload) {
- let resource_list = payload.mutation_args.list_name;
-
- state[resource_list] = state[resource_list].filter(
- el => el._id !== payload.to_server.resource_id
- );
+ reset_resource_lists: function() {
+ state.resources = [];
},
- add_resource: function(commit, payload) {
- payload.server_response.forEach(resource => {
- let list_name = resource.type + "list";
- let new_resource = resource.new_resource;
- let resource_list = state[list_name];
- if (resource_list.some(el => el._id === new_resource._id)) {
- return;
- }
- resource_list.push(new_resource);
- });
-
- return payload.server_response;
+ unlink_resource: function(commit, resource_id) {
+ state.resources = state.resources.filter(el => el._id !== resource_id);
},
add_update: async function(commit, update) {
let url = "/api/get_resource";
let resource_id = update.resource_id;
- let resource_type = update.resource_type;
- let resource_list = resource_type + "list";
await api_call({
url: url,
- resource_id: resource_id,
- resource_type: resource_type
+ resource_id: resource_id
}).then(resp => {
let resp_as_json = null;
+
try {
resp_as_json = JSON.parse(resp.data);
- // state[resource_list] = state[resource_list].filter(
- // el => el._id !== resp_as_json._id
- // );
- // state[resource_list].push(resp_as_json);
} catch (error) {
resp_as_json = resp.data;
}
- let resource = state[resource_list].find(el => el._id === resource_id);
+ let resource = state.resources.find(el => el._id === resource_id);
resource.plugins = resp_as_json.plugins;
resource.tags = resp_as_json.tags;
});
@@ -110,8 +112,9 @@ const mutations = {
};
const getters = {
- // reusable data accessors
- get_resources: state => resource_list => state[resource_list]
+ get_resources: state => resource_type => {
+ return state.resources.filter(elem => elem.resource_type === resource_type);
+ }
};
export default {
diff --git a/server/entities/domain.py b/server/entities/domain.py
deleted file mode 100755
index edc7f53..0000000
--- a/server/entities/domain.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import time
-import json
-import bson
-
-from server.db import DB
-from server.entities.resource_types import ResourceType
-from server.entities.resource_base import ResourceBase
-
-
-class Domains:
- db = DB("domain")
-
- @staticmethod
- def get_by_name(domain_name):
- domain_exists = Domains.db.collection.find_one({"domain": domain_name})
- if domain_exists:
- return Domain(domain_exists["_id"])
-
- else:
- args = {
- "canonical_name": domain_name,
- "domain": domain_name,
- "creation_time": time.time(),
- "plugins": [],
- "resource_type": "domain",
- "tags": [],
- }
- inserted_one = Domains.db.collection.insert_one(args)
-
- return Domain(inserted_one.inserted_id)
-
- @staticmethod
- def get_by_id(resource_id):
- return Domain(resource_id)
-
-
-class Domain(ResourceBase):
- def __init__(self, resource_id):
- super().__init__(resource_id, ResourceType.DOMAIN)
diff --git a/server/entities/email.py b/server/entities/email.py
deleted file mode 100755
index b6c0c6f..0000000
--- a/server/entities/email.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import time
-import json
-import bson
-
-from server.db import DB
-from server.entities.resource_types import ResourceType
-from server.entities.resource_base import ResourceBase
-
-
-class Emails:
- db = DB("email")
-
- @staticmethod
- def get_by_name(email):
- existing_email = Emails.db.collection.find_one({"email": email})
- if existing_email:
- return Email(existing_email["_id"])
-
- else:
- args = {
- "canonical_name": email,
- "email": email,
- "creation_time": time.time(),
- "domain": email.split("@")[1],
- "plugins": [],
- "resource_type": "email",
- "tags": [],
- }
- inserted_one = Emails.db.collection.insert_one(args)
-
- return Email(inserted_one.inserted_id)
-
- @staticmethod
- def get_by_id(resource_id):
- return Email(resource_id)
-
-
-class Email(ResourceBase):
- def __init__(self, resource_id):
- super().__init__(resource_id, ResourceType.EMAIL)
diff --git a/server/entities/hash.py b/server/entities/hash.py
deleted file mode 100755
index e023042..0000000
--- a/server/entities/hash.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import time
-import json
-import bson
-
-from server.db import DB
-from server.entities.resource_types import ResourceType
-from server.entities.resource_base import ResourceBase
-from server.entities.hash_types import HashType
-
-
-class Hashes:
- db = DB("hash")
-
- @staticmethod
- def get_by_name(hash_string):
- hash_string = hash_string.lower()
- existing_hash = Hashes.db.collection.find_one({"hash": hash_string})
- if existing_hash:
- return Hash(existing_hash["_id"])
-
- else:
- hash_type = HashType.hash_detection(hash_string)
-
- if hash_type == HashType.UNKNOWN:
- raise Exception(f"Oops. Unknown hash type in Hash.py {hash_string}")
- args = {
- "hash": hash_string,
- "creation_time": time.time(),
- "hash_type": hash_type.value,
- "hash_short": hash_string[:8],
- "canonical_name": hash_string[:8],
- "resource_type": "hash",
- "plugins": [],
- "tags": [],
- }
- inserted_one = Hashes.db.collection.insert_one(args)
-
- return Hash(inserted_one.inserted_id)
-
- @staticmethod
- def get_by_id(resource_id):
- return Hash(resource_id)
-
-
-class Hash(ResourceBase):
- def __init__(self, resource_id):
- super().__init__(resource_id, ResourceType.HASH)
diff --git a/server/entities/ip.py b/server/entities/ip.py
deleted file mode 100755
index e68993f..0000000
--- a/server/entities/ip.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import time
-import json
-import bson
-
-from server.db import DB
-from server.entities.resource_types import ResourceType
-from server.entities.resource_base import ResourceBase
-
-
-class IPs:
- db = DB("ip")
-
- @staticmethod
- def get_by_name(ip_address):
- if ":" in ip_address:
- ip_address = ip_address.split(":")[0]
-
- ip = IPs.db.collection.find_one({"address": ip_address})
- if ip:
- return IP(ip["_id"])
-
- else:
- args = {
- "canonical_name": ip_address,
- "resource_type": "ip",
- "address": ip_address,
- "creation_time": time.time(),
- "plugins": [],
- "tags": [],
- }
-
- inserted_one = IPs.db.collection.insert_one(args)
-
- return IP(inserted_one.inserted_id)
-
- @staticmethod
- def get_by_id(resource_id):
- return IP(resource_id)
-
-
-class IP(ResourceBase):
- def __init__(self, resource_id):
- super().__init__(resource_id, ResourceType.IPv4)
diff --git a/server/plugins/plugin_base.py b/server/entities/plugin_base.py
similarity index 74%
rename from server/plugins/plugin_base.py
rename to server/entities/plugin_base.py
index e4ebbe5..e24aea8 100755
--- a/server/plugins/plugin_base.py
+++ b/server/entities/plugin_base.py
@@ -1,5 +1,6 @@
import traceback
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
+from server.entities.resource_manager import ResourceManager
# TODO: Unused base class. Either deleted it or refactor plugins base class
class PluginBase:
@@ -24,11 +25,9 @@ def finishing_task(plugin_name, project_id, resource_id, resource_type, result):
print(result)
- resource_type = ResourceType(resource_type)
- resource = Resources.get(resource_id, resource_type)
- resource.set_plugin_results(
- plugin_name, project_id, resource_id, resource_type, result
- )
+ resource = ResourceManager.get(resource_id)
+ resource.set_plugin_results(plugin_name, project_id, result)
+
except Exception as e:
tb1 = traceback.TracebackException.from_exception(e)
print("".join(tb1.format()))
diff --git a/server/plugins/plugins.py b/server/entities/plugins.py
similarity index 96%
rename from server/plugins/plugins.py
rename to server/entities/plugins.py
index 5fdee87..62d2435 100755
--- a/server/plugins/plugins.py
+++ b/server/entities/plugins.py
@@ -6,7 +6,7 @@
PLUGIN_DIRECTORY = "server/plugins/"
PLUGIN_HIERARCHY = "server.plugins"
-EXCLUDE_SET = ["plugins.py", "__init__.py", "plugin_base.py", "TEMPLATE.py"]
+EXCLUDE_SET = ["__init__.py", "TEMPLATE.py"]
def _load_plugins(resource_type, name=None):
diff --git a/server/entities/project.py b/server/entities/project.py
index 34d190e..c2b99b1 100755
--- a/server/entities/project.py
+++ b/server/entities/project.py
@@ -4,7 +4,6 @@
import bson
from server.db import DB
-from server.entities.resource import Resources
from server.entities.resource_types import ResourceType
from server.entities.update_central import UpdateCentral
@@ -60,7 +59,7 @@ def remove_resource(self, resource_id):
def add_resource(self, resource):
data = {
- "resource_id": resource.get_id(),
+ "resource_id": resource.resource_id,
"resource_type": resource.get_type_value(),
}
@@ -74,21 +73,13 @@ def get_resource(self, resource_id):
{"resource_refs": 1},
)
- def get_resources(self, resource_type):
+ def get_resources(self):
result = self.db.collection.find_one(
- {
- "_id": self.project_id,
- "resource_refs.resource_type": resource_type.value,
- },
- {"resource_refs": 1},
+ {"_id": self.project_id,}, {"resource_refs": 1},
)
if result and "resource_refs" in result.keys():
- return [
- item["resource_id"]
- for item in result["resource_refs"]
- if item["resource_type"] == resource_type.value
- ]
+ return [item["resource_id"] for item in result["resource_refs"]]
else:
return []
diff --git a/server/entities/resource.py b/server/entities/resource.py
deleted file mode 100755
index dc3f6a6..0000000
--- a/server/entities/resource.py
+++ /dev/null
@@ -1,63 +0,0 @@
-import bson
-import re
-import validators
-
-from enum import Enum
-
-from server.db import DB
-from server.utils.validations import HashType, hash_detection
-
-from server.entities.ip import IPs
-from server.entities.domain import Domains
-from server.entities.email import Emails
-from server.entities.hash import Hashes
-from server.entities.url import URLs
-from server.entities.username import Usernames
-
-from server.entities.resource_types import ResourceType, ResourceTypeException
-
-
-class Resources:
- @staticmethod
- def get(resource_field, resource_type=None, get_by_name=False):
- if not get_by_name or not resource_type:
- attribute = "get_by_id"
- else:
- attribute = "get_by_name"
-
- if resource_type == ResourceType.UNKNOWN:
- raise ResourceTypeException()
-
- elif resource_type == ResourceType.IPv4:
- return getattr(IPs, attribute)(resource_field)
-
- elif resource_type == ResourceType.DOMAIN:
- return getattr(Domains, attribute)(resource_field)
-
- elif resource_type == ResourceType.EMAIL:
- return getattr(Emails, attribute)(resource_field)
-
- elif resource_type == ResourceType.HASH:
- return getattr(Hashes, attribute)(resource_field)
-
- elif resource_type == ResourceType.URL:
- return getattr(URLs, attribute)(resource_field)
-
- elif resource_type == ResourceType.USERNAME:
- return getattr(Usernames, attribute)(resource_field)
-
- @staticmethod
- def get_data_from_resources(resource_refs):
- result = []
- if not resource_refs:
- return result
-
- for resource_ref in resource_refs:
- resource = Resources.get(
- resource_ref["resource_id"],
- ResourceType.get_type_from_string(resource_ref["resource_type"]),
- )
-
- result.append(resource.get_data())
-
- return result
diff --git a/server/entities/resource_base.py b/server/entities/resource_base.py
index 8162628..2adbaae 100755
--- a/server/entities/resource_base.py
+++ b/server/entities/resource_base.py
@@ -2,34 +2,135 @@
import json
import bson
import time
+import urllib.parse
+
from server.db import DB
-from server.plugins.plugins import Plugins
+from server.entities.plugins import Plugins
from server.entities.update_central import UpdateCentral
+from server.entities.resource_types import ResourceType
+from server.entities.hash_types import HashType
+
+COLLECTION = "resources"
+
+# TODO: Legacy method for old database resources
+# TODO: Get rid of this legacy method
+def get_resource_legacy_method(resource_id):
+ """
+ Lookup the resource_id in all old documents
+ Returns resource and doc name to change global COLLECTION
+ """
+ docs = ["ip", "url", "username", "hash", "email", "domain"]
+
+ for doc in docs:
+ collection = DB(doc).collection
+ resource = collection.find_one({"_id": resource_id})
+
+ if resource:
+ return (resource, doc)
+
+ print(f"[resource_base/get_resource_legacy_method]: {resource_id}")
+
+ return (None, None)
+
+
+def enrich_by_type(args):
+ resource_type = ResourceType(args["resource_type"])
+
+ if resource_type == ResourceType.IPv4:
+ args["address"] = args["canonical_name"]
+
+ elif resource_type == ResourceType.USERNAME:
+ args["username"] = args["canonical_name"]
+
+ elif resource_type == ResourceType.URL:
+ args["full_url"] = args["canonical_name"]
+ url_parts = urllib.parse.urlparse(args["full_url"])
+ args["scheme"] = url_parts.scheme
+ args["netloc"] = url_parts.netloc
+ args["path"] = url_parts.path
+ args["params"] = url_parts.params
+ args["query"] = url_parts.query
+ args["fragment"] = url_parts.fragment
-class ResourceBase:
- def __init__(self, resource_id, resource_type):
+ elif resource_type == ResourceType.HASH:
+ args["hash"] = args["canonical_name"]
+ args["hash_type"] = HashType.hash_detection(args["hash"]).value
+ # canonical_name == printable name in the view
+ args["canonical_name"] = args["hash"][:8]
+
+ elif resource_type == ResourceType.EMAIL:
+ args["email"] = args["canonical_name"]
+ if "@" in args["email"]:
+ args["domain"] = args["email"].split("@")[1]
+ else:
+ args["domain"] = None
+
+ elif resource_type == ResourceType.DOMAIN:
+ args["domain"] = args["canonical_name"]
+
+ else:
+ print(
+ f"[entities/resource_base/enrich_by_type]: Unknown resource type {args['resource_type']} when creating resource."
+ )
+
+ return args
+
+
+class Resource:
+ @staticmethod
+ def collection(collection=COLLECTION):
+ return DB(collection).collection
+
+ @staticmethod
+ def create(name, resource_type):
+ """
+ name: name of the resource
+ type: type as ResourceType
+ """
+ args = {
+ "canonical_name": name,
+ "resource_type": resource_type.value,
+ "creation_time": time.time(),
+ "plugins": [],
+ "tags": [],
+ }
+
+ args = enrich_by_type(args)
+ result = Resource.collection().insert_one(args)
+ print(f"Creating new resource with {args}")
+ return Resource(str(result.inserted_id))
+
+ def __init__(self, resource_id):
self.resource_id = bson.ObjectId(resource_id)
- self.type = resource_type
+ collection = COLLECTION
+ self.resource = Resource.collection(collection).find_one(
+ {"_id": self.resource_id}
+ )
+ # TODO: Get rid of this legacy method
+ # We have found anything, try legacy database method
+ if not self.resource:
+ # If found, change global resource database
+ self.resource, collection = get_resource_legacy_method(self.resource_id)
- def collection(self):
- return DB(self.get_type_value()).collection
+ # Store collection name
+ self.own_collection = collection
- def get_id(self):
- return self.resource_id
+ def get_collection(self):
+ return Resource.collection(self.own_collection)
def get_id_as_string(self):
return str(self.resource_id)
def get_type(self):
- return self.type
+ return ResourceType.get_type_from_string(self.resource["resource_type"])
def get_type_value(self):
- return self.type.value
+ return self.get_type().value
def get_data(self):
- return DB(self.get_type_value()).collection.find_one({"_id": self.resource_id})
+ return self.resource
def launch_plugins(self, project_id, profile=None):
try:
@@ -47,16 +148,14 @@ def launch_plugin(self, project_id, plugin_name, profile=None):
tb1 = traceback.TracebackException.from_exception(e)
print("".join(tb1.format()))
- def set_plugin_results(
- self, plugin_name, project_id, resource_id, resource_type, query_result
- ):
+ def set_plugin_results(self, plugin_name, project_id, query_result):
# TODO: Should we store an time-based diff of results if they differ?
- result_exists = self.collection().find_one(
+ result_exists = self.get_collection().find_one(
{"_id": self.resource_id, f"plugins.name": plugin_name}
)
if not result_exists:
- self.collection().update_one(
+ self.get_collection().update_one(
{"_id": self.resource_id},
{
"$addToSet": {
@@ -76,10 +175,10 @@ def set_plugin_results(
plugin["results"] = query_result
plugin["update_time"] = time.time()
- self.collection().replace_one({"_id": self.resource_id}, result_exists)
+ self.get_collection().replace_one({"_id": self.resource_id}, result_exists)
UpdateCentral().set_pending_update(
- project_id, resource_id, resource_type, plugin_name
+ project_id, self.get_id_as_string(), self.get_type(), plugin_name
)
def get_plugins(self, project_id):
@@ -92,7 +191,7 @@ def get_plugins(self, project_id):
def manage_tag(self, tag):
try:
- resource = self.collection().find_one({"_id": self.get_id()})
+ resource = self.get_collection().find_one({"_id": self.resource_id})
if "tags" in resource:
if tag["name"] in [t["name"] for t in resource["tags"]]:
@@ -106,7 +205,7 @@ def manage_tag(self, tag):
else:
resource["tags"] = [tag]
- self.collection().replace_one({"_id": self.resource_id}, resource)
+ self.get_collection().replace_one({"_id": self.resource_id}, resource)
except Exception as e:
tb1 = traceback.TracebackException.from_exception(e)
@@ -125,9 +224,10 @@ def get_doc_if_reference(plugin_name, entry):
)
return entry
- doc = DB(self.get_type_value()).collection.find_one({"_id": self.resource_id})
+ # doc = self.get_collection().find_one({"_id": self.resource_id})
# HACK: Curiously, this seens to work in order to eliminated the double "" JSON encoding
# when converting from ObjectId to String
+ doc = self.resource
for plugin in doc["plugins"]:
if "results" in plugin and isinstance(plugin["results"], list):
diff --git a/server/entities/resource_manager.py b/server/entities/resource_manager.py
new file mode 100644
index 0000000..879f1d7
--- /dev/null
+++ b/server/entities/resource_manager.py
@@ -0,0 +1,70 @@
+import bson
+import re
+import validators
+
+from enum import Enum
+
+from server.db import DB
+from server.entities.resource_base import Resource
+from server.entities.resource_types import ResourceType, ResourceTypeException
+
+
+class ResourceManager:
+ @staticmethod
+ def get(resource_id):
+ """
+ Return a resource by its ID.
+ The resource must exists in database, otherwise use legacy db method
+ """
+ return Resource(resource_id)
+
+ # TODO: "resource_type" should not be needed here, all resources must have a "searchable" field.
+ @staticmethod
+ def get_by_name(resource_name, resource_type):
+ """
+ Lookup database for a resource with name "resource_name"
+ if None is found, then create the resource.
+ """
+ search = "canonical_name"
+ resource_type = ResourceType.get_type_from_string(resource_type)
+
+ if resource_type == ResourceType.HASH:
+ search = "hash"
+
+ db = Resource.collection()
+ result = db.find_one({search: resource_name})
+ if result:
+ return Resource(result["_id"])
+
+ # TODO: Legacy method for old database resources
+ # TODO: Get rid of this legacy method
+ if not result:
+ docs = ["ip", "url", "username", "hash", "email", "domain"]
+ for doc in docs:
+ result = DB(doc).collection.find_one({search: resource_name})
+ if result:
+ return Resource(result["_id"])
+
+ print(f"Tried get_by_name nothing found {result}")
+ return None
+
+ @staticmethod
+ def get_or_create(resource_name, resource_type):
+ created = False
+ resource = ResourceManager.get_by_name(resource_name, resource_type)
+ if not resource:
+ resource = Resource.create(resource_name, resource_type)
+ created = True
+ return (resource, created)
+
+ @staticmethod
+ def get_data_from_resources(resource_refs):
+ result = []
+ if not resource_refs:
+ return result
+
+ for resource_ref in resource_refs:
+ resource = ResourceManager.get(resource_ref["resource_id"],)
+ result.append(resource.get_data())
+
+ return result
diff --git a/server/entities/url.py b/server/entities/url.py
deleted file mode 100755
index 66c94b6..0000000
--- a/server/entities/url.py
+++ /dev/null
@@ -1,49 +0,0 @@
-import time
-import json
-import bson
-import urllib.parse
-
-from server.db import DB
-from server.entities.resource_types import ResourceType
-from server.entities.resource_base import ResourceBase
-
-
-class URLs:
- db = DB("url")
-
- @staticmethod
- def get_by_name(url):
- previous_url = URLs.db.collection.find_one({"full_url": url})
- if previous_url:
- return URL(previous_url["_id"])
-
- else:
- url_parts = urllib.parse.urlparse(url)
-
- args = {
- "canonical_name": url,
- "resource_type": "url",
- "scheme": url_parts.scheme,
- "netloc": url_parts.netloc,
- "path": url_parts.path,
- "params": url_parts.params,
- "query": url_parts.query,
- "fragment": url_parts.fragment,
- "full_url": url,
- "creation_time": time.time(),
- "plugins": [],
- "tags": [],
- }
-
- inserted_one = URLs.db.collection.insert_one(args)
-
- return URL(inserted_one.inserted_id)
-
- @staticmethod
- def get_by_id(resource_id):
- return URL(resource_id)
-
-
-class URL(ResourceBase):
- def __init__(self, resource_id):
- super().__init__(resource_id, ResourceType.URL)
diff --git a/server/entities/username.py b/server/entities/username.py
deleted file mode 100755
index 20ee267..0000000
--- a/server/entities/username.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import time
-import json
-import bson
-
-from server.db import DB
-from server.entities.resource_types import ResourceType
-from server.entities.resource_base import ResourceBase
-
-
-class Usernames:
- db = DB("username")
-
- @staticmethod
- def get_by_name(username):
- existing_username = Usernames.db.collection.find_one({"username": username})
- if existing_username:
- return Username(existing_username["_id"])
-
- else:
- args = {
- "canonical_name": username,
- "username": username,
- "creation_time": time.time(),
- "plugins": [],
- "resource_type": "username",
- "tags": [],
- "sites": [],
- }
- inserted_one = Usernames.db.collection.insert_one(args)
-
- return Username(inserted_one.inserted_id)
-
- @staticmethod
- def get_by_id(resource_id):
- return Username(resource_id)
-
-
-class Username(ResourceBase):
- def __init__(self, resource_id):
- super().__init__(resource_id, ResourceType.USERNAME)
diff --git a/server/plugins/TEMPLATE.py b/server/plugins/TEMPLATE.py
index add03c2..876bae2 100644
--- a/server/plugins/TEMPLATE.py
+++ b/server/plugins/TEMPLATE.py
@@ -11,8 +11,8 @@
# [DONOTDELETE] - Internal usage dependencies
-from server.entities.resource import Resources, ResourceType
-from server.plugins.plugin_base import finishing_task
+from server.entities.resource_types import ResourceType
+from server.entities.plugin_base import finishing_task
from tasks.tasks import celery_app
diff --git a/server/plugins/abuseipdb.py b/server/plugins/abuseipdb.py
index b7fc4c2..73deda1 100755
--- a/server/plugins/abuseipdb.py
+++ b/server/plugins/abuseipdb.py
@@ -3,9 +3,9 @@
import requests
from tasks.api_keys import KeyRing
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
API_KEY = KeyRing().get("abuseipdb")
URL = "https://api.abuseipdb.com/api/v2/check"
diff --git a/server/plugins/basic_ip.py b/server/plugins/basic_ip.py
index 67bd37d..7bc8560 100755
--- a/server/plugins/basic_ip.py
+++ b/server/plugins/basic_ip.py
@@ -4,10 +4,10 @@
import traceback
from ipwhois import IPWhois
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
from dns import resolver, reversename
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# Which resources are this plugin able to work with
diff --git a/server/plugins/binaryedge.py b/server/plugins/binaryedge.py
index 21152d4..d7a05e1 100755
--- a/server/plugins/binaryedge.py
+++ b/server/plugins/binaryedge.py
@@ -3,9 +3,9 @@
import requests
from tasks.api_keys import KeyRing
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# 250 requests left, 31 days until renewal.
API_KEY = KeyRing().get("binaryedge")
diff --git a/server/plugins/botscout.py b/server/plugins/botscout.py
index fbb7b34..49b9887 100755
--- a/server/plugins/botscout.py
+++ b/server/plugins/botscout.py
@@ -1,7 +1,8 @@
import traceback
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
+
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# Login with the following information:
# Login Name: zigineki@getnada.com
@@ -12,6 +13,7 @@
import json
import urllib.request
from bs4 import BeautifulSoup
+from server.entities.resource_manager import ResourceManager
from tasks.api_keys import KeyRing
@@ -109,7 +111,7 @@ def botscout_task(plugin_name, project_id, resource_id, resource_type, ip):
else:
print("BotScout resource type does not found")
- resource = Resources.get(resource_id, resource_type)
+ resource = ResourceManager.get(resource_id)
resource.set_plugin_results(
plugin_name, project_id, resource_id, resource_type, query_result
)
diff --git a/server/plugins/diario.py b/server/plugins/diario.py
index 93c6180..925d725 100755
--- a/server/plugins/diario.py
+++ b/server/plugins/diario.py
@@ -4,9 +4,9 @@
from diario import Diario
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
from tasks.api_keys import KeyRing
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
APP_ID = KeyRing().get("diario-appid")
diff --git a/server/plugins/dns.py b/server/plugins/dns.py
index 58d557a..7cc7323 100755
--- a/server/plugins/dns.py
+++ b/server/plugins/dns.py
@@ -6,9 +6,9 @@
import dns.resolver as resolver
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# Which resources are this plugin able to work with
RESOURCE_TARGET = [ResourceType.DOMAIN]
diff --git a/server/plugins/emailrep.py b/server/plugins/emailrep.py
index 6e02171..d824d11 100755
--- a/server/plugins/emailrep.py
+++ b/server/plugins/emailrep.py
@@ -4,8 +4,8 @@
from tasks.api_keys import KeyRing
from tasks.tasks import celery_app
-from server.entities.resource import Resources, ResourceType
-from server.plugins.plugin_base import finishing_task
+from server.entities.resource_types import ResourceType
+from server.entities.plugin_base import finishing_task
# At this time there is no need for an APIKEY
# API_KEY = KeyRing().get("emailrep")
diff --git a/server/plugins/geoip.py b/server/plugins/geoip.py
index 0d4e19c..c623d1c 100755
--- a/server/plugins/geoip.py
+++ b/server/plugins/geoip.py
@@ -4,9 +4,9 @@
import urllib.request
from tasks.api_keys import KeyRing
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# Which resources are this plugin able to work with
RESOURCE_TARGET = [ResourceType.IPv4]
diff --git a/server/plugins/haveibeenpwned.py b/server/plugins/haveibeenpwned.py
index 7d6d02b..c28e53e 100755
--- a/server/plugins/haveibeenpwned.py
+++ b/server/plugins/haveibeenpwned.py
@@ -1,12 +1,12 @@
import traceback
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
import json
import requests
from tasks.api_keys import KeyRing
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
API_KEY = KeyRing().get("haveibeenpwned")
URL = "https://haveibeenpwned.com/api/v3/{service}/{account}"
diff --git a/server/plugins/hunterio.py b/server/plugins/hunterio.py
index 5ef9450..2a2ba3b 100755
--- a/server/plugins/hunterio.py
+++ b/server/plugins/hunterio.py
@@ -3,9 +3,9 @@
import requests
from tasks.api_keys import KeyRing
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
API_KEY = KeyRing().get("hunterio")
diff --git a/server/plugins/maltiverse.py b/server/plugins/maltiverse.py
index 6b6461d..bb8d96a 100755
--- a/server/plugins/maltiverse.py
+++ b/server/plugins/maltiverse.py
@@ -7,9 +7,9 @@
from tasks.deps.maltiverse import Maltiverse
from tasks.api_keys import KeyRing
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# Maltiverse does not need api key in some operations
# Keeping this if they change their mind in a future
diff --git a/server/plugins/metagoofil.py b/server/plugins/metagoofil.py
index 06dac25..4e3b649 100644
--- a/server/plugins/metagoofil.py
+++ b/server/plugins/metagoofil.py
@@ -6,7 +6,7 @@
from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# Which resources are this plugin able to work with
RESOURCE_TARGET = [ResourceType.DOMAIN]
diff --git a/server/plugins/onyphe.py b/server/plugins/onyphe.py
index 4bdb7f7..bca5b6e 100755
--- a/server/plugins/onyphe.py
+++ b/server/plugins/onyphe.py
@@ -4,9 +4,9 @@
import urllib.request
from tasks.api_keys import KeyRing
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
API_KEY = KeyRing().get("onyphe")
diff --git a/server/plugins/otx.py b/server/plugins/otx.py
index a1ec62f..9c9166d 100755
--- a/server/plugins/otx.py
+++ b/server/plugins/otx.py
@@ -5,6 +5,8 @@
import json
import requests, base64
+from server.entities.resource_manager import ResourceManager
+
from tasks.api_keys import KeyRing
# https://otx.alienvault.com/api/v1/indicators/file/6c5360d41bd2b14b1565f5b18e5c203cf512e493/analysis
@@ -19,7 +21,7 @@
URL_IPv6 = "https://otx.alienvault.com/api/v1/indicators/IPv6/{ip}/{section}"
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
@@ -241,7 +243,7 @@ def otx_task(plugin_name, project_id, resource_id, resource_type, target):
else:
print("OTX resource type does not found")
- resource = Resources.get(resource_id, resource_type)
+ resource = ResourceManager.get(resource_id)
resource.set_plugin_results(
plugin_name, project_id, resource_id, resource_type, query_result
)
diff --git a/server/plugins/pastebin.py b/server/plugins/pastebin.py
index 9fc27b7..f45d731 100755
--- a/server/plugins/pastebin.py
+++ b/server/plugins/pastebin.py
@@ -6,10 +6,10 @@
from server.db import DB
from server.entities.pastebin_manager import PastebinManager, Paste
-from server.entities.resource import Resources, ResourceType
-from server.plugins.plugin_base import finishing_task
+from server.entities.resource_types import ResourceType
+from server.entities.plugin_base import finishing_task
from tasks.api_keys import KeyRing
-from tasks.subtasks.googlesearch import restricted_googlesearch
+from tasks.googlesearch import restricted_googlesearch
from tasks.tasks import celery_app
diff --git a/server/plugins/phishtank.py b/server/plugins/phishtank.py
index db15188..e202b2c 100755
--- a/server/plugins/phishtank.py
+++ b/server/plugins/phishtank.py
@@ -6,9 +6,9 @@
from urllib.parse import urlparse
from tasks.api_keys import KeyRing
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
API_KEY = KeyRing().get("phishtank")
diff --git a/server/plugins/pulsedive.py b/server/plugins/pulsedive.py
index 4596afe..8de5b92 100644
--- a/server/plugins/pulsedive.py
+++ b/server/plugins/pulsedive.py
@@ -7,8 +7,8 @@
import requests, base64
from tasks.api_keys import KeyRing
-
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_manager import ResourceManager
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
API_KEY = KeyRing().get("pulsedive")
@@ -136,7 +136,7 @@ def pulsedive_task(plugin_name, project_id, resource_id, resource_type, domain_o
else:
print("PulseDive resource type does not found")
- resource = Resources.get(resource_id, resource_type)
+ resource = ResourceManager.get(resource_id, resource_type)
resource.set_plugin_results(
plugin_name, project_id, resource_id, resource_type, query_result
)
diff --git a/server/plugins/robtex.py b/server/plugins/robtex.py
index e128e31..8d64056 100755
--- a/server/plugins/robtex.py
+++ b/server/plugins/robtex.py
@@ -2,9 +2,9 @@
import json
import requests
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# Which resources are this plugin able to work with
RESOURCE_TARGET = [ResourceType.IPv4]
diff --git a/server/plugins/sherlock.py b/server/plugins/sherlock.py
index 0451e84..9b2d2bb 100755
--- a/server/plugins/sherlock.py
+++ b/server/plugins/sherlock.py
@@ -4,9 +4,9 @@
import tasks.deps.sherlock.sherlock as _sherlock
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# Which resources are this plugin able to work with
RESOURCE_TARGET = [ResourceType.USERNAME]
diff --git a/server/plugins/shodan.py b/server/plugins/shodan.py
index 0866e76..956557b 100755
--- a/server/plugins/shodan.py
+++ b/server/plugins/shodan.py
@@ -3,9 +3,9 @@
import requests
from tasks.api_keys import KeyRing
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# Which resources are this plugin able to work with
RESOURCE_TARGET = [ResourceType.IPv4]
diff --git a/server/plugins/tacyt.py b/server/plugins/tacyt.py
index ad18a5d..96baefd 100755
--- a/server/plugins/tacyt.py
+++ b/server/plugins/tacyt.py
@@ -1,10 +1,10 @@
import traceback
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
from tasks.deps.tacyt import TacytApp as tacytsdk
from tasks.api_keys import KeyRing
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
APP_ID = KeyRing().get("tacyt-appid")
SECRET_KEY = KeyRing().get("tacyt-secret")
diff --git a/server/plugins/threatcrowd.py b/server/plugins/threatcrowd.py
index 317fc77..8e42743 100755
--- a/server/plugins/threatcrowd.py
+++ b/server/plugins/threatcrowd.py
@@ -2,9 +2,9 @@
import json
import requests
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
URL_IP = "https://www.threatcrowd.org/searchApi/v2/ip/report/?ip={ip}"
URL_DOMAIN = "https://www.threatcrowd.org/searchApi/v2/domain/report/?domain={domain}"
diff --git a/server/plugins/threatminer.py b/server/plugins/threatminer.py
index bdbd639..f0c0477 100755
--- a/server/plugins/threatminer.py
+++ b/server/plugins/threatminer.py
@@ -2,7 +2,8 @@
import json
import traceback
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
+from server.entities.resource_manager import ResourceManager
from tasks.tasks import celery_app
import json
import requests
@@ -210,7 +211,7 @@ def threatminer_task(plugin_name, project_id, resource_id, resource_type, domain
else:
print("threatminer resource type does not found")
- resource = Resources.get(resource_id, resource_type)
+ resource = ResourceManager.get(resource_id, resource_type)
resource.set_plugin_results(
plugin_name, project_id, resource_id, resource_type, query_result
)
diff --git a/server/plugins/urlscan.py b/server/plugins/urlscan.py
index 5ecc2f7..478da97 100755
--- a/server/plugins/urlscan.py
+++ b/server/plugins/urlscan.py
@@ -3,10 +3,10 @@
import time
import requests
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
from tasks.api_keys import KeyRing
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
API_KEY = KeyRing().get("urlscan")
SUBMISSION_URL = "https://urlscan.io/api/v1/scan/"
diff --git a/server/plugins/verifymail.py b/server/plugins/verifymail.py
index 8038825..1b154e9 100755
--- a/server/plugins/verifymail.py
+++ b/server/plugins/verifymail.py
@@ -3,9 +3,9 @@
import requests
from tasks.api_keys import KeyRing
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
API_KEY = KeyRing().get("verify-email")
URL = "https://app.verify-email.org/api/v1/{key}/verify/{email}"
diff --git a/server/plugins/virustotal.py b/server/plugins/virustotal.py
index e5012a2..d1a3634 100755
--- a/server/plugins/virustotal.py
+++ b/server/plugins/virustotal.py
@@ -4,8 +4,8 @@
from tasks.api_keys import KeyRing
from tasks.tasks import celery_app
-from server.entities.resource import Resources, ResourceType
-from server.plugins.plugin_base import finishing_task
+from server.entities.resource_types import ResourceType
+from server.entities.plugin_base import finishing_task
API_KEY = KeyRing().get("virustotal")
diff --git a/server/plugins/vt_domain.py b/server/plugins/vt_domain.py
index 06e04bd..63b9ed3 100644
--- a/server/plugins/vt_domain.py
+++ b/server/plugins/vt_domain.py
@@ -4,8 +4,8 @@
from tasks.api_keys import KeyRing
from tasks.tasks import celery_app
-from server.entities.resource import Resources, ResourceType
-from server.plugins.plugin_base import finishing_task
+from server.entities.resource_types import ResourceType
+from server.entities.plugin_base import finishing_task
API_KEY = KeyRing().get("virustotal")
diff --git a/server/plugins/whois.py b/server/plugins/whois.py
index 5acec0f..394765d 100755
--- a/server/plugins/whois.py
+++ b/server/plugins/whois.py
@@ -4,9 +4,9 @@
import json
import traceback
-from server.entities.resource import Resources, ResourceType
+from server.entities.resource_types import ResourceType
from tasks.tasks import celery_app
-from server.plugins.plugin_base import finishing_task
+from server.entities.plugin_base import finishing_task
# Which resources are this plugin able to work with
RESOURCE_TARGET = [ResourceType.DOMAIN, ResourceType.EMAIL]
diff --git a/server/routes/apikeys.py b/server/routes/apikeys.py
index fa47ed3..a6fde69 100755
--- a/server/routes/apikeys.py
+++ b/server/routes/apikeys.py
@@ -8,7 +8,6 @@
from server.db import DB
from server.utils.password import token_required
-from server.entities.user import User
apikeys_api = Blueprint("apikeys", __name__)
@@ -17,7 +16,7 @@
@token_required
def get_apikeys(user):
try:
- results = DB("apikeys").collection.find({}, {'_id': False})
+ results = DB("apikeys").collection.find({}, {"_id": False})
list_results = list(results)
return dumps(list_results)
@@ -26,6 +25,7 @@ def get_apikeys(user):
print(e)
return jsonify({"error_message": "Error getting API keys"}), 400
+
@apikeys_api.route("/api/upload_apikeys", methods=["POST"])
@token_required
def upload_apikeys(user):
@@ -42,6 +42,7 @@ def upload_apikeys(user):
print(e)
return jsonify({"error_message": "Error uploading API keys"}), 400
+
@apikeys_api.route("/api/remove_apikeys", methods=["POST"])
@token_required
def remove_apikeys(user):
@@ -49,9 +50,7 @@ def remove_apikeys(user):
apikeys = request.json["entries"]
for name in apikeys:
print(name)
- result = DB("apikeys").collection.remove(
- {"name": name["name"]}
- )
+ result = DB("apikeys").collection.remove({"name": name["name"]})
return json.dumps(apikeys, default=str)
diff --git a/server/routes/plugins.py b/server/routes/plugins.py
index 98e2b0f..55524bd 100755
--- a/server/routes/plugins.py
+++ b/server/routes/plugins.py
@@ -10,7 +10,7 @@
from server.utils.password import token_required
-from server.entities.resource import Resources
+from server.entities.resource_manager import ResourceManager
from server.entities.resource_types import ResourceType, ResourceTypeException
from server.entities.user import User
from server.entities.pastebin_manager import PastebinManager
@@ -38,7 +38,7 @@ def get_all_plugins(user):
return json.dumps(plugins)
except Exception as e:
- print(e)
+ print(f"[get_all_plugins]: {e}")
return jsonify({"error_message": "Error gettings plugins"}), 400
@@ -52,7 +52,7 @@ def get_plugins(user):
project = User(user).get_active_project()
resource_type = ResourceType(resource_type_as_string)
- resource = Resources.get(resource_id, resource_type)
+ resource = ResourceManager.get(resource_id)
plugin_list = resource.get_plugins(project_id)
return json.dumps(plugin_list, default=str)
@@ -72,7 +72,7 @@ def launch_plugin(user):
project = User(user).get_active_project()
resource_type = ResourceType(resource_type_as_string)
- resource = Resources.get(resource_id, resource_type)
+ resource = ResourceManager.get(resource_id)
resource.launch_plugin(project.get_id(), plugin_name)
return jsonify({"sucess_message": "ok"})
diff --git a/server/routes/resources.py b/server/routes/resources.py
index 31c77bf..e596751 100755
--- a/server/routes/resources.py
+++ b/server/routes/resources.py
@@ -9,73 +9,15 @@
from server.utils.password import token_required
-from server.entities.resource import Resources
+from server.entities.resource_manager import ResourceManager
+
from server.entities.resource_types import ResourceType, ResourceTypeException
from server.entities.user import User
+from server.entities.project import Project
resources_api = Blueprint("resources", __name__)
-@resources_api.route("/api/create_multiple_resources", methods=["POST"])
-@token_required
-def create_multiple_resources(user):
- try:
- project = User(user).get_active_project()
- response = []
-
- for entry in request.json["entries"]:
- resource_name = entry["resource"]
- resource_type = ResourceType.get_type_from_string(entry["type"].lower())
- if resource_type == ResourceType.UNKNOWN:
- print(
- f"[resources/create_multiple_resources]: Unknown resource type {entry['type'].lower()}"
- )
- continue
-
- resource = Resources.get(resource_name, resource_type, get_by_name=True)
- project.add_resource(resource)
-
- response.append(
- {
- "success_message": f"Added new resource: {resource_name}",
- "new_resource": resource.to_JSON(),
- "type": resource.get_type_value(),
- }
- )
- resource.launch_plugins(project.get_id())
-
- # Deal with the case of URL resources where we have the chance to add a Domain or IP
- if resource.get_type() == ResourceType.URL:
- ip_or_domain = urllib.parse.urlparse(resource_name).netloc
- resource_type = ResourceType.validate_ip_or_domain(ip_or_domain)
- if ip_or_domain:
- resource = Resources.get(
- ip_or_domain, resource_type, get_by_name=True
- )
- project.add_resource(resource)
- response.append(
- {
- "success_message": f"Added new resource: {ip_or_domain}",
- "new_resource": resource.to_JSON(),
- "type": resource.get_type_value(),
- }
- )
- resource.launch_plugins(project.get_id())
-
- # TODO: Deal with the case of domain -> IP
- # TODO: Deal with the case of emails -> domains -> IP
-
- return jsonify(response)
-
- except ResourceTypeException:
- return jsonify({"error_message": "Trying to add an unknown resource type"}), 400
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return jsonify({"error_message": "Server error :("}), 400
-
-
@resources_api.route("/api/create_resource", methods=["POST"])
@token_required
def create_resource(user):
@@ -85,28 +27,25 @@ def create_resource(user):
resource_type = ResourceType.get_type_from_string(resource_type)
- resource = Resources.get(resource_name, resource_type, get_by_name=True)
+ resource, created = ResourceManager.get_or_create(resource_name, resource_type)
project = User(user).get_active_project()
project.add_resource(resource)
response = []
- response.append(
- {
- "success_message": f"Added new resource: {resource_name}",
- "new_resource": resource.to_JSON(),
- "type": resource.get_type_value(),
- }
- )
+ response.append(resource.to_JSON())
- resource.launch_plugins(project.get_id())
+ if created:
+ resource.launch_plugins(project.get_id())
# Deal with the case of URL resources where we have the chance to add a Domain or IP
if resource.get_type() == ResourceType.URL:
ip_or_domain = urllib.parse.urlparse(resource_name).netloc
resource_type = ResourceType.validate_ip_or_domain(ip_or_domain)
if ip_or_domain:
- resource = Resources.get(ip_or_domain, resource_type, get_by_name=True)
+ resource, created = ResourceManager.get_or_create(
+ ip_or_domain, resource_type
+ )
project.add_resource(resource)
response.append(
{
@@ -115,7 +54,8 @@ def create_resource(user):
"type": resource.get_type_value(),
}
)
- resource.launch_plugins(project.get_id())
+ if created:
+ resource.launch_plugins(project.get_id())
# TODO: Deal with the case of domain -> IP
# TODO: Deal with the case of emails -> domains -> IP
@@ -134,26 +74,30 @@ def create_resource(user):
@resources_api.route("/api/get_resources", methods=["POST"])
@token_required
def get_resources(user):
- resource_type_as_string = request.json["type"]
-
try:
- resource_type = ResourceType(resource_type_as_string)
+ project_id = request.json["project_id"]
+ user_projects = [str(project) for project in User(user).get_projects()]
- project = User(user).get_active_project()
- resources = project.get_resources(resource_type)
+ # User unable to load the project
+ if not project_id in user_projects:
+ return (
+ jsonify(
+ {
+ "error_message": f"User is not allowed to load project {project_id}"
+ }
+ ),
+ 400,
+ )
+
+ project = Project(project_id)
+ resources = project.get_resources()
results = []
for resource in resources:
- results.append(Resources.get(resource, resource_type).to_JSON())
+ results.append(ResourceManager.get(resource).to_JSON())
return jsonify(results)
- except ValueError:
- raise ResourceTypeException()
-
- except ResourceTypeException:
- return jsonify({"error_message": "Received an unknown type of resource"}), 400
-
except Exception as e:
print(f"Error getting resource list {e}")
tb1 = traceback.TracebackException.from_exception(e)
@@ -164,6 +108,9 @@ def get_resources(user):
@resources_api.route("/api/unlink_resource", methods=["POST"])
@token_required
def unlink_resource(user):
+ """
+ Unlink (not remove) a resource from the active project.
+ """
try:
resource_id = bson.ObjectId(request.json["resource_id"])
@@ -181,15 +128,17 @@ def unlink_resource(user):
@token_required
def get_resource(user):
"""
- Return a resource doc
+ Return a resource json dump by its ID
"""
- resource_type_as_string = request.json["resource_type"]
+
resource_id = request.json["resource_id"]
try:
- resource_type = ResourceType(resource_type_as_string)
- resource = Resources.get(resource_id, resource_type)
- return jsonify(resource.to_JSON())
+ resource = ResourceManager.get(resource_id)
+ if resource:
+ return jsonify(resource.to_JSON())
+ else:
+ return jsonify({"error_message": "Resource not found"})
except ValueError:
raise ResourceTypeException()
diff --git a/server/routes/tags.py b/server/routes/tags.py
index c104da4..23bf6d7 100755
--- a/server/routes/tags.py
+++ b/server/routes/tags.py
@@ -9,7 +9,7 @@
from server.utils.password import token_required
-from server.entities.resource import Resources
+from server.entities.resource_manager import ResourceManager
from server.entities.resource_types import ResourceType, ResourceTypeException
from server.entities.user import User
@@ -83,7 +83,7 @@ def tag_to_resource(user):
tag = request.json["tag"]
resource_type = ResourceType(resource_type_as_string)
- resource = Resources.get(resource_id, resource_type)
+ resource = ResourceManager.get(resource_id)
resource.manage_tag(tag)
return jsonify({"sucess_message": "ok"})
diff --git a/tasks/subtasks/googlesearch.py b/tasks/googlesearch.py
old mode 100755
new mode 100644
similarity index 99%
rename from tasks/subtasks/googlesearch.py
rename to tasks/googlesearch.py
index 334d91e..418722e
--- a/tasks/subtasks/googlesearch.py
+++ b/tasks/googlesearch.py
@@ -3,11 +3,8 @@
import requests
from googleapiclient.discovery import build
-
-
from tasks.api_keys import KeyRing
-
API_KEY = KeyRing().get("googlesearch")
SORT = "date"
diff --git a/tasks/subtasks/__init__.py b/tasks/subtasks/__init__.py
deleted file mode 100755
index e69de29..0000000
diff --git a/tasks/subtasks/abuseipdb.py b/tasks/subtasks/abuseipdb.py
deleted file mode 100755
index 9998b95..0000000
--- a/tasks/subtasks/abuseipdb.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import traceback
-import json
-import requests
-
-from tasks.api_keys import KeyRing
-
-API_KEY = KeyRing().get("abuseipdb")
-URL = "https://api.abuseipdb.com/api/v2/check"
-
-
-def abuseipdb(ip):
- try:
- if not API_KEY:
- print("No API key...!")
- return None
-
- response = {}
- headers = {"Accept": "application/json", "Key": API_KEY}
- data = {"ipAddress": ip}
- abuse_response = requests.get(URL, headers=headers, json=data)
- if not abuse_response.status_code == 200:
- print("API key error!")
- return None
- else:
- response = json.loads(abuse_response.content)
- print(response)
-
- return response
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return None
diff --git a/tasks/subtasks/asn.py b/tasks/subtasks/asn.py
deleted file mode 100755
index a6bc59f..0000000
--- a/tasks/subtasks/asn.py
+++ /dev/null
@@ -1,61 +0,0 @@
-def asn(ip):
- try:
- results = {}
- target = IPWhois(ip)
- lookup = target.lookup_rdap(depth=1)
- if lookup:
- results["asn"] = {
- "asn": lookup["asn"],
- "asn_cidr": lookup["asn_cidr"],
- "asn_country_code": lookup["asn_country_code"],
- "asn_date": lookup["asn_date"],
- "asn_description": lookup["asn_description"],
- "asn_registry": lookup["asn_registry"],
- }
-
- results["network"] = {
- "cidr": lookup["network"]["cidr"],
- "country": lookup["network"]["country"],
- "handle": lookup["network"]["handle"],
- "name": lookup["network"]["name"],
- }
-
- return results
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
-
-@celery_app.task
-def basic_ip_task(plugin_name, project_id, resource_id, resource_type, ip):
-
- query_result = {}
-
- # PTR
- try:
- PTR_record = ptr(ip)
-
- if PTR_record:
- query_result["ptr"] = PTR_record
-
- ASN_NET_record = asn(ip)
-
- if "asn" in ASN_NET_record:
- query_result["asn"] = ASN_NET_record["asn"]
-
- if "network" in ASN_NET_record:
- query_result["network"] = ASN_NET_record["network"]
-
- # TODO: Probably, we can save some parameters here when object is instantiated
- resource_type = ResourceType(resource_type)
-
- resource = Resources.get(resource_id, resource_type)
- resource.set_plugin_results(
- plugin_name, project_id, resource_id, resource_type, query_result
- )
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
-
-
diff --git a/tasks/subtasks/binaryedge.py b/tasks/subtasks/binaryedge.py
deleted file mode 100755
index 502527d..0000000
--- a/tasks/subtasks/binaryedge.py
+++ /dev/null
@@ -1,26 +0,0 @@
-def binaryedge(ip):
- try:
-
- if not API_KEY:
- print("No API key...!")
- return {}
-
- response = {}
- headers = {"X-Key": API_KEY}
- response = requests.get(URL.format(**{"ip": ip}), headers=headers)
-
- if response.status_code == 404:
- print("associated records not found!")
- elif not response.status_code == 200:
- print("API key error!")
- else:
- response = json.loads(response.content)
- print(response)
- return response
-
- return {}
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return None
diff --git a/tasks/subtasks/botscout.py b/tasks/subtasks/botscout.py
deleted file mode 100644
index 2221309..0000000
--- a/tasks/subtasks/botscout.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Login with the following information:
-# Login Name: zigineki@getnada.com
-# Password: 6aiIRgAm
-# The BotScout Team
-# http://BotScout.com
-
-
-import traceback
-import json
-import urllib.request
-from bs4 import BeautifulSoup
-
-from tasks.api_keys import KeyRing
-
-API_KEY = KeyRing().get("botscout")
-
-
-def botscout_ip(ip):
- try:
- URL = f"http://botscout.com/test/?ip={ip}&key={API_KEY}&format=xml"
- response = urllib.request.urlopen(URL).read()
- return response
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return None
-
-
-# parsing results
-def botscout_ip_details(ip):
- try:
- URL = f"http://botscout.com/search.htm?sterm={ip}&stype=q"
- response = urllib.request.urlopen(URL).read()
-
- # parser HTML to extract last or To 10
- # soup = BeautifulSoup(response, 'html.parser')
- # html_data = soup.find('table', attrs={'class':'sortable'})
- # table_data = [[cell.text for cell in row("td")]]
- # for row in soup.body.find_all('table', attrs={'class' : 'sortable'})]
-
- # print(json.dumps(dict(table_data)))
-
- return response
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return None
diff --git a/tasks/subtasks/cybercrimetracker.py b/tasks/subtasks/cybercrimetracker.py
deleted file mode 100755
index 48e09b9..0000000
--- a/tasks/subtasks/cybercrimetracker.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import traceback
-import json
-import requests, base64
-from bs4 import BeautifulSoup
-
-#from tasks.api_keys import KeyRing
-
-#API_KEY = KeyRing().get("hybrid")
-
-URL = "http://cybercrime-tracker.net/index.php?search={ip}"
-
-def cybercrime_search(ip):
- try:
-
- response = {}
-
- headers = { "User-Agent": "Mozilla/5.0 (X11; Linux i686; rv:64.0) Gecko/20100101 Firefox/64.0" }
-
- response = requests.get(URL.format(**{"ip": ip}), headers=headers)
- if not response.status_code == 200:
- print("Response Service error!")
- return None
- else:
- soup = BeautifulSoup(response.content, 'html.parser')
- #response = json.loads(response.content)
-
-
- return soup
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return None
-
-#print ( cybercrime_search("5.79.66.145") )
diff --git a/tasks/subtasks/diario.py b/tasks/subtasks/diario.py
deleted file mode 100755
index e69de29..0000000
diff --git a/tasks/subtasks/dns.py b/tasks/subtasks/dns.py
deleted file mode 100755
index bca4858..0000000
--- a/tasks/subtasks/dns.py
+++ /dev/null
@@ -1,60 +0,0 @@
-import dns.resolver as resolver
-import traceback
-
-from urllib.parse import urlparse
-from server.entities.resource import Resources, ResourceType
-
-from tasks.tasks import celery_app
-
-# If you want to expand DNS query types this is the right place
-LOOKUP = ["NS", "A", "AAAA", "MX", "TXT", "SRV"]
-
-
-def dns(domain):
- try:
- results = {}
-
- for TYPE in LOOKUP:
- try:
- r = resolver.query(domain, TYPE)
- results[TYPE] = [str(i) for i in r]
-
- except:
- # Case when the query must be on canonical domain
- try:
- root_name = ".".join(domain.split(".")[-2:])
- r = resolver.query(root_name, TYPE)
- results[TYPE] = [str(i) for i in r]
-
- except:
- results[TYPE] = None
-
- print(results)
- return results
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
-
-@celery_app.task
-def dns_task(plugin_name, project_id, resource_id, resource_type, domain):
-
- query_result = {}
-
- # PTR
- try:
- dns_results = dns(domain)
- query_result = dns_results
-
- # TODO: Probably, we can save some parameters here when object is instantiated
- resource_type = ResourceType(resource_type)
-
- resource = Resources.get(resource_id, resource_type)
- resource.set_plugin_results(
- plugin_name, project_id, resource_id, resource_type, query_result
- )
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
-
diff --git a/tasks/subtasks/emailrep.py b/tasks/subtasks/emailrep.py
deleted file mode 100755
index 139597f..0000000
--- a/tasks/subtasks/emailrep.py
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/tasks/subtasks/geoip.py b/tasks/subtasks/geoip.py
deleted file mode 100755
index 9bd26d6..0000000
--- a/tasks/subtasks/geoip.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import traceback
-import json
-import urllib.request
-
-from tasks.api_keys import KeyRing
-
-API_KEY = KeyRing().get("ipstack")
-
-
-def geoip(ip):
- try:
- URL = f"http://api.ipstack.com/{ip}?access_key={API_KEY}&format=1"
- response = urllib.request.urlopen(URL).read()
- return json.loads(response)
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return None
diff --git a/tasks/subtasks/haveibeenpwned.py b/tasks/subtasks/haveibeenpwned.py
deleted file mode 100755
index e69de29..0000000
diff --git a/tasks/subtasks/hunterio.py b/tasks/subtasks/hunterio.py
deleted file mode 100755
index e69de29..0000000
diff --git a/tasks/subtasks/hybridanalysis.py b/tasks/subtasks/hybridanalysis.py
deleted file mode 100644
index 5c64103..0000000
--- a/tasks/subtasks/hybridanalysis.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# https://www.hybrid-analysis.com/
-# user: zigineki@getnada.com
-# pass: Developer1
-
-import traceback
-import json
-import requests, base64
-
-from tasks.api_keys import KeyRing
-
-API_KEY = KeyRing().get("hybrid")
-SECRET = KeyRing().get("hybrid_secret")
-
-URL = "https://www.hybrid-analysis.com/api/v2"
-PATH_HASH = "/search/hash"
-PATH_TERMS = "/search/terms"
-
-
-def hybrid_search_hash(hash):
- try:
- if not API_KEY:
- print("No API key...!")
- return None
-
- response = {}
-
- headers = {"User-Agent": "Falcon Sandbox", "api-key": API_KEY}
- post_data = {"hash": hash}
-
- response = requests.post(URL + PATH_HASH, post_data, headers=headers)
- if not response.status_code == 200:
- print("API key error!")
- return None
- else:
- response = json.loads(response.content)
-
- return response
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return None
-
-
-# https://www.hybrid-analysis.com/docs/api/v2#/Search/post_search_terms
-# param = host, domain, url
-def hybrid_search_terms(param):
- try:
- if not API_KEY:
- print("No API key...!")
- return None
-
- response = {}
-
- headers = {"User-Agent": "Falcon Sandbox", "api-key": API_KEY}
-
- post_data = {"domain": param}
-
- response = requests.post(URL + PATH_TERMS, post_data, headers=headers)
- if not response.status_code == 200:
- print("API key error!")
- return None
- else:
- response = json.loads(response.content)
-
- return response
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return None
diff --git a/tasks/subtasks/maltiverse.py b/tasks/subtasks/maltiverse.py
deleted file mode 100755
index e69de29..0000000
diff --git a/tasks/subtasks/onyphe.py b/tasks/subtasks/onyphe.py
deleted file mode 100755
index e69de29..0000000
diff --git a/tasks/subtasks/otx.py b/tasks/subtasks/otx.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tasks/subtasks/pastebin.py b/tasks/subtasks/pastebin.py
deleted file mode 100755
index e062c94..0000000
--- a/tasks/subtasks/pastebin.py
+++ /dev/null
@@ -1,67 +0,0 @@
-
-def get_key_from_paste_key(item):
- return item.split("/")[-1]
-
-
-def pastebin(results):
- try:
- if not API_KEY:
- raise Exception("No API_KEY for pastebin")
-
- links = []
- if "items" in results:
- links = [item["link"] for item in results["items"]]
- pastebins_refs = []
-
- for link in links:
- paste_key = get_key_from_paste_key(link)
- try:
- time.sleep(RATE_LIMIT)
-
- args = {}
- meta = requests.get(METADATA_URL + paste_key)
- if meta.status_code == 200:
- try:
- meta = meta.json()[0]
- except:
- print(f"This paste {paste_key} has been deleted")
- continue
- else:
- print(f"Error {meta.status_code} getting paste from pastebin.com")
- continue
-
- for field in [
- "size",
- "title",
- "user",
- "hits",
- "date",
- "syntax",
- "expire",
- ]:
- args[field] = meta[field]
-
- paste = Paste(paste_key, args)
-
- time.sleep(RATE_LIMIT)
-
- result = requests.get(RAWPASTE_URL + paste_key)
-
- if result.status_code == 200:
- paste.set_content(result.content)
-
- pastebins_refs.append(paste.save())
-
- except Exception as e:
- print(f"Failed to get pastebin: {link}")
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- continue
-
- if len(pastebins_refs) == 0 or len(links) == 0:
- return None
- return pastebins_refs
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
diff --git a/tasks/subtasks/phishtank.py b/tasks/subtasks/phishtank.py
deleted file mode 100755
index e69de29..0000000
diff --git a/tasks/subtasks/ptr.py b/tasks/subtasks/ptr.py
deleted file mode 100755
index 139597f..0000000
--- a/tasks/subtasks/ptr.py
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/tasks/subtasks/pulsedive.py b/tasks/subtasks/pulsedive.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tasks/subtasks/robtex.py b/tasks/subtasks/robtex.py
deleted file mode 100755
index b28b04f..0000000
--- a/tasks/subtasks/robtex.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/tasks/subtasks/sherlock.py b/tasks/subtasks/sherlock.py
deleted file mode 100755
index e69de29..0000000
diff --git a/tasks/subtasks/shodan.py b/tasks/subtasks/shodan.py
deleted file mode 100755
index 082ca43..0000000
--- a/tasks/subtasks/shodan.py
+++ /dev/null
@@ -1,53 +0,0 @@
-import traceback
-import json
-import requests
-
-
-from tasks.api_keys import KeyRing
-
-API_KEY = KeyRing().get("shodan")
-
-URL = "https://api.shodan.io/shodan/host/{ip}?key={API_KEY}"
-
-
-def shodan(ip):
- try:
- if not API_KEY:
- print("No API key...!")
- return None
-
- response = {}
- ipinfo = requests.get(URL.format(**{"ip": ip, "API_KEY": API_KEY}))
- if not ipinfo.status_code == 200:
- return None
- else:
- ipinfo = json.loads(ipinfo.content)
- with open("/tmp/shodan.json", "w") as f:
- f.write(json.dumps(ipinfo))
-
- response["hostnames"] = ipinfo["hostnames"] if "hostnames" in ipinfo else []
- response["os"] = ipinfo["os"] if "os" in ipinfo else None
- response["org"] = ipinfo["org"] if "org" in ipinfo else None
- response["isp"] = ipinfo["isp"] if "isp" in ipinfo else None
- response["services"] = []
-
- for data in ipinfo["data"]:
- service = {}
- service["port"] = data["port"] if "port" in data else None
- service["transport"] = data["transport"] if "transport" in data else None
- service["service"] = data["service"] if "service" in data else None
- service["data"] = data["data"] if "data" in data else None
- service["product"] = data["product"] if "product" in data else None
- service["banner"] = data["banner"] if "banner" in data else None
- service["devicetype"] = data["devicetype"] if "devicetype" in data else None
- service["timestamp"] = data["timestamp"] if "timestamp" in data else None
- service["hostnames"] = data["hostnames"] if "hostnames" in data else []
-
- response["services"].append(service)
-
- return response
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return None
diff --git a/tasks/subtasks/tacyt.py b/tasks/subtasks/tacyt.py
deleted file mode 100755
index 8b13789..0000000
--- a/tasks/subtasks/tacyt.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tasks/subtasks/threatcrowd.py b/tasks/subtasks/threatcrowd.py
deleted file mode 100755
index e69de29..0000000
diff --git a/tasks/subtasks/threatminer.py b/tasks/subtasks/threatminer.py
deleted file mode 100644
index 8b13789..0000000
--- a/tasks/subtasks/threatminer.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tasks/subtasks/urlscan.py b/tasks/subtasks/urlscan.py
deleted file mode 100755
index 8b13789..0000000
--- a/tasks/subtasks/urlscan.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tasks/subtasks/verifymail.py b/tasks/subtasks/verifymail.py
deleted file mode 100755
index e69de29..0000000
diff --git a/tasks/subtasks/virustotal.py b/tasks/subtasks/virustotal.py
deleted file mode 100755
index 5d9eb7d..0000000
--- a/tasks/subtasks/virustotal.py
+++ /dev/null
@@ -1,56 +0,0 @@
-import traceback
-import json
-import requests
-
-from tasks.api_keys import KeyRing
-from server.entities.resource_types import ResourceType
-
-API_KEY = KeyRing().get("virustotal")
-
-url_for_hashes = "https://www.virustotal.com/vtapi/v2/file/report"
-url_for_urls = "https://www.virustotal.com/vtapi/v2/url/report"
-url_for_domains = "https://www.virustotal.com/vtapi/v2/domain/report"
-url_for_ips = "https://www.virustotal.com/vtapi/v2/ip-address/report"
-
-
-def virustotal(resource, resource_type):
- try:
- if not API_KEY:
- print("No API key...!")
- return None
-
- response = None
- url = None
- params = {"apikey": API_KEY}
-
- if resource_type == ResourceType.DOMAIN:
- url = url_for_domains
- params["domain"] = resource
- elif resource_type == ResourceType.URL:
- url = url_for_urls
- params["resource"] = resource
- elif resource_type == ResourceType.IPv4:
- url = url_for_ips
- params["ip"] = resource
- elif resource_type == ResourceType.HASH:
- url = url_for_hashes
- params["resource"] = resource
- else:
- print("[VT] Unknown resource type before querying service")
- return None
-
- response = requests.get(url, params=params)
-
- if not response.status_code == 200:
- print(response)
- return None
- else:
- response = json.loads(response.content)
-
- print(response)
- return response
-
- except Exception as e:
- tb1 = traceback.TracebackException.from_exception(e)
- print("".join(tb1.format()))
- return None
diff --git a/tasks/tasks.py b/tasks/tasks.py
index 1ef2a98..4af9964 100755
--- a/tasks/tasks.py
+++ b/tasks/tasks.py
@@ -3,7 +3,7 @@
from celery import Celery
# TODO: Integrar en una sola funcion, se repeite en plugins.py
-EXCLUDE_SET = ["plugins.py", "__init__.py", "plugin_base.py", "TEMPLATE.py"]
+EXCLUDE_SET = ["__init__.py", "TEMPLATE.py"]
plugins = []
for root, dirs, files in os.walk("server/plugins"):