LOGON描述(5)

作者:陆麟
转载请征得作者同意.如有BUG,请汇报.
2000.4.12


日前接了个小活,打乱了写作计划.居然买主(兼系统分析员)不懂WIN编程.一段极其漂亮的商用代码被否定.气得我吐血.先歇几天再写他的程序吧.先写点LOGON分析.:DDD
上次说到WlxLoggedOutSAS.该函数的实现中,GINA搜集了用户名,密码.如果机器在网络上,还有域名也被搜集到了.当然,搜集用户名和密码本身并不是GINA的根本目的.GINA的根本目的是要把经过授权验证的用户登录.现在,GINA就根据搜集到的用户名和密码调用Lsa来登录用户.
首先,必须调用的是
NTSTATUS
LsaRegisterLogonProcess(
  IN PLSA_STRING LogonProcessName,
  OUT PHANDLE LsaHandle,
  OUT PLSA_OPERATIONAL_MODE SecurityMode
);
该函数只有有SeTcbPrivilege的特权的程序可以调用.
通过第一参数,审计程序将记录是什么进程尝试了登录.这样才能达到所谓的C2级安全性:所有的行为能够被审计.
当该函数成功后,进程将获得和LSA交互的权限.
然后,调用
NTSTATUS
LsaLookupAuthenticationPackage(
  IN HANDLE LsaHandle,
  IN PLSA_STRING PackageName,
  OUT PULONG AuthenticationPackage
);
GINA将查找MSV1_0_PACKAGE_NAME的验证包.该包提供缺省的登录验证服务.
当验证包被确定后,调用
NTSTATUS
LsaLogonUser(
  IN HANDLE LsaHandle,
  IN PLSA_STRING OriginName,
  IN SECURITY_LOGON_TYPE LogonType,
  IN ULONG AuthenticationPackage,
  IN PVOID AuthenticationInformation,
  IN ULONG AuthenticationInformationLength,
  IN PTOKEN_GROUPS LocalGroups OPTIONAL,
  IN PTOKEN_SOURCE SourceContext,
  OUT PVOID *ProfileBuffer,
  OUT PULONG ProfileBufferLength,
  OUT PLUID LogonId,
  OUT PHANDLE Token,
  OUT PQUOTA_LIMITS Quotas,
  OUT PNTSTATUS SubStatus
);
这里乃是一个LSA的CALL.通知LSA有人企图登录啦.
现在程序的控制被转移到了LSASS.
我们回头在讲述一下LSA这里的动静.
LSA和LOGON进程交互时,既然LOGON进程指定了验证包,那么验证包的初始化是一定要进行的.所以,LSA自己对于验证包要求必须EXPORT一个函数.这个函数就是
NTSTATUS
LsaApInitializePackage(
  IN ULONG AuthenticationPackageId,
  IN PLSA_DISPATCH_TABLE LsaDispatchTable,
  IN PLSA_STRING Database OPTIONAL,
  IN PLSA_STRING Confidentiality OPTIONAL,
  OUT PLSA_STRING *AuthenticationPackageName
);
这个函数将只被调用一次.以后就永远不被调用了.并且是在系统启动LSASS时就调用了,并不等待LOGON的CALL才进行.
LSA当被调用LsaLogonUser时,LSA本身并不处理多少,将调用传递到
NTSTATUS
LsaApLogonUser(
  IN PLSA_CLIENT_REQUEST ClientRequest,
  IN SECURITY_LOGON_TYPE LogonType,
  IN PVOID AuthenticationInformation,
  IN PVOID ClientAuthenticationBase,
  IN ULONG AuthenticationInformationLength,
  OUT PVOID *ProfileBuffer,
  OUT PULONG ProfileBufferLength,
  OUT PLUID LogonId,
  OUT PNTSTATUS SubStatus,
  OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
  OUT PVOID *TokenInformation,
  OUT PLSA_UNICODE_STRING *AccountName,
  OUT PLSA_UNICODE_STRING *AuthenticatingAuthority
);
就算完事.同时,由于C2审计的原因,上面的函数缺少对客户机器名的审计,所以导致下面函数也进入了规范.
NTSTATUS
LsaApLogonUserEx(
  IN PLSA_CLIENT_REQUEST ClientRequest,
  IN SECURITY_LOGON_TYPE LogonType,
  IN PVOID AuthenticationInformation,
  IN PVOID ClientAuthenticationBase,
  IN ULONG AuthenticationInformationLength,
  OUT PVOID *ProfileBuffer,
  OUT PULONG ProfileBufferLength,
  OUT PLUID LogonId,
  OUT PNTSTATUS SubStatus,
  OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
  OUT PVOID *TokenInformation,
  OUT PUNICODE_STRING *AccountName,
  OUT PUNICODE_STRING *AuthenticatingAuthority,
  OUT PUNICODE_STRING *MachineName
  );
最后一个参数表明了客户机的名称.在微软自己的验证包里,它返回一个NETBIOS机器名.
今天似乎太长了点.下次继续.