概要
WAFやFirewallで日々検知されるログを確認している際に、「このIPアドレスはどこのIPだろう?怪しいIP?」と思うことが多々あると思います。
危険なIPアドレスかどうかを調べる際によくAbuseIPDBを使用しているのですが、Web上だと1つずつしか確認ができないため、複数のIPアドレスをまとめてチェックしたい時には手間がかかります。
そのため、APIを使用してまとめてチェックするプログラムをPythonで作成しました。
前提条件
- AbuseIPDBのアカウントを持っていること
- AbuseIPDBのAPIキーを取得していること
取得方法は公式ページを参照してください - 検知したIPアドレス一覧を「ipaddress-list.csv」に保存すること
制限事項
- 無料版だと1日あたり1000IP分までしか検索ができません。
プログラム
abuseIp.py
import requests
import json
import csv
import ipaddress
api_key = 'API Key'
max_age_in_days = '90'
def main():
ip_address_list_file = 'ipaddress-list.csv'
check_ip_list = read_ip_address_list_file(ip_address_list_file)
# IPの個数分ドメイン情報を取得する
# get domain info of ip addresses
for ip_address in check_ip_list:
if is_valid_ip(ip_address[0]):
domain_info = get_domain_info(ip_address[0])
domain, isp, score, countryCode, is_public = domain_info
if is_public == True:
print(f"{ip_address[0]},{domain},{isp},{countryCode},{score}")
else:
print(f"{ip_address[0]},Private IP,Private IP,0")
else:
print(f"Invalid IP address: {ip_address[0]}")
def get_domain_info(ip_address):
# This function receives a ip address and check its domain info by using abuseip api.
# Then return a list of its domain name, isp info, countryCode, abuse score, and IPAddress info(Public or Private)
# Defining the api-endpoint
url = 'https://api.abuseipdb.com/api/v2/check'
# Curlを投げてドメイン情報を取得
# get domain info with curl command
querystring = {
'ipAddress': ip_address,
'maxAgeInDays': max_age_in_days
}
headers = {
'Accept': 'application/json',
'Key': api_key
}
response = requests.request(
method='GET', url=url, headers=headers, params=querystring)
try:
# JSONデータを辞書型に変換
data_dict = response.json()
# 必要なデータを取得
domain = data_dict['data']['domain']
isp = data_dict['data']['isp']
countryCode = data_dict['data']['countryCode']
score = data_dict['data']['abuseConfidenceScore']
is_public = data_dict['data']['isPublic']
return domain, isp, score, countryCode, is_public
except KeyError as e:
print(f"KeyError: {e} in response: {response.text}")
return None, None, None, None, None
def read_ip_address_list_file(ip_address_list_file):
# This function reads csv file and return a list of ip addresses
# 検索したいIPリストを記載したCSVファイルを読み込む
# read csv file which has ip addresses you want to search domain info
with open(ip_address_list_file, encoding='utf-8-sig') as f:
reader = csv.reader(f)
search_ipaddress = []
for row in reader:
# 確認したいIPアドレスをリスト化
# create a list of ip addresses
# [['IPアドレス','検知数']・・・]の情報が入る
# list will be [['IP Address', 'count of ip address']・・・]
search_ipaddress.append(row)
return search_ipaddress
def is_valid_ip(ip_addr):
try:
ipaddress.ip_address(ip_addr)
return True
except ValueError:
return False
if __name__ == "__main__":
main()
「ipaddress-list.csv」は以下のように準備してください。
ipaddress-list.csv
192.168.0.1
192.168.0.2
192.168.0.3
・・・
結果は以下のようなイメージになります。
出力イメージ.txt
['XX.XX.XX.XX'],paloaltonetworks.com,Palo Alto Networks Inc,US,100
2024/1/31追記
IPアドレスのバリデーションや、エラーハンドリングを追加しました。