-
Notifications
You must be signed in to change notification settings - Fork 54
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 #10 from rapid7/unshorten
Unshorten: Open-source plugin
- Loading branch information
Showing
21 changed files
with
460 additions
and
0 deletions.
There are no files selected for viewing
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
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,20 @@ | ||
FROM komand/python-pypy3-plugin:2 | ||
LABEL organization=komand | ||
LABEL sdk=python | ||
LABEL type=plugin | ||
|
||
ENV SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt | ||
ENV SSL_CERT_DIR /etc/ssl/certs | ||
ENV REQUESTS_CA_BUNDLE /etc/ssl/certs/ca-certificates.crt | ||
|
||
ADD ./plugin.spec.yaml /plugin.spec.yaml | ||
ADD . /python/src | ||
|
||
WORKDIR /python/src | ||
# Add any package dependencies here | ||
|
||
# End package dependencies | ||
RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | ||
RUN python setup.py build && python setup.py install | ||
|
||
ENTRYPOINT ["/usr/local/bin/komand_unshorten"] |
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,53 @@ | ||
# Include other Makefiles for improved functionality | ||
INCLUDE_DIR = ../tools/Makefiles | ||
MAKEFILES := $(wildcard $(INCLUDE_DIR)/*.mk) | ||
# We can't guarantee customers will have the include files | ||
# - prefix to ignore Makefiles when not present | ||
# https://www.gnu.org/software/make/manual/html_node/Include.html | ||
-include $(MAKEFILES) | ||
|
||
ifneq ($(MAKEFILES),) | ||
$(info [$(YELLOW)*$(NORMAL)] Use ``make menu`` for available targets) | ||
$(info [$(YELLOW)*$(NORMAL)] Including available Makefiles: $(MAKEFILES)) | ||
$(info --) | ||
else | ||
$(warning Makefile includes directory not present: $(INCLUDE_DIR)) | ||
endif | ||
|
||
VERSION?=$(shell grep '^version: ' plugin.spec.yaml | sed 's/version: //') | ||
NAME?=$(shell grep '^name: ' plugin.spec.yaml | sed 's/name: //') | ||
VENDOR?=$(shell grep '^vendor: ' plugin.spec.yaml | sed 's/vendor: //') | ||
CWD?=$(shell basename $(PWD)) | ||
_NAME?=$(shell echo $(NAME) | awk '{ print toupper(substr($$0,1,1)) tolower(substr($$0,2)) }') | ||
PKG=$(VENDOR)-$(NAME)-$(VERSION).tar.gz | ||
|
||
# Set default target explicitly. Make's default behavior is the first target in the Makefile. | ||
# We don't want that behavior due to includes which are read first | ||
.DEFAULT_GOAL := default # Make >= v3.80 (make -version) | ||
|
||
|
||
default: image tarball | ||
|
||
tarball: | ||
$(info [$(YELLOW)*$(NORMAL)] Creating plugin tarball) | ||
rm -rf build | ||
rm -rf $(PKG) | ||
tar -cvzf $(PKG) --exclude=$(PKG) --exclude=tests --exclude=run.sh * | ||
|
||
image: | ||
$(info [$(YELLOW)*$(NORMAL)] Building plugin image) | ||
docker build --pull -t $(VENDOR)/$(NAME):$(VERSION) . | ||
docker tag $(VENDOR)/$(NAME):$(VERSION) $(VENDOR)/$(NAME):latest | ||
|
||
regenerate: | ||
$(info [$(YELLOW)*$(NORMAL)] Regenerating schema from plugin.spec.yaml) | ||
icon-plugin generate python --regenerate | ||
|
||
export: image | ||
$(info [$(YELLOW)*$(NORMAL)] Exporting docker image) | ||
@printf "\n ---> Exporting Docker image to ./$(VENDOR)_$(NAME)_$(VERSION).tar\n" | ||
@docker save $(VENDOR)/$(NAME):$(VERSION) | gzip > $(VENDOR)_$(NAME)_$(VERSION).tar | ||
|
||
# Make will not run a target if a file of the same name exists unless setting phony targets | ||
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html | ||
.PHONY: default tarball image regenerate |
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,32 @@ | ||
#!/usr/bin/env python | ||
# GENERATED BY KOMAND SDK - DO NOT EDIT | ||
import komand | ||
from komand_unshorten import connection, actions, triggers | ||
|
||
|
||
Name = 'Unshorten.me' | ||
Vendor = 'rapid7' | ||
Version = '1.0.0' | ||
Description = 'Unshorten.me provides an easy method to unshorten a wide range of shortened URLs' | ||
|
||
|
||
class ICONUnshorten(komand.Plugin): | ||
def __init__(self): | ||
super(self.__class__, self).__init__( | ||
name=Name, | ||
vendor=Vendor, | ||
version=Version, | ||
description=Description, | ||
connection=connection.Connection() | ||
) | ||
self.add_action(actions.Unshorten()) | ||
|
||
|
||
def main(): | ||
"""Run plugin""" | ||
cli = komand.CLI(ICONUnshorten()) | ||
cli.run() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
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,87 @@ | ||
|
||
# Unshorten.me | ||
|
||
## About | ||
|
||
[Unshorten.me](https://unshorten.me/) is a free service which unshorten's a wide range of shortened URLs. | ||
|
||
This plugin utilizes the [Unshorten.me API](https://unshorten.me/api). | ||
|
||
## Actions | ||
|
||
### Unshorten | ||
|
||
This action is used to unshorten a URL. | ||
|
||
#### Input | ||
|
||
|Name|Type|Default|Required|Description|Enum| | ||
|----|----|-------|--------|-----------|----| | ||
|url|string|None|True|Short URL|None| | ||
|
||
#### Output | ||
|
||
|Name|Type|Required|Description| | ||
|----|----|--------|-----------| | ||
|resolved_url|string|True|Long URL| | ||
|success|boolean|True|Success| | ||
|usage_count|integer|True|Usage count| | ||
|requested_url|string|True|Short URL| | ||
|error|string|False|Error message| | ||
|
||
Example output: | ||
|
||
``` | ||
{ | ||
"requested_url": "https://bit.ly/1dNVPAW", | ||
"resolved_url": "http://www.google.com/", | ||
"success": true, | ||
"usage_count": 5 | ||
} | ||
``` | ||
|
||
An error can occur from the Unshorten API e.g. submitting a malformed URL. Any error messages from the API are contained in a key called `error`. | ||
In addition, `success` will be set to `false`. | ||
|
||
Example output: | ||
|
||
``` | ||
{ | ||
"requested_url": "https://adfasdfadsfadsfasdfadsf.netadfa", | ||
"resolved_url": "", | ||
"error": "Connection Error", | ||
"success": false, | ||
"usage_count": 0 | ||
} | ||
``` | ||
|
||
## Triggers | ||
|
||
This plugin does not contain any triggers. | ||
|
||
## Connection | ||
|
||
This plugin does not contain a connection. | ||
|
||
## Troubleshooting | ||
|
||
Note that the API is limited to 10 requests per hour per IP address. | ||
|
||
## Versions | ||
|
||
* 1.0.0 - Initial plugin | ||
|
||
## Workflows | ||
|
||
Examples: | ||
|
||
* Phishing campaigns | ||
|
||
## References | ||
|
||
* [Unshorten.me](https://unshorten.me/) | ||
* [API](https://unshorten.me/) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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 @@ | ||
# GENERATED BY KOMAND SDK - DO NOT EDIT |
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 @@ | ||
# GENERATED BY KOMAND SDK - DO NOT EDIT | ||
from .unshorten.action import Unshorten |
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 @@ | ||
# GENERATED BY KOMAND SDK - DO NOT EDIT | ||
from .action import Unshorten |
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,53 @@ | ||
import komand | ||
from .schema import UnshortenInput, UnshortenOutput | ||
# Custom imports below | ||
import requests | ||
|
||
|
||
class Unshorten(komand.Action): | ||
|
||
def __init__(self): | ||
super(self.__class__, self).__init__( | ||
name='unshorten', | ||
description='Unshorten a shortened URL', | ||
input=UnshortenInput(), | ||
output=UnshortenOutput()) | ||
|
||
def run(self, params={}): | ||
short_url = params.get('url') | ||
try: | ||
r = requests.get('https://unshorten.me/json/' + short_url) | ||
r.raise_for_status() | ||
out = r.json() | ||
except Exception as e: | ||
self.logger.error(e) | ||
raise | ||
|
||
try: | ||
if out['error']: | ||
self.logger.error(out.get('error')) | ||
except KeyError: | ||
# All good, no error key is present | ||
self.logger.info('No errors') | ||
|
||
return out | ||
|
||
def test(self): | ||
url = 'https://bit.ly/komand_rocks' | ||
try: | ||
r = requests.get('https://unshorten.me/json/' + url) | ||
r.raise_for_status() | ||
out = r.json() | ||
except Exception as e: | ||
self.logger.error(e) | ||
raise | ||
|
||
# All good | ||
try: | ||
if out['error']: | ||
self.logger.error(out.get('error')) | ||
except KeyError: | ||
# All good, no error key is present | ||
self.logger.info('No errors') | ||
|
||
return out |
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,88 @@ | ||
# GENERATED BY KOMAND SDK - DO NOT EDIT | ||
import komand | ||
import json | ||
|
||
|
||
class Input: | ||
URL = "url" | ||
|
||
|
||
class Output: | ||
ERROR = "error" | ||
REQUESTED_URL = "requested_url" | ||
RESOLVED_URL = "resolved_url" | ||
SUCCESS = "success" | ||
USAGE_COUNT = "usage_count" | ||
|
||
|
||
class UnshortenInput(komand.Input): | ||
schema = json.loads(""" | ||
{ | ||
"type": "object", | ||
"title": "Variables", | ||
"properties": { | ||
"url": { | ||
"type": "string", | ||
"title": "URL", | ||
"description": "Short URL", | ||
"order": 1 | ||
} | ||
}, | ||
"required": [ | ||
"url" | ||
] | ||
} | ||
""") | ||
|
||
def __init__(self): | ||
super(self.__class__, self).__init__(self.schema) | ||
|
||
|
||
class UnshortenOutput(komand.Output): | ||
schema = json.loads(""" | ||
{ | ||
"type": "object", | ||
"title": "Variables", | ||
"properties": { | ||
"error": { | ||
"type": "string", | ||
"title": "Error", | ||
"description": "Error message", | ||
"order": 5 | ||
}, | ||
"requested_url": { | ||
"type": "string", | ||
"title": "Requested URL", | ||
"description": "Short URL", | ||
"order": 1 | ||
}, | ||
"resolved_url": { | ||
"type": "string", | ||
"title": "Resolved URL", | ||
"description": "Long URL", | ||
"order": 2 | ||
}, | ||
"success": { | ||
"type": "boolean", | ||
"title": "Success", | ||
"description": "Success", | ||
"order": 3 | ||
}, | ||
"usage_count": { | ||
"type": "integer", | ||
"title": "Usage Count", | ||
"description": "Usage count", | ||
"order": 4 | ||
} | ||
}, | ||
"required": [ | ||
"usage_count", | ||
"requested_url", | ||
"resolved_url", | ||
"success" | ||
] | ||
} | ||
""") | ||
|
||
def __init__(self): | ||
super(self.__class__, self).__init__(self.schema) |
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 @@ | ||
# GENERATED BY KOMAND SDK - DO NOT EDIT | ||
from .connection import Connection |
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,12 @@ | ||
import komand | ||
from .schema import ConnectionSchema | ||
# Custom imports below | ||
|
||
|
||
class Connection(komand.Connection): | ||
|
||
def __init__(self): | ||
super(self.__class__, self).__init__(input=ConnectionSchema()) | ||
|
||
def connect(self, params): | ||
pass |
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,15 @@ | ||
# GENERATED BY KOMAND SDK - DO NOT EDIT | ||
import komand | ||
import json | ||
|
||
|
||
class Input: | ||
pass | ||
|
||
class ConnectionSchema(komand.Input): | ||
schema = json.loads(""" | ||
{} | ||
""") | ||
|
||
def __init__(self): | ||
super(self.__class__, self).__init__(self.schema) |
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 @@ | ||
# GENERATED BY KOMAND SDK - DO NOT EDIT |
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 @@ | ||
# GENERATED BY KOMAND SDK - DO NOT EDIT |
Oops, something went wrong.