You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#查找指定网络端口占用进程并监控AD登录请求状态

基于C#的AD登录请求监控实现方案

实现思路

AD登录请求通常走LDAP(默认389端口)或LDAPS(636端口),要实现监控需完成三个核心动作:捕获本地到AD服务器的网络连接并关联进程PID、记录请求时间戳、通过Windows事件日志判断登录成败状态。

具体实现步骤

1. 捕获网络连接并关联PID

利用Windows原生的IP Helper API获取TCP连接的进程映射,过滤目标端口为389/636的连接(AD服务端口),拿到发起请求的进程PID。

代码示例:

using System;
using System.Runtime.InteropServices;

public class TcpConnectionTracker
{
    [DllImport("iphlpapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int pdwSize, bool bOrder, int ulAf, TcpTableClass tblClass, uint dwReserved);

    private enum TcpTableClass
    {
        TCP_TABLE_OWNER_PID_CONNECTIONS = 4
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct MIB_TCPROW_OWNER_PID
    {
        public uint state;
        public uint localAddr;
        public uint localPort;
        public uint remoteAddr;
        public uint remotePort;
        public int owningPid;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct MIB_TCPTABLE_OWNER_PID
    {
        public uint dwNumEntries;
        public MIB_TCPROW_OWNER_PID table;
    }

    public static void TrackAdConnections()
    {
        int bufferSize = 0;
        GetExtendedTcpTable(IntPtr.Zero, ref bufferSize, true, 2, TcpTableClass.TCP_TABLE_OWNER_PID_CONNECTIONS, 0);
        IntPtr tableBuffer = Marshal.AllocHGlobal(bufferSize);

        try
        {
            if (GetExtendedTcpTable(tableBuffer, ref bufferSize, true, 2, TcpTableClass.TCP_TABLE_OWNER_PID_CONNECTIONS, 0) == 0)
            {
                MIB_TCPTABLE_OWNER_PID tcpTable = Marshal.PtrToStructure<MIB_TCPTABLE_OWNER_PID>(tableBuffer);
                IntPtr rowPtr = (IntPtr)((long)tableBuffer + Marshal.SizeOf(tcpTable.dwNumEntries));

                for (int i = 0; i < tcpTable.dwNumEntries; i++)
                {
                    MIB_TCPROW_OWNER_PID row = Marshal.PtrToStructure<MIB_TCPROW_OWNER_PID>(rowPtr);
                    ushort remotePort = (ushort)((row.remotePort >> 8) | ((row.remotePort & 0xFF) << 8));
                    if (remotePort == 389 || remotePort == 636)
                    {
                        int pid = row.owningPid;
                        string timestamp = DateTime.Now.ToString("HH:mm:ss:ffff");
                        Console.WriteLine($"捕获到AD请求 - PID: {pid}, 时间: {timestamp}");
                    }
                    rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf<MIB_TCPROW_OWNER_PID>());
                }
            }
        }
        finally
        {
            Marshal.FreeHGlobal(tableBuffer);
        }
    }
}

2. 获取AD登录状态

Windows安全日志会记录AD登录事件:事件ID4624表示登录成功,4625表示失败。通过读取这些日志,结合PID关联到之前捕获的请求,就能得到登录状态。

代码示例:

using System;
using System.Diagnostics.Eventing.Reader;
using System.Diagnostics;

public class AdLoginStatusChecker
{
    public static void MonitorAdLoginLogs(string domainName)
    {
        string query = $"*[System[EventID=4624 or EventID=4625]] and *[EventData[Data[@Name='TargetDomainName']='{domainName}']]";
        EventLogQuery logQuery = new EventLogQuery("Security", PathType.LogName, query);

        using (EventLogReader logReader = new EventLogReader(logQuery))
        {
            EventRecord logEntry;
            while ((logEntry = logReader.ReadEvent()) != null)
            {
                try
                {
                    int pid = int.Parse(logEntry.Properties[10].Value.ToString());
                    string status = logEntry.Id == 4624 ? "Success" : "Failed";
                    string timestamp = logEntry.TimeCreated.Value.ToString("HH:mm:ss:ffff");
                    Process process = Process.GetProcessById(pid);
                    string appInfo = $"{process.ProcessName}_{pid}";

                    Console.WriteLine($"{appInfo}, {timestamp} , ({status})");
                }
                catch (ArgumentException)
                {
                    continue;
                }
            }
        }
    }
}

3. 整合监控逻辑

将上述两部分结合,比如每隔一段时间扫描TCP连接,同时实时监听事件日志,通过PID和时间窗口(比如连接发生后5分钟内的日志)匹配,输出最终结果。

关键注意事项

  • 程序必须以管理员权限运行,否则无法访问TCP连接信息和安全事件日志。
  • 事件日志中的PID可能存在延迟,建议设置合理的时间窗口进行匹配。
  • 如果AD使用非标准端口,需要调整代码中过滤的端口号。

内容的提问来源于stack exchange,提问作者Ken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:33:19