import requests
import csv
import argparse
import re
def scan_endpoint(method, hostname, url, region):
"""
Scans a single endpoint with the specified method, hostname, URL, and region.
Args:
method: The HTTP method (e.g., "GET", "POST").
hostname: The base hostname.
url: The URL path.
region: The region to be inserted into the hostname.
Returns:
A dictionary containing the response status code and a brief description.
"""
# Construct the full hostname with the region
parts = hostname.split(".")
if len(parts) >= 2:
parts.insert(1, region) # Insert region after the first dot
full_hostname = ".".join(parts)
else:
print(f"Invalid hostname format: {hostname}")
return {"status_code": 0, "description": "Invalid hostname format"}
full_url = f"https://{full_hostname}{url}"
try:
if method == "GET":
response = requests.get(full_url, timeout=5)
elif method == "POST":
response = requests.post(full_url, timeout=5)
elif method == "PUT":
response = requests.put(full_url, timeout=5)
elif method == "PATCH":
response = requests.patch(full_url, timeout=5)
elif method == "DELETE":
response = requests.delete(full_url, timeout=5)
else:
return {"status_code": 0, "description": f"Unsupported method:
{method}"}
return {
"status_code": response.status_code,
"description": response.reason,
}
except requests.exceptions.Timeout:
return {"status_code": 0, "description": "Timeout"}
except requests.exceptions.ConnectionError:
return {"status_code": 0, "description": "Connection Error"}
except requests.exceptions.RequestException as e:
return {"status_code": 0, "description": str(e)}
def scan_endpoints_from_csv(csv_file, region):
"""
Scans endpoints from a CSV file for a given region.
Args:
csv_file: The path to the CSV file.
region: The region to scan.
"""
results = []
try:
with open(csv_file, 'r') as file:
reader = csv.DictReader(file)
for row in reader:
method = row['method']
hostname = row['hostname']
url = row['url']
# Extract the original region from the hostname, if present
match = re.search(r"\.(.*?)\.", hostname)
original_region = match.group(1) if match else None
if original_region is None:
print(f"Could not extract region from hostname: {hostname}.
Skipping...")
continue
# Scan only if the extracted region matches the target region or is
'eu-east-1'
if original_region == region or original_region == 'eu-east-1':
result = scan_endpoint(method, hostname, url, region)
results.append({
"method": method,
"hostname": hostname.replace(original_region, region) if
original_region != 'eu-east-1' else hostname, #replace only if not eu-east-1
"url": url,
"region": region,
"status_code": result["status_code"],
"description": result["description"],
})
except FileNotFoundError:
print(f"Error: CSV file not found at {csv_file}")
return
# Print results
print("Scan Results:")
for result in results:
print(f" - {result['method']} {result['hostname']}{result['url']} (Region:
{result['region']}):")
print(f" Status Code: {result['status_code']}")
print(f" Description: {result['description']}\n")
# You can optionally save the results to a file (e.g., JSON, CSV)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Scan endpoints from a CSV file.")
parser.add_argument("csv_file", help="Path to the CSV file containing
endpoints.")
parser.add_argument("region", help="The region to scan (e.g., africa.afso1).")
args = parser.parse_args()
scan_endpoints_from_csv(args.csv_file, args.region)