Skip to content

Instantly share code, notes, and snippets.

@selimslab
Created November 30, 2023 13:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save selimslab/3cce7f22fe886f1d83fcaf0aab6e265d to your computer and use it in GitHub Desktop.
Save selimslab/3cce7f22fe886f1d83fcaf0aab6e265d to your computer and use it in GitHub Desktop.
import csv
import yaml
import ipaddress
from intervaltree import IntervalTree, Interval
def read_csv_lines(file):
with open(file, 'r') as file:
csv_reader = csv.reader(file)
return [row[0] for row in csv_reader]
def read_yaml_lines(file):
with open(file, 'r') as file:
yaml_content = file.read()
data = yaml.safe_load(yaml_content)
return [line for line in data if not line.startswith("#")]
def create_interval_tree(blocked_networks):
# Create an IntervalTree for blocked IPs
blocked_intervals = IntervalTree()
for blocked_ip in blocked_networks:
# Convert IPNetwork objects to integers for querying IntervalTree
# network_address is the lowest and the broadcast_address is highest in the range
ip_start = int(blocked_ip.network_address)
ip_end = int(blocked_ip.broadcast_address)
if ip_start <= ip_end:
# +1 to have an inclusive range
blocked_intervals.add(Interval(ip_start, ip_end+1, blocked_ip))
'''
blocked_intervals go like this:
Interval(878679552, 878679808, IPv4Network('52.95.150.0/24'))
Interval(56973056, 56973120, IPv4Network('3.101.87.0/26'))
Interval(42541956123655038472487924334797520896, 42541956123655038490934668408507072512, IPv6Network('2001:4860:4801:61::/64'))
'''
return blocked_intervals
def check_overlapping_intervals(blocked_networks, apple_networks):
blocked_intervals = create_interval_tree(blocked_networks)
# search in the tree of blocked IP intervals
blocked_apple_ips = set()
for apple_ip in apple_networks:
# Convert IPNetwork objects to integers for querying IntervalTree
ip_start = int(apple_ip.network_address)
ip_end = int(apple_ip.broadcast_address)
# Query the IntervalTree to check for overlaps with apple_ip
overlaps = blocked_intervals.overlap(ip_start, ip_end+1)
if any(apple_ip in interval for interval in overlaps):
print(f"IP {apple_ip} is blocked.")
blocked_apple_ips.add(apple_ip)
print(f"{len(blocked_apple_ips)} blocked Apple IPs:", blocked_apple_ips)
def search_blocked_apple_ips():
apple_ip_ranges = read_csv_lines('apple.csv')
blocked_ip_ranges = read_yaml_lines('blocked.yaml')
# str to IP network objects
apple_networks = [ipaddress.ip_network(ip_range, strict=False) for ip_range in apple_ip_ranges]
blocked_networks = [ipaddress.ip_network(ip_range, strict=False) for ip_range in blocked_ip_ranges]
check_overlapping_intervals(blocked_networks, apple_networks)
if __name__ == '__main__':
'''
Find if any of the Apple IPs are in your blocklist
Iterative search is too slow so this script uses an interval tree
Prerequisites:
1. pip install intervaltree
2. curl https://mask-api.icloud.com/egress-ip-ranges.csv -o apple.csv
3. blocked.yaml is your blocklist
Assumes apple.csv and blocked.yaml are in the same folder as this script
'''
search_blocked_apple_ips()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment