~ K A L I ~
UNAME : Linux web65.extendcp.co.uk 4.18.0-553.56.1.el8_10.x86_64 #1 SMP Tue Jun 10 05:00:59 EDT 2025 x86_64SERVER IP : 10.0.187.65 -________-
CLIENT IP : 216.73.216.230 MINI SHELL D ZAB '
Current File : //usr/local/bin/inventory-agent.py |
import os
import math
import time
import requests
import platform
import subprocess
from datetime import datetime
from collections import defaultdict
# API endpoint
API_ENDPOINT = "HTTP://10.0.32.45/api/restapi.php"
# Function to get the system information
def gather_system_info():
system_info = {}
# Get hostname (FQDN) and domain using the `hostname` command
try:
proc = subprocess.Popen(["hostname"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
hostname_output, error = proc.communicate()
fqdn = str(hostname_output.decode().strip())
system_info["hostname"] = fqdn.split(".")[0]
domain_parts = fqdn.split(".")[1:]
system_info["domain"] = ".".join(domain_parts) if domain_parts else "Unknown"
except Exception as e:
system_info["hostname"] = "Unknown"
system_info["domain"] = "Unknown"
system_info["hostname_error"] = str(e)
# Get IP addresses with interface names (excluding lo and docker interfaces)
system_info["ip_addresses"] = []
try:
interfaces = os.listdir('/sys/class/net')
for interface in interfaces:
if "docker" in interface or interface == "lo":
continue
try:
ip_output = subprocess.Popen(["ip", "addr", "show", interface], stdout=subprocess.PIPE)
output, _ = ip_output.communicate()
for line in output.decode().splitlines():
if "inet " in line:
ip_address = line.strip().split()[1].split('/')[0]
system_info["ip_addresses"].append({
"interface": interface,
"ip_address": str(ip_address),
})
except Exception:
continue
except Exception as e:
system_info["ip_addresses_error"] = str(e)
# Get OS details
try:
if os.path.exists("/etc/os-release"):
with open("/etc/os-release", "r") as f:
os_release = {}
for line in f:
if "=" in line:
key, value = line.strip().split("=", 1)
os_release[key] = value.strip('"')
system_info["os"] = {
"name": os_release.get("PRETTY_NAME", platform.system()),
"release": os_release.get("VERSION", platform.release()),
"architecture": platform.architecture()[0],
"kernel": platform.release(),
}
elif os.path.exists("/etc/redhat-release"):
with open("/etc/redhat-release", "r") as f:
os_release = f.read().strip()
system_info["os"] = {
"name": os_release,
"release": " ".join(os_release.split()[2:]),
"architecture": platform.architecture()[0],
"kernel": platform.release(),
}
elif os.path.exists("/etc/issue"):
with open("/etc/issue", "r") as f:
os_issue = f.read().strip()
system_info["os"] = {
"name": os_issue,
"release": " ".join(os_issue.split()[2:]),
"architecture": platform.architecture()[0],
"kernel": platform.release(),
}
else:
system_info["os"] = {
"name": platform.system(),
"release": platform.release(),
"architecture": platform.architecture()[0],
"kernel": platform.release(),
}
except Exception as e:
system_info["os_error"] = str(e)
# Get computer model, manufacturer, and type
try:
if os.path.exists("/sys/class/dmi/id/product_name"):
with open("/sys/class/dmi/id/product_name", "r") as f:
system_info["computer_model"] = f.read().strip()
with open("/sys/class/dmi/id/sys_vendor", "r") as f:
system_info["computer_manufacturer"] = f.read().strip()
with open("/sys/class/dmi/id/product_uuid", "r") as f:
system_info["uuid"] = f.read().strip()
with open("/sys/class/dmi/id/chassis_type", "r") as f:
chassis_type_code = int(f.read().strip())
chassis_type_map = {
1: "Other", 2: "Unknown", 3: "Desktop", 4: "Low Profile Desktop",
5: "Pizza Box", 6: "Mini Tower", 7: "Tower", 8: "Portable",
9: "Laptop", 10: "Notebook", 11: "Hand Held", 12: "Docking Station",
13: "All In One", 14: "Sub Notebook", 15: "Space-Saving",
16: "Lunch Box", 17: "Main System Chassis", 18: "Expansion Chassis",
19: "SubChassis", 20: "Bus Expansion Chassis", 21: "Peripheral Chassis",
22: "RAID Chassis", 23: "Rack Mount Chassis", 24: "Sealed-Case PC",
25: "Multi-System Chassis", 26: "CompactPCI", 27: "AdvancedTCA",
28: "Blade", 29: "Blade Enclosure",
}
system_info["computer_type"] = chassis_type_map.get(chassis_type_code, "Unknown")
else:
system_info.update({
"computer_model": "Unknown",
"computer_manufacturer": "Unknown",
"uuid": "Unknown",
"computer_type": "Unknown",
})
except Exception as e:
system_info["computer_info_error"] = str(e)
# Get last reboot time using `who -b`
try:
proc = subprocess.Popen(["who", "-b"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
reboot_output, error = proc.communicate()
if proc.returncode == 0:
last_reboot = str(reboot_output.decode().strip().split("system boot")[1].strip())
system_info["last_reboot"] = last_reboot
else:
system_info["last_reboot"] = "Unknown"
except Exception as e:
system_info["last_reboot"] = "Unknown"
system_info["last_reboot_error"] = str(e)
# Get serial number
try:
if os.path.exists("/sys/class/dmi/id/product_serial"):
with open("/sys/class/dmi/id/product_serial", "r") as f:
system_info["serial_number"] = f.read().strip()
else:
system_info["serial_number"] = "Unknown"
except Exception as e:
system_info["serial_number_error"] = str(e)
# Get volume data without using shell=True
system_info["volumes"] = []
try:
df_proc = subprocess.Popen(["df", "-hT"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
df_output, error = df_proc.communicate()
for line in df_output.decode().splitlines()[1:]:
parts = line.split()
# Exclude tmpfs and loop filesystems
if len(parts) >= 7 and parts[1] not in ["tmpfs", "loop", "devtmpfs"] and parts[6] != "/boot/efi" and "efi" not in parts[6].lower():
precentage = parts[5].replace("%", "")
system_info["volumes"].append({
"mountpoint": str(parts[6]),
"percent": str(precentage),
})
except Exception as e:
system_info["volumes_error"] = str(e)
# Get physical disk data
system_info["physical_disks"] = []
try:
for disk in os.listdir("/sys/block"):
if disk.startswith("loop") or disk.startswith("dm") or disk.startswith("sr") or disk.startswith("ram"):
continue
disk_info = {
"name": disk,
"size": None,
"model": None,
}
try:
size_path = "/sys/block/%s/size" % disk
if os.path.exists(size_path):
with open(size_path, "r") as f:
size_in_sectors = int(f.read().strip())
sector_size = 512
disk_info["size"] = "%.2f GB" % ((size_in_sectors * sector_size) / (1024 ** 3))
model_path = "/sys/block/%s/device/model" % disk
if os.path.exists(model_path):
with open(model_path, "r") as f:
disk_info["model"] = f.read().strip()
except Exception as e:
disk_info["error"] = str(e)
system_info["physical_disks"].append(disk_info)
except Exception as e:
system_info["physical_disks_error"] = str(e)
# Get CPU Data
try:
with open("/proc/cpuinfo", "r") as f:
cpu_count = sum(1 for line in f if line.startswith("processor"))
system_info["cpu"] = cpu_count
except Exception as e:
system_info["cpu"] = "Unknown"
system_info["cpu_error"] = str(e)
# Get Memory data
try:
with open("/proc/meminfo", "r") as f:
meminfo = f.readlines()
total_memory = next((int(line.split()[1]) for line in meminfo if line.startswith("MemTotal")), 0)
system_info["memory"] = "{0} GB".format(math.ceil(total_memory / 1024 / 1024))
except Exception as e:
system_info["memory"] = "Unknown"
system_info["memory_error"] = str(e)
# Get bridge details
system_info["bridge_details"] = []
bridge_association = defaultdict(list)
try:
with open(os.devnull, "w") as devnull:
if subprocess.call(["which", "bridge"], stdout=devnull, stderr=devnull) == 0:
result = subprocess.Popen(["bridge", "link", "show"], stdout=subprocess.PIPE)
output, _ = result.communicate()
for line in output.decode().splitlines():
parts = line.split()
if "master" in parts:
interface = parts[1].strip(":")
master = parts[parts.index("master") + 1]
bridge_association[master].append(interface)
elif subprocess.call(["which", "brctl"], stdout=devnull, stderr=devnull) == 0:
result = subprocess.Popen(["brctl", "show"], stdout=subprocess.PIPE)
output, _ = result.communicate()
for line in output.decode().splitlines()[1:]:
parts = line.split()
if len(parts) >= 4:
bridge = parts[0]
interface = parts[3]
bridge_association[bridge].append(interface)
else:
system_info["bridge_details_error"] = "Neither 'bridge' nor 'brctl' command is available."
except Exception as e:
system_info["bridge_details_error"] = str(e)
system_info["bridge_summary"] = {}
for bridge, interfaces in bridge_association.items():
system_info["bridge_summary"][bridge] = ", ".join(interfaces)
return system_info
# Function to send data to the API
def send_data_to_api(data):
try:
response = requests.post(API_ENDPOINT, json=data)
if response.status_code == 200:
print("Data successfully sent to the server.")
else:
print("Failed to send data. Status code: {}, Response: {}".format(response.status_code, response.text))
except Exception as e:
print("Error sending data to the API: {}".format(e))
# Main function to run the agent
def main():
while True:
system_info = gather_system_info()
send_data_to_api(system_info)
time.sleep(1800)
if __name__ == "__main__":
main()
Coded by KALI :v Greetz to DR HARD ../ kali.zbi@hotmail.com