作者:陆麟
转载请征得作者同意.如有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机器名.
今天似乎太长了点.下次继续.