Skip to content

Instantly share code, notes, and snippets.

@sinansh
Created January 23, 2026 13:37
Show Gist options
  • Select an option

  • Save sinansh/94697ef612d70d9c3fa203101de96feb to your computer and use it in GitHub Desktop.

Select an option

Save sinansh/94697ef612d70d9c3fa203101de96feb to your computer and use it in GitHub Desktop.
import paramiko
import csv
import sys
import socket
import re
# --- AYARLAR ---
INPUT_CSV = "servers.csv"
OUTPUT_REPORT = "envanter_analiz_raporu.csv"
# Ubuntu 10.04, CentOS 5 vb. için eski algoritmalar
def get_legacy_transport_options():
return {
"disabled_algorithms": None,
"kex": [
"diffie-hellman-group1-sha1",
"diffie-hellman-group14-sha1",
"diffie-hellman-group-exchange-sha1"
],
"ciphers": [
"aes128-cbc", "3des-cbc", "aes256-cbc", "blowfish-cbc"
]
}
def create_ssh_client(ip, port, user, password):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 1. Deneme: Modern Bağlantı
try:
client.connect(ip, port=int(port), username=user, password=password, timeout=5, allow_agent=False, look_for_keys=False)
return client, "Standard"
except (paramiko.ssh_exception.SSHException, socket.error):
pass # Modern başarısız, Legacy dene
# 2. Deneme: Legacy Bağlantı (Ubuntu 10.04, RHEL 5 vb.)
try:
legacy_opts = get_legacy_transport_options()
client.connect(
ip, port=int(port), username=user, password=password, timeout=5,
allow_agent=False, look_for_keys=False,
disabled_algorithms=legacy_opts['disabled_algorithms']
)
return client, "Legacy-Mode"
except Exception as e:
return None, str(e)
def run_command(client, command):
try:
stdin, stdout, stderr = client.exec_command(command, timeout=8)
output = stdout.read().decode('utf-8', errors='ignore').strip()
# Satır sonlarını temizle
return output.replace('\n', ' ').replace('\r', '')
except Exception:
return ""
def determine_strategy(os_name, kernel, arch):
"""
Sunucuya hangi güvenlik paketinin kurulacağına karar veren mantık.
"""
os_lower = os_name.lower()
kernel_lower = kernel.lower()
# 1. Appliance / Özel Sistemler (DOKUNMA)
if "photon" in os_lower or "esx" in os_lower or "coreos" in os_lower:
return "SKIP (Appliance/Container OS)"
# 2. Mimari Kontrolü
if arch not in ["x86_64"]:
return "LEGACY (32-bit/Non-x64)"
# 3. Kernel Versiyon Analizi
# Kernel string örneği: "5.4.0-15-generic" veya "3.10.0-1160.el7.x86_64"
try:
# Sadece ana versiyonu al (Major.Minor)
match = re.search(r'^(\d+)\.(\d+)', kernel)
if match:
major = int(match.group(1))
minor = int(match.group(2))
else:
major, minor = 0, 0
except:
major, minor = 0, 0
# --- MODERN (Sysmon + Auditd) ---
# Kernel 5.x ve üzeri (Ubuntu 20+, Debian 11+, RHEL 9)
if major >= 5:
return "MODERN"
# Kernel 4.17+ (RHEL 8, Rocky 8, Ubuntu 18.04 HWE)
if major == 4 and minor >= 17:
return "MODERN"
# --- HYBRID / ÖZEL DURUM (CentOS 7) ---
# RHEL/CentOS 7'de kernel 3.10 olsa da, build 1127+ ise Sysmon çalışır (eBPF backport)
if "el7" in kernel_lower:
# Build numarasını çekmeye çalış (3.10.0-1160...)
if "3.10.0-" in kernel:
try:
build_part = kernel.split("3.10.0-")[1].split(".")[0]
if int(build_part) >= 1127:
return "MODERN (RHEL7 Backport)"
except:
pass # Parse edemezse Legacy kabul et
return "LEGACY (CentOS 7 Old Kernel)"
# --- LEGACY (Sadece Auditd) ---
# Kernel < 4.17 (Ubuntu 16.04, CentOS 6, Debian 9)
return "LEGACY"
def main():
print(f"[*] Envanter Kesif ve Analiz Baslatiliyor...")
print(f"[*] Hedef Dosya: {INPUT_CSV}")
print("-" * 60)
results = []
try:
with open(INPUT_CSV, 'r') as f:
reader = csv.DictReader(f)
rows = list(reader)
total = len(rows)
for i, row in enumerate(rows, 1):
host = row.get('Host', 'Unknown')
ip = row['IP']
user = row['User']
password = row['Password']
port = row.get('SSH_Port', 22)
print(f"[{i}/{total}] {host} ({ip}) ...", end=" ")
sys.stdout.flush()
ssh, conn_status = create_ssh_client(ip, port, user, password)
if ssh:
# 1. Bilgi Toplama Komutları
kernel = run_command(ssh, "uname -r")
arch = run_command(ssh, "uname -m")
# OS İsmi Bulma (Garantili Yöntem)
os_name = run_command(ssh, "cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '\"'")
if not os_name: os_name = run_command(ssh, "cat /etc/redhat-release")
if not os_name: os_name = run_command(ssh, "cat /etc/issue | head -n 1")
if not os_name: os_name = "Unknown Linux"
# Temizlik
os_name = os_name.replace('\\n', '').replace('\\l', '').strip()
# Service Manager (systemd vs init)
init_proc = run_command(ssh, "ps -p 1 -o comm=")
service_mgr = "systemd" if "systemd" in init_proc else "init/upstart"
# 2. Analiz ve Karar
strategy = determine_strategy(os_name, kernel, arch)
print(f"OK -> {strategy}")
results.append({
"Host": host,
"IP": ip,
"Status": "Success",
"SSH_Mode": conn_status,
"OS_Distribution": os_name,
"Kernel_Version": kernel,
"Architecture": arch,
"Service_Manager": service_mgr,
"Recommended_Strategy": strategy,
"Notes": ""
})
ssh.close()
else:
print(f"FAIL ({conn_status})")
results.append({
"Host": host,
"IP": ip,
"Status": "Failed",
"SSH_Mode": "-",
"OS_Distribution": "-",
"Kernel_Version": "-",
"Architecture": "-",
"Service_Manager": "-",
"Recommended_Strategy": "MANUAL CHECK",
"Notes": conn_status
})
except FileNotFoundError:
print(f"HATA: {INPUT_CSV} dosyasi bulunamadi!")
return
# Raporu Kaydet
try:
with open(OUTPUT_REPORT, 'w', newline='', encoding='utf-8') as f:
fieldnames = ["Host", "IP", "Status", "SSH_Mode", "OS_Distribution", "Kernel_Version", "Architecture", "Service_Manager", "Recommended_Strategy", "Notes"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(results)
print("-" * 60)
print(f"[+] Rapor olusturuldu: {OUTPUT_REPORT}")
print("[*] Excel ile acip 'Recommended_Strategy' sutununa gore filtreleyebilirsiniz.")
except Exception as e:
print(f"HATA: Rapor yazilamadi -> {e}")
if __name__ == "__main__":
main()
Host IP SSH_Port User Password
SRV-App-01 192.168.1.100 22 root Sifre123
SRV-Web-Legacy 192.168.1.101 22 admin AdminPass
SRV-Photon-Test 192.168.1.102 22 root VMware123
SRV-Ubuntu-Old 192.168.1.103 22 root OldPass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment