Skip to content

Commit

Permalink
Add IP2Location.io plugin. (#200)
Browse files Browse the repository at this point in the history
  • Loading branch information
ip2location authored Dec 12, 2023
1 parent 8ae7f18 commit f66d9ad
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ After configuration the following plugins are available within the `harpoon` com
intel Gather information on a domain
ip Gather information on an IP address
ipinfo Request ipinfo.io information
ip2locationio Request IP2Location.io information
koodous Request Koodous API
malshare Requests MalShare database
misp Get information from a MISP server through the API
Expand Down Expand Up @@ -125,6 +126,7 @@ You can get information on each command with `harpoon help COMMAND`
* [Hybrid Analysis](https://www.hybrid-analysis.com/apikeys/info)
* [IBM Xforce Exchange](https://exchange.xforce.ibmcloud.com/settings/api)
* [ipinfo.io](https://ipinfo.io/)
* [IP2Location.io](https://www.ip2location.io/)
* [Koodous](https://koodous.com/)
* [MalShare](https://malshare.com/register.php)
* [NumVerify](https://numverify.com/)
Expand Down
102 changes: 102 additions & 0 deletions harpoon/commands/ip2locationio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#! /usr/bin/env python
import json
import os
import sys
import time

from harpoon.commands.base import Command
from harpoon.lib.ip2locationio import IP2Locationio, IP2LocationioError
from harpoon.lib.utils import unbracket


class CommandIPInfo(Command):
"""
# IP2Location.io plugin
**Query IP2Location.io API**
* Get info on an IP : `harpoon ip2locationio ip IP`
* Get infos on a list of IPs in a file : `harpoon ip2locationio file FILE`
"""
name = "ip2locationio"
description = "Request IP2Location.io information"
config = {'IP2Locationio': ['token']}

def add_arguments(self, parser):
subparsers = parser.add_subparsers(help='Subcommand')
parser_a = subparsers.add_parser('ip', help='Information on an IP')
parser_a.add_argument('IP', help='IP address')
parser_a.set_defaults(subcommand='ip')
parser_b = subparsers.add_parser('file', help='Information on a list of IPs')
parser_b.add_argument('FILE', help='Filename')
parser_b.add_argument('--delay', '-d', type=int, default=1, help='Delay between two queries in seconds')
parser_b.set_defaults(subcommand='file')
self.parser = parser

def run(self, args, plugins):
ip2locationio = IP2Locationio(token=self._config_data['IP2Locationio']['token'])
if 'subcommand' in args:
if args.subcommand == 'ip':
try:
infos = ip2locationio.get_infos(unbracket(args.IP))
except IP2LocationioError:
print("Invalid request")
else:
print(json.dumps(infos, sort_keys=True, indent=4, separators=(',', ': ')))
elif args.subcommand == 'file':
if os.path.isfile(args.FILE):
with open(args.FILE) as f:
data = f.read().split("\n")
print(
"IP;Domain;City;Region;Country;Location;" +
"ISP;ASN;AS Name;" +
"Is Proxy;Proxy Type;Threat Type;Last Seen in")
for d in data:
if d.strip() == '':
continue
ip = unbracket(d.strip())
try:
infos = ip2locationio.get_infos(ip)
except IP2LocationioError:
print("%s;;;;;;;;;;;;;" % ip)
else:
loc = str(infos['latitude']) + ',' + str(infos['longitude'])
if "proxy" in infos:
print("%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s" % (
ip,
infos['domain'] if 'domain' in infos else '',
infos['city_name'] if 'city' in infos else '',
infos['region_name'] if 'region' in infos else '',
infos['country_name'] if 'country' in infos else '',
loc,
infos['isp'] if 'isp' in infos else '',
infos['asn'] if 'asn' in infos else '',
infos['as'] if 'as' in infos else '',
infos['is_proxy'] if 'is_proxy' in infos else '',
infos['proxy']['proxy_type'] if 'proxy_type' in infos['proxy'] else '',
infos['proxy']['threat'] if 'threat' in infos['proxy'] else '',
(str(infos['proxy']['last_seen']) + (' days' if infos['proxy']['last_seen'] > 1 else ' day')) if 'last_seen' in infos['proxy'] else ''
)
)
else:
print("%s;%s;%s;%s;%s;%s;%s;%s;%s;;;;;" % (
ip,
infos['domain'] if 'domain' in infos else '',
infos['city_name'],
infos['region_name'],
infos['country_name'],
loc,
infos['isp'] if 'isp' in infos else '',
infos['asn'] if 'asn' in infos else '',
infos['as'] if 'as' in infos else '',
)
)
time.sleep(args.delay)

else:
print("This file does not exist")
sys.exit(1)
else:
self.parser.print_help()
else:
self.parser.print_help()
3 changes: 3 additions & 0 deletions harpoon/data/example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ key:
[IPInfo]
token:

[IP2Locationio]
token:

[OpenCage]
key:

Expand Down
17 changes: 17 additions & 0 deletions harpoon/lib/ip2locationio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import requests

class IP2LocationioError(Exception):
def __init__(self, message):
self.message = message
Exception.__init__(self, message)

class IP2Locationio(object):
def __init__(self, token):
self.token = token
self.base_url = 'https://api.ip2location.io/'

def get_infos(self, ip):
r = requests.get(self.base_url , params={'key': self.token, 'ip': ip})
if r.status_code != 200:
raise IP2LocationioError('Invalid HTTP code %i' % r.status_code)
return r.json()

0 comments on commit f66d9ad

Please sign in to comment.