Bootstrap

【系统安全】CVE-2024-49113 Windows轻量级目录访问协议(LDAP)拒绝服务漏洞


免责声明

在网络安全领域,技术文章应谨慎使用,遵守法律法规,严禁非法网络活动。未经授权,不得利用文中信息进行入侵,造成的任何后果,由使用者自行承担,本文作者不负责。提供的工具仅限学习使用,严禁外用。


一、漏洞描述

Windows Lightweight Directory Access Protocol(LDAP)是一种轻量级得目录访问协议,它是基于X.500标准的目录访问协议的一个简化版本。LDAP主要用于访问和维护分布式目录信息服务,如活动目录(Active Directory)中的数据。近日,微软发布12月补丁日安全更新修复Windows轻量级目录访问协议(LDAP)拒绝服务漏洞(CVE-2024-49113),该漏洞产生的原因是Windows LDAP客户端处理Netlogon Remote Protocol(NRPC)和LDAP客户端交互时,未能正确处理特制的LDAP响应。

二、漏洞成因

该漏洞源于 Windows 在实现 LDAP 客户端逻辑时存在的整数溢出问题。攻击者可以通过诱导目标服务器(域控制器或其他 Windows Server)访问恶意构造的 LDAP/CLDAP 服务,触发整数溢出,造成信息泄漏或导致 LSASS 进程崩溃,引发拒绝服务攻击(DoS)。

三、漏洞危害

攻击者通过向目标服务器发送恶意RPC请求诱骗目标服务器向攻击者发送LDAP查询,从而导致信息泄露和服务器崩溃等危害。

四、影响版本

Windows Server 2012 R2 (Server Core installation)
Windows Server 2012 R2
Windows Server 2012 (Server Core installation)
Windows Server 2012
Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Coreinstallation)
Windows Server 2008 R2 for x64-based Systems Service Pack 1
Windows Server 2008 for x64-based Systems Service Pack 2 (Server Coreinstallation)
Windows Server 2008 for x64-based Systems Service Pack 2
Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Coreinstallation)
Windows Server 2008 for 32-bit Systems Service Pack 2
Windows Server 2016 (Server Core installation)
Windows Server 2016
Windows 10 Version 1607 for x64-based Systems
Windows 10 Version 1607 for 32-bit Systems
Windows 10 for x64-based Systems
Windows 10 for 32-bit Systems
Windows Server 2025
Windows 11 Version 24H2 for x64-based Systems
Windows 11 Version 24H2 for ARM64-based Systems
Windows Server 2022, 23H2 Edition (Server Core installation)
Windows 11 Version 23H2 for x64-based Systems
Windows 11 Version 23H2 for ARM64-based Systems
Windows Server 2025 (Server Core installation)
Windows 10 Version 22H2 for 32-bit Systems
Windows 10 Version 22H2 for ARM64-based Systems
Windows 10 Version 22H2 for x64-based Systems
Windows 11 Version 22H2 for x64-based Systems
Windows 11 Version 22H2 for ARM64-based Systems
Windows 10 Version 21H2 for x64-based Systems
Windows 10 Version 21H2 for ARM64-based Systems
Windows 10 Version 21H2 for 32-bit Systems
Windows Server 2022 (Server Core installation)

五、攻击流程

  • 攻击者向受害者服务器发送DCE/RPC请求;
  • 受害者被触发发送有关SafeBreachLabs.pro的DNS SRV查询;
  • 攻击者的DNS服务器使用攻击者的主机名和LDAP端口进行响应;
  • 受害者发送广播NBNS请求来查找收到的主机名(攻击者)的IP地址;
  • 攻击者发送一个NBNS响应,其中包含其IP地址;
  • 受害者成为LDAP客户端并向攻击者的机器发送CLDAP请求;
  • 攻击者发送带有特定值的CLDAP引用响应数据包,导致LSASS崩溃并强制受害者服务器重新启动;
    在这里插入图片描述

利用条件:

  1. 攻击者能够发起并触发目标服务器的 RPC 调用,通常需要在内网环境中。
  2. 目标服务器(DC)的 DNS 查询可出网。
  3. 攻击者能够接收来自目标服务器的 LDAP/CLDAP 请求,并返回恶意响应。

漏洞检测脚本如下:

import socket
import argparse
import threading
import time
import ipaddress
from concurrent.futures import ThreadPoolExecutor
from impacket.dcerpc.v5 import transport, nrpc

class ExploitChecker:
    def __init__(self, target_ip):
        self.target_ip = target_ip
        self.results = {
            "ldap_connect": False,
            "rpc_connect": False,
            "netlogon_service": False,
            "ldap_callback": False
        }

    def check_rpc_port(self, port=49664):
        try:
            rpctransport = transport.DCERPCTransportFactory(f'ncacn_ip_tcp:{self.target_ip}[{port}]')
            dce = rpctransport.get_dce_rpc()
            dce.connect()
            try:
                dce.bind(nrpc.MSRPC_UUID_NRPC)
                self.results["netlogon_service"] = True
            except:
                pass
            dce.disconnect()
            self.results["rpc_connect"] = True
            return True
        except:
            return False

    def check_ldap_port(self, port=389):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(2)
            result = sock.connect_ex((self.target_ip, port))
            sock.close()
            self.results["ldap_connect"] = (result == 0)
            return self.results["ldap_connect"]
        except:
            return False

    def ldap_callback_listener(self):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            sock.bind(('0.0.0.0', 389))
            sock.settimeout(5)
            while not self.results["ldap_callback"]:
                try:
                    data, addr = sock.recvfrom(1024)
                    if addr[0] == self.target_ip:
                        self.results["ldap_callback"] = True
                        break
                except socket.timeout:
                    break
            sock.close()
        except Exception as e:
            print(f"LDAP Listener Error: {str(e)}")

    def run_checks(self):
        print(f"\n[*] Checking {self.target_ip}")
        
        listener_thread = threading.Thread(target=self.ldap_callback_listener)
        listener_thread.daemon = True
        listener_thread.start()

        with ThreadPoolExecutor(max_workers=3) as executor:
            executor.submit(self.check_rpc_port)
            executor.submit(self.check_ldap_port)
        
        time.sleep(6)
        
        can_exploit = all(self.results.values())
        status = "Potentially Vulnerable" if can_exploit else "Not Vulnerable"
        
        print(f"[{self.target_ip}]")
        print(f"├── RPC (49664): {'✓' if self.results['rpc_connect'] else '✗'}")
        print(f"├── LDAP (389): {'✓' if self.results['ldap_connect'] else '✗'}")
        print(f"├── Netlogon: {'✓' if self.results['netlogon_service'] else '✗'}")
        print(f"├── Callbacks: {'✓' if self.results['ldap_callback'] else '✗'}")
        print(f"└── Status: {status}\n")
        
        return can_exploit

def check_targets(targets):
    vulnerable_hosts = []
    for ip in targets:
        checker = ExploitChecker(str(ip))
        if checker.run_checks():
            vulnerable_hosts.append(str(ip))
    return vulnerable_hosts

def parse_ip_input(ip_input):
    try:
        return list(ipaddress.ip_network(ip_input, strict=False).hosts())
    except ValueError:
        try:
            return [ipaddress.ip_address(ip_input)]
        except ValueError:
            with open(ip_input, 'r') as f:
                return [ipaddress.ip_address(line.strip()) for line in f if line.strip()]

def main():
    parser = argparse.ArgumentParser(description="Multi-target LDAP Nightmare Pre-Exploit Checker")
    parser.add_argument("target", help="Target IP, subnet (CIDR), or file with IP list")
    parser.add_argument("-o", "--output", help="Output file for vulnerable hosts")
    args = parser.parse_args()

    try:
        targets = parse_ip_input(args.target)
        print(f"[*] Loaded {len(targets)} targets")
        
        vulnerable_hosts = check_targets(targets)
        
        print("\n[+] Scan Complete")
        print(f"[+] Found {len(vulnerable_hosts)} potentially vulnerable hosts")
        
        if args.output and vulnerable_hosts:
            with open(args.output, 'w') as f:
                for host in vulnerable_hosts:
                    f.write(f"{host}\n")
            print(f"[+] Results saved to {args.output}")

    except Exception as e:
        print(f"[-] Error: {str(e)}")

if __name__ == "__main__":
    main()

利用脚本如下:https://github.com/SafeBreach-Labs/CVE-2024-49113

在这里插入图片描述

六、修复方案

临时修复方案

1、 使用流量设备监控可疑的DNS SRV查询,对可疑查询进行防护。
2、 使用终端设备监控可疑的DsrGetDcNameEx2 RPC调用,对可疑RPC调用进行防护。

Windows自动更新

Windows系统默认启用Microsoft Update,当检测到可用更新时,将会自动下载更新并在下一次启动时安装。
还可以通过以下步骤快速安装更新:

1、 点击开始菜单或按Windows快捷键,点击进入设置
2、 选择更新和安全,进入Windows更新(Windows Server2012以及Windows Server2012R2可通过控制面板进入Windows更新,步骤为控制面板->系统和安全->Windows更新);
3、 选择检查更新,等待系统将自动检查并下载可用更新;
4、 重启计算机,安装更新。

Windows手动安装补丁

对于不能自动更新的系统版本,可参考以下链接下载适用于该系统的补丁并安装:
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-49113

;