Citrix warnt seine Kunden vor den kritischen Sicherheitslücken CVE-2023-3519, CVE-2023-3466, CVE-2023-3467 in den Produkten NetScaler ADC und NetScaler Gateway (CTX561482).
Folgende Versionen sind betroffen:
# -*- coding: utf-8 -*-
import os
import time
from datetime import datetime
import subprocess
import gzip
import StringIO
cve_analyse_file = “/tmp/cve-analyse.txt”
def check_adc():
print(“Start ADC Check”)
print(“Create Analyse”)
create_analyse()
print(“Get Last Update Conf Backup”)
latest_file, latest_mtime = get_update_date()
formatted_date = time.strftime(“%m/%d/%Y”, time.localtime(latest_mtime))
file_name_content = “Die neueste Datei ist: ” + latest_file
file_date_content = “Das Datum der letzten Aenderung ist: ” + formatted_date
extend_analyse(file_name_content)
extend_analyse(file_date_content)
print(“Check nobody CronJobs”)
try:
crontab_process = subprocess.Popen([“crontab”, “-l”, “-u”, “nobody”], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
crontab_output, _ = crontab_process.communicate()
crontab_output = crontab_output.decode(“utf-8”)
print(crontab_output)
extend_analyse(“CronJobs fuer nobody:”)
extend_analyse(crontab_output)
except subprocess.CalledProcessError as e:
extend_analyse(“Es wurde kein CronJob fuer nobody gefunden”)
print(“Pruefung der bekannten Verzeichnisse (ohne NSGUI)”)
extend_analyse(“Pruefung der bekannten Verzeichnisse (ohne NSGUI)”)
folders_to_check = [“/var/python”, “/var/vpn”, “/var/netscaler/logon/”]
for folder in folders_to_check:
newer_files = check_folder(folder, latest_mtime)
extend_analyse(“Fuer den Ordner ” +folder + ” gefundene Dateien.”)
for file_path in newer_files:
extend_analyse(“Datei Gefunden: ” +file_path + “”)
print(“Pruefung des Datum vom NS_Gui Ordner”)
nsgui_change_date = check_nsgui_folder()
extend_analyse(“Der NS_GUI Ordner wurde zuletzt an folgenden Datum geaendert: ” +nsgui_change_date + “”)
print(“Pruefung der HTTP Error Logs”)
extend_analyse(“Pruefung der HTTP Error Logs”)
loglines = check_http_error_logs()
for line in loglines:
extend_analyse(line)
print(“Pruefung der SH Logs”)
extend_analyse(“Pruefung der SH Logs”)
loglines = check_http_error_logs()
for line in loglines:
extend_analyse(line)
print(“Pruefung der setui”)
extend_analyse(“Pruefung der setui”)
setuid_result = check_setuid(formatted_date)
extend_analyse(setuid_result)
def create_analyse():
with open(cve_analyse_file, “w”) as cve_analyse:
content = “Analyse zum NetScaler CVE-2023-3466, CVE-2023-3467, CVE-2023-3519”
cve_analyse.write(content + “\n\n”)
def extend_analyse(content):
with open(cve_analyse_file, “a”) as cve_analyse:
cve_analyse.write(content + “\n”)
def get_update_date():
folder_path = “/nsconfig”
prefix = “ns.conf.NS”
matching_files = [file for file in os.listdir(folder_path) if file.startswith(prefix)]
if not matching_files:
return None, None
file_with_mtime = [(file, os.path.getmtime(os.path.join(folder_path, file))) for file in matching_files]
file_with_mtime.sort(key=lambda x: x[1], reverse=True)
latest_file = file_with_mtime[0][0]
latest_mtime = file_with_mtime[0][1]
return latest_file, latest_mtime
def check_folder(folder, latest_mtime):
newer_files = []
print(“Checking files in folder: ” +folder + “”)
for root, _, files in os.walk(folder):
for file in files:
file_path = os.path.join(root, file)
file_mtime = os.path.getmtime(file_path)
if file_mtime > latest_mtime:
newer_files.append(file_path)
return newer_files
def check_nsgui_folder():
folder_path = “/netscaler/ns_gui/”
try:
last_mod_time = os.path.getmtime(folder_path)
formatted_date = time.strftime(“%m/%d/%Y %H:%M:%S”, time.localtime(last_mod_time))
except FileNotFoundError:
print(“Folder ‘” +folder_path + “‘ not found.”)
return formatted_date
def check_http_error_logs():
search_directory = ‘/var/log/’
file_patterns = [‘httperror.log’]
line_patterns = [‘.sh’, ‘.php’]
matching_files = search_files_for_patterns(search_directory, file_patterns)
matching_lines = search_lines_in_files(matching_files, line_patterns)
return matching_lines
def check_sh_logs():
search_directory = ‘/var/log/’
file_patterns = [‘sh.log’]
line_patterns = [‘/flash/nsconfig/keys’]
matching_files = search_files_for_patterns(search_directory, file_patterns)
matching_lines = search_lines_in_files(matching_files, line_patterns)
return matching_lines
def search_files_for_patterns(directory, filename_patterns):
matching_files = []
for root, _, files in os.walk(directory):
for file in files:
if all(pattern in file for pattern in filename_patterns):
matching_files.append(os.path.join(root, file))
return matching_files
def open_file(file_path):
if file_path.lower().endswith(‘.gz’):
return gzip.open(file_path, ‘rb’)
else:
return open(file_path, ‘r’)
def search_lines_in_files(files, patterns):
matching_lines = []
for file in files:
try:
with open_file(file) as f:
if isinstance(f, gzip.GzipFile):
gzip_content = f.read()
f_text = StringIO.StringIO(gzip_content)
for line in f_text:
if any(pattern in line for pattern in patterns):
matching_lines.append(line.strip())
else:
for line in f:
if any(pattern in line for pattern in patterns):
matching_lines.append(line.strip())
except IOError:
pass
return matching_lines
def check_setuid(last_update):
search_path = “/netscaler/ns_gui/”
php_files_pattern = “*.php”
update_date_str = last_update
update_date = datetime.strptime(update_date_str, “%m/%d/%Y”).strftime(“%Y-%m-%d”)
command = “find ” +search_path + ” -type f -name ‘” +php_files_pattern + “‘ -newermt ” +update_date + ” -exec ls -l ” +” + + ” + ” \\;”
try:
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
output, error = process.communicate()
if process.returncode != 0:
print(“Fehler bei der Ausfuehrung des Befehls: ” + error)
return None
setuid_result = output
return setuid_result
except subprocess.CalledProcessError as e:
print(“Fehler bei der Ausfuehrung des Befehls: ” + str(e))
return None
if __name__ == ‘__main__’:
check_adc()
Wir sind für SIE da.
Auch für Ihre Herausforderung bieten wir die passende Lösung. Zögern Sie nicht uns zu kontaktieren. Wir unterstützen Sie gerne.
FLORIAN RZYTKI | Head of Sales