PHP监控Windows服务器登录事件

前言

开启Windows服务器远程桌面服务后,为了查询用户登录的时间、IP及次数等信息,需要在事件查看器中查看,不是很方便。本篇文章主要实现了通过PHP来查询登录事件,并把登录事件中包含的关键信息通知给系统管理员。

原理

Windows登录成功的事件ID是:4624(登录失败为4625),事件中包含了登录账户名、登录源IP和端口等信息:

可以通过powershell的Get-EventLog命令来查询事件:

Get-EventLog -LogName Security -InstanceId 4624 -Message '*User32*' -Newest 1 | Select-Object -Property *

关于Get-EventLog命令参数的详细解释可以查看微软的官方文档

可以通过php来执行powershell命令获取事件的具体内容。

代码

$log = getEventLog();
error_log($log."\r\n",3,'C:/login.log');
echo $log;die;

function getEventLog()
{
    $cmd = "powershell.exe \"Get-EventLog -LogName Security -InstanceId 4624 -Message '*User32*' -Newest 1| Select-Object -Property *\" ";
    exec($cmd,$output, $return_val);
    $outputStr = implode('$$',$output);
    $outputStr = iconv("GBK","UTF-8",$outputStr);
    $outputStr = str_replace('        ','',$outputStr);
    $account = getTagValue('Account Name',$outputStr);
    $ip = getTagValue('Source Network Address',$outputStr);
    $loginAt = getTagValue('TimeWritten',$outputStr);
    return "用户使用账号:{$account}登录成功,来源IP:{$ip},登录时间:{$loginAt}";
}

function getTagValue($tag,$str)
{
    preg_match_all('/'.$tag.':(.*?)\$/',$str,$matches);
    if(!$matches[1]) {
        $tagCn = getTagCn($tag);
        preg_match_all('/'.$tagCn.':(.*?)\$/',$str,$matches);
        if(!$matches[1]) return '';
    }
    return $matches[1][1] ? trim($matches[1][1]) : trim($matches[1][0]);
}

function getTagCn($tag)
{
    switch ($tag){
        case "Account Name":
            return '帐户名称';
        case "Source Network Address":
            return '源网络地址';
        default:
            return $tag;
    }
}

触发

上面的PHP代码可以获取到最新一条的登录日志信息,可以通过Windows的计划任务来执行。
打开计划任务程序,创建基本任务:

触发器选择“当前用户登录时”:

操作选择“启动程序”:

填写要执行的脚本路径:

创建完成后,找到刚新建的任务计划,右键点击属性:
勾选最高权限运行,同时,如果你不想登录的时候看到一闪而过的cmd黑窗口,可以选择由SYSTEM用户组来执行:

在“触发器”中选择“新建”:

开始任务选择“当连接到用户会话时”:

添加完成后,触发器中应有两条记录:

测试

设置好后,断开远程连接,重新登录服务器,可以看到在C盘会出现一个login.log文件:

后续就是为上面的代码添加通知功能,通知的类型很多:短信、电子邮件、钉钉、微信等,也可以把登录日志记录到数据库中便于查询,这里就不多说了。

登录失败的监控

以上对登录成功事件进行了监控,为了第一时间知道有人在破解密码,获取到登录失败的通知,那么还需要配置监听登录失败的监控。与登录成功的监控类似,也需要创建一个计划任务,只是触发器需要按照下面的图片修改下:

开机监控

开机监控代码

function getEventLog()
{
    $cmd = "powershell.exe \"Get-EventLog -LogName Security -InstanceId 4608 -Newest 1| Select-Object -Property *\" ";
    exec($cmd,$output, $return_val);
    $outputStr = implode('$$',$output);    
    $outputStr = iconv("GBK","UTF-8",$outputStr);
    $outputStr = str_replace('  ','',$outputStr);
    $message = getTagValue('Message',$outputStr);
    $loginAt = getTagValue('TimeGenerated',$outputStr);
    return $message.",启动时间:{$loginAt}";
}
function getTagValue($tag,$str)
{
    preg_match_all('/'.$tag.':(.*?)\$/',$str,$matches);
    return $matches[1][1] ? trim($matches[1][1]) : trim($matches[1][0]);
}

未执行的情况

windows10或windows11如出现以上代码未执行时,可以改为监听7001事件:

function getEventLog()
{
    $cmd = "powershell.exe \"Get-EventLog -LogName System -InstanceId 7001 -Newest 1| Select-Object -Property *\" ";
    exec($cmd,$output, $return_val);
    $outputStr = implode('$$',$output);
    $outputStr = str_replace('  ','',$outputStr);
    $outputStr = str_replace('客户体验改善计划的','',$outputStr);
    $message = getTagValue('Message',$outputStr);
    $loginAt = getTagValue('TimeGenerated',$outputStr);
    return $message.",启动时间:{$loginAt}";
}

指定事件监控

常见问题

没有获取到登录失败事件

原因是审核策略中没有开启,在控制面板-管理工具-本地安全策略-本地策略 – 审核策略:启用全部成功、失败的审核策略:

更多事件

4608 —– Windows正在启动
4609 —– Windows正在关闭
4624 —– 帐户已成功登录
4625 —– 帐户无法登录
4634 —– 帐户已注销
4720 —– 已创建用户帐户
4722 —– 用户帐户已启用
4723 —– 尝试更改帐户的密码
4724 —– 尝试重置帐户密码
4725 —– 用户帐户已被禁用
4726 —– 用户帐户已删除
4740 —– 用户帐户已被锁定
4741 —– 已创建计算机帐户
4742 —– 计算机帐户已更改
4743 —– 计算机帐户已删除
5024 —– Windows防火墙服务已成功启动
5025 —– Windows防火墙服务已停止
https://blog.csdn.net/WEARE001/article/details/121924551

发表评论

邮箱地址不会被公开。 必填项已用*标注