From 10ac0f946560e03875fe6c09865a4cb94e762057 Mon Sep 17 00:00:00 2001 From: jose nazario Date: Sun, 29 Mar 2020 19:21:12 -0400 Subject: [PATCH 1/5] add a censys command --- README.md | 1 + plugins/censys/censys.plug | 9 ++++++++ plugins/censys/censys.py | 42 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 plugins/censys/censys.plug create mode 100644 plugins/censys/censys.py diff --git a/README.md b/README.md index 5526afb..7e07ca7 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ We are excited to share with the world a chat bot that we affectionately call Cy !whois \ - WHOIS Query (ex: cylance[.]com) !nslookup \ - DNS forward/reverse Query (ex: www[.]cylance[.]com) !geoip \ - Perform GeoIP lookup of host (ex: www[.]cylance[.]com) + !censys \ - Return Censys information on host (ex: 1.2.3.4) !unshorten \ - Unshortens URLs (ex: goo[.]gl/IGL1lE) !screenshot - Takes a screenshot of a website and returns the .png - Accepts defanged [()] URLs !linkextractor \ - Extracts links from a site and safely displays them (ex: hxxps://www[.]google[.]com) diff --git a/plugins/censys/censys.plug b/plugins/censys/censys.plug new file mode 100644 index 0000000..9d17951 --- /dev/null +++ b/plugins/censys/censys.plug @@ -0,0 +1,9 @@ +[Core] +Name = censys +Module = censts + +[Documentation] +Description = This plugin queries Censys.io for information about an IP address. + +[Python] +Version = 2+ diff --git a/plugins/censys/censys.py b/plugins/censys/censys.py new file mode 100644 index 0000000..57b3591 --- /dev/null +++ b/plugins/censys/censys.py @@ -0,0 +1,42 @@ +# !censys is used for Querying the censys.io API + +import os, requests, json, re +from errbot import BotPlugin, botcmd, arg_botcmd + +base_url = "https://www.censys.io/api/v1" +api_id = "changeme" +api_secret = "changeme" + + +class censys(BotPlugin): + @arg_botcmd("query", type=str) # flags a command + def censys(self, msg, query=None): + query = re.sub("[\[()\]]", "", query) + uri = "view/ipv4/{}".format(query) + response = requests.get(base_url + uri, auth=api_creds) + json_resp = response.json() + + answer = "Status: " + json_resp["status"] + "\r\n" + + if json_resp.get("error", False): + answer += json_resp["error"] + "\r\n" + else: + answer += "IP: {0}\r\n".format(", ".join(json_resp["ip"])) + answer += "Tags: {0}\r\n".format(", ".join(json_resp["tags"])) + answer += "Protocols: {0}\r\n".format(", ".join(json_resp["protocols"])) + if (80) in json_resp["ports"]: + try: + answer += "Web page title (80/http): {0}\r\n".format( + json_resp["80"]["http"]["get"]["title"] + ) + except KeyError: + pass + if (443) in json_resp["ports"]: + try: + answer += "Web page title (443/https): {0}\r\n".format( + json_resp["443"]["https"]["get"]["title"] + ) + except KeyError: + pass + answer += "Updated at: {0}\r\n".format(", ".join(json_resp["updated_at"])) + return answer From 06fecda9f4bf0e6c83d39c8f6d5a36ef53a1bd75 Mon Sep 17 00:00:00 2001 From: jose nazario Date: Mon, 30 Mar 2020 16:00:27 -0400 Subject: [PATCH 2/5] api_creds used but never declared - fix --- plugins/censys/censys.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/censys/censys.py b/plugins/censys/censys.py index 57b3591..11318eb 100644 --- a/plugins/censys/censys.py +++ b/plugins/censys/censys.py @@ -13,6 +13,7 @@ class censys(BotPlugin): def censys(self, msg, query=None): query = re.sub("[\[()\]]", "", query) uri = "view/ipv4/{}".format(query) + api_creds = (api_id, api_secret) response = requests.get(base_url + uri, auth=api_creds) json_resp = response.json() From 1f7af6043c5b0ff6fb1f49795d0a03e6c5600081 Mon Sep 17 00:00:00 2001 From: jose nazario Date: Mon, 30 Mar 2020 16:08:41 -0400 Subject: [PATCH 3/5] status not always there --- plugins/censys/censys.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/censys/censys.py b/plugins/censys/censys.py index 11318eb..c7ea904 100644 --- a/plugins/censys/censys.py +++ b/plugins/censys/censys.py @@ -17,12 +17,10 @@ def censys(self, msg, query=None): response = requests.get(base_url + uri, auth=api_creds) json_resp = response.json() - answer = "Status: " + json_resp["status"] + "\r\n" - if json_resp.get("error", False): - answer += json_resp["error"] + "\r\n" + answer = 'Error: ' + json_resp["error"] + "\r\n" else: - answer += "IP: {0}\r\n".format(", ".join(json_resp["ip"])) + answer = "IP: {0}\r\n".format(", ".join(json_resp["ip"])) answer += "Tags: {0}\r\n".format(", ".join(json_resp["tags"])) answer += "Protocols: {0}\r\n".format(", ".join(json_resp["protocols"])) if (80) in json_resp["ports"]: From bc7ed58d12d0ebd24d8bd016c066e18e52462b3a Mon Sep 17 00:00:00 2001 From: paralax Date: Wed, 25 Mar 2020 22:33:28 -0400 Subject: [PATCH 4/5] updated_at not an array --- plugins/censys/censys.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/censys/censys.py b/plugins/censys/censys.py index c7ea904..639543a 100644 --- a/plugins/censys/censys.py +++ b/plugins/censys/censys.py @@ -37,5 +37,5 @@ def censys(self, msg, query=None): ) except KeyError: pass - answer += "Updated at: {0}\r\n".format(", ".join(json_resp["updated_at"])) + answer += "Updated at: {0}\r\n".format(json_resp["updated_at"]) return answer From ab06c758c2a59dd803ea0f4438ca8b3f8acb33ff Mon Sep 17 00:00:00 2001 From: paralax Date: Wed, 25 Mar 2020 22:38:39 -0400 Subject: [PATCH 5/5] why did i think ip was an array??! --- plugins/censys/censys.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/censys/censys.py b/plugins/censys/censys.py index 639543a..c3c089b 100644 --- a/plugins/censys/censys.py +++ b/plugins/censys/censys.py @@ -20,7 +20,7 @@ def censys(self, msg, query=None): if json_resp.get("error", False): answer = 'Error: ' + json_resp["error"] + "\r\n" else: - answer = "IP: {0}\r\n".format(", ".join(json_resp["ip"])) + answer = "IP: {0}\r\n".format(ip) answer += "Tags: {0}\r\n".format(", ".join(json_resp["tags"])) answer += "Protocols: {0}\r\n".format(", ".join(json_resp["protocols"])) if (80) in json_resp["ports"]: