commit 17ec53f7640665d5943394fd3408d73d5655a5a0 Author: eetnaviation Date: Fri Jun 27 12:38:19 2025 +0300 Initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0248c73 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +*.txt \ No newline at end of file diff --git a/GeoLite2-City.mmdb b/GeoLite2-City.mmdb new file mode 100644 index 0000000..3a35c4b Binary files /dev/null and b/GeoLite2-City.mmdb differ diff --git a/GeoLite2-Country.mmdb b/GeoLite2-Country.mmdb new file mode 100644 index 0000000..0e4cc49 Binary files /dev/null and b/GeoLite2-Country.mmdb differ diff --git a/analyze.py b/analyze.py new file mode 100644 index 0000000..6aba5db --- /dev/null +++ b/analyze.py @@ -0,0 +1,91 @@ +import re +from collections import defaultdict +import matplotlib.pyplot as plt + +def parse_file(file_path): + with open(file_path, 'r') as file: + data = file.read() + + pattern = re.compile(r'Source address: /(\d+\.\d+\.\d+\.\d+).*?Destination address: /(\d+\.\d+\.\d+\.\d+).*?Source port: (\d+).*?Destination port: (\d+)', re.DOTALL) + matches = pattern.findall(data) + + return matches + +def count_occurrences(matches): + counts = defaultdict(int) + src_ip_counts = defaultdict(int) + dst_ip_counts = defaultdict(int) + src_port_counts = defaultdict(int) + dst_port_counts = defaultdict(int) + + for src_ip, dst_ip, src_port, dst_port in matches: + counts[(src_ip, dst_ip, dst_port)] += 1 + src_ip_counts[src_ip] += 1 + dst_ip_counts[dst_ip] += 1 + src_port_counts[src_port] += 1 + dst_port_counts[dst_port] += 1 + + return counts, src_ip_counts, dst_ip_counts, src_port_counts, dst_port_counts + +def plot_data(counts): + src_ips = [] + dst_ips = [] + ports = [] + occurrences = [] + + for (src_ip, dst_ip, port), count in counts.items(): + src_ips.append(src_ip) + dst_ips.append(dst_ip) + ports.append(port) + occurrences.append(count) + + fig, ax = plt.subplots(figsize=(10, 8)) + + bar_width = 0.35 + index = range(len(src_ips)) + + bars = ax.bar(index, occurrences, bar_width, label='Occurrences') + + ax.set_xlabel('IP and Port Combinations') + ax.set_ylabel('Occurrences') + ax.set_title('Occurrences of Source IPs, Destination IPs, and Ports') + ax.set_xticks(index) + ax.set_xticklabels([f'{src_ips[i]} -> {dst_ips[i]}:{ports[i]}' for i in range(len(src_ips))], rotation=90) + ax.legend() + + plt.tight_layout() + plt.show() + +def plot_single_category(data, category_name): + items = list(data.keys()) + occurrences = list(data.values()) + + fig, ax = plt.subplots(figsize=(10, 8)) + + bar_width = 0.35 + index = range(len(items)) + + bars = ax.bar(index, occurrences, bar_width, label='Occurrences') + + ax.set_xlabel(category_name) + ax.set_ylabel('Occurrences') + ax.set_title(f'Occurrences of {category_name}') + ax.set_xticks(index) + ax.set_xticklabels(items, rotation=90) + ax.legend() + + plt.tight_layout() + plt.show() + +# File path to your text file +file_path = 'sample.txt' + +matches = parse_file(file_path) +counts, src_ip_counts, dst_ip_counts, src_port_counts, dst_port_counts = count_occurrences(matches) + +# Plot each category +plot_data(counts) # Current graph with everything +plot_single_category(dst_ip_counts, 'Destination IPs') +plot_single_category(src_ip_counts, 'Source IPs') +plot_single_category(dst_port_counts, 'Destination Ports') +plot_single_category(src_port_counts, 'Source Ports') \ No newline at end of file diff --git a/heatmap-back.py b/heatmap-back.py new file mode 100644 index 0000000..9d7571b --- /dev/null +++ b/heatmap-back.py @@ -0,0 +1,68 @@ +from mpl_toolkits.basemap import Basemap +import matplotlib.pyplot as plt +from matplotlib.patches import Polygon +import matplotlib as mpl +from collections import defaultdict +import geoip2.database + +# Function to read IPs from file +def read_ips_from_file(file_path): + with open(file_path, 'r') as f: + ips = f.read().strip().splitlines() + return ips + +# Function to geolocate IPs and count IPs per country +def geolocate_and_count(ips): + reader = geoip2.database.Reader('GeoLite2-Country.mmdb') + country_count = defaultdict(int) + + for ip in ips: + try: + response = reader.country(ip) + country_name = response.country.name + country_count[country_name] += 1 + except geoip2.errors.AddressNotFoundError: + continue + + reader.close() + return country_count + +# Function to generate heatmap based on country IP counts +def generate_heatmap(country_counts, title): + plt.figure(figsize=(16, 10)) # Increase figure size as needed + m = Basemap(projection='mill', llcrnrlat=-60, urcrnrlat=90, llcrnrlon=-180, urcrnrlon=180, resolution='c') + m.drawcoastlines() + m.drawcountries() + + # Normalize counts for colormap + max_count = max(country_counts.values()) + norm = mpl.colors.Normalize(vmin=0, vmax=max_count) + cmap = plt.cm.get_cmap('YlOrRd') + + for country, count in country_counts.items(): + try: + country_info = m.readshapefile('shapefiles/TM_WORLD_BORDERS-0.3', 'world', drawbounds=True) + country_code = country_info['world_info'][country_info['world_info']['NAME'] == country]['ISO3'][0] + if country_code != '-99': + color = cmap(norm(count)) + poly = Polygon(m.world[country_code], facecolor=color, edgecolor='black') + plt.gca().add_patch(poly) + except: + continue + + plt.title(title) + sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm) + sm.set_array([]) + cbar = plt.colorbar(sm, orientation='vertical', shrink=0.7) # Adjust shrink parameter if necessary + cbar.set_label('Number of IPs') + plt.show() + + +# Main function to execute the program +def main(): + ips = read_ips_from_file('sample.txt') + country_counts = geolocate_and_count(ips) + generate_heatmap(country_counts, 'Heatmap of IPs by Country') + +if __name__ == "__main__": + main() diff --git a/heatmap.py b/heatmap.py new file mode 100644 index 0000000..bb04ca8 --- /dev/null +++ b/heatmap.py @@ -0,0 +1,91 @@ +import re +import matplotlib.pyplot as plt +from mpl_toolkits.basemap import Basemap +from geoip2.database import Reader + + +# Function to extract IP addresses from text using regex +def extract_ip_addresses(text): + ip_pattern = r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' + return re.findall(ip_pattern, text) + + +# Function to check if an IP address is private +def is_private_ip(ip): + octets = ip.split('.') + first_octet = int(octets[0]) + second_octet = int(octets[1]) + + # Check for private IP ranges + if (first_octet == 10) or (first_octet == 172 and 16 <= second_octet <= 31) or ( + first_octet == 192 and second_octet == 168): + return True + else: + return False + + +# Function to geolocate multiple IP addresses using GeoIP2 +def geolocate_ips(ip_list): + latitudes = [] + longitudes = [] + if ip_list: + try: + reader = Reader('GeoLite2-City.mmdb') # Replace with your actual GeoIP2 database path + for ip in ip_list: + response = reader.city(ip) + latitudes.append(response.location.latitude) + longitudes.append(response.location.longitude) + return latitudes, longitudes + except Exception as e: + print(f"Error geolocating IPs: {e}") + return [], [] + finally: + if 'reader' in locals(): + reader.close() + else: + return [], [] + + +# Function to generate heatmap +def generate_heatmap(latitude_list, longitude_list, title): + plt.figure(figsize=(50, 40)) + m = Basemap(projection='merc', llcrnrlat=-60, urcrnrlat=90, llcrnrlon=-180, urcrnrlon=180, resolution='c') + + if latitude_list and longitude_list and len(latitude_list) == len(longitude_list): + valid_indices = [i for i in range(len(latitude_list)) if latitude_list[i] is not None and longitude_list[i] is not None] + if valid_indices: + latitudes = [latitude_list[i] for i in valid_indices] + longitudes = [longitude_list[i] for i in valid_indices] + + x, y = m(longitudes, latitudes) + m.scatter(x, y, marker='o', color='r', s=50, zorder=10) + + m.drawcoastlines() + m.drawcountries() + m.drawmapboundary() + + plt.title(title) + plt.show() + + + +# Read the contents of the text file +file_path = 'sample.txt' # Replace with your actual file path +with open(file_path, 'r') as file: + data = file.read() + +# Extract all source and destination IP addresses +ips = extract_ip_addresses(data) +source_ips = [ip for ip in ips[::2] if not is_private_ip(ip)] # Exclude private IPs from source list +destination_ips = [ip for ip in ips[1::2] if not is_private_ip(ip)] # Exclude private IPs from destination list + +print(f"Source IPs: {source_ips}") +print(f"Destination IPs: {destination_ips}") + +# Geolocate all source and destination IPs +source_lats, source_lons = geolocate_ips(source_ips) +destination_lats, destination_lons = geolocate_ips(destination_ips) + +# Generate heatmaps for source and destination IPs +generate_heatmap(source_lats, source_lons, 'Source IPs Geolocation Heatmap (excluding private)') +generate_heatmap(destination_lats, destination_lons, 'Destination IPs Geolocation Heatmap (excluding private)') diff --git a/old.py b/old.py new file mode 100644 index 0000000..87082cc --- /dev/null +++ b/old.py @@ -0,0 +1,55 @@ +import re +from collections import defaultdict +import matplotlib.pyplot as plt + +def parse_file(file_path): + with open(file_path, 'r') as file: + data = file.read() + + pattern = re.compile(r'Source address: /(\d+\.\d+\.\d+\.\d+).*?Destination address: /(\d+\.\d+\.\d+\.\d+).*?Source port: (\d+).*?Destination port: (\d+)', re.DOTALL) + matches = pattern.findall(data) + + return matches + +def count_occurrences(matches): + counts = defaultdict(int) + for src_ip, dst_ip, src_port, dst_port in matches: + counts[(src_ip, dst_ip, dst_port)] += 1 + + return counts + +def plot_data(counts): + src_ips = [] + dst_ips = [] + ports = [] + occurrences = [] + + for (src_ip, dst_ip, port), count in counts.items(): + src_ips.append(src_ip) + dst_ips.append(dst_ip) + ports.append(port) + occurrences.append(count) + + fig, ax = plt.subplots(figsize=(10, 8)) + + bar_width = 0.35 + index = range(len(src_ips)) + + bars = ax.bar(index, occurrences, bar_width, label='Occurrences') + + ax.set_xlabel('IP and Port Combinations') + ax.set_ylabel('Occurrences') + ax.set_title('Occurrences of Source IPs, Destination IPs, and Ports') + ax.set_xticks(index) + ax.set_xticklabels([f'{src_ips[i]} -> {dst_ips[i]}:{ports[i]}' for i in range(len(src_ips))], rotation=90) + ax.legend() + + plt.tight_layout() + plt.show() + +# File path to your text file +file_path = 'sample.txt' + +matches = parse_file(file_path) +counts = count_occurrences(matches) +plot_data(counts)