lsass.exe调试方法

90 views
Skip to first unread message

cly...@gmail.com

unread,
Dec 7, 2007, 4:46:50 AM12/7/07
to Ph4nt0m
先说下刚刚又更新了fakemsv1_0一个小错误,更新后win2k3sp1里输入错误密码就不会崩溃。
其实是跳错了一个地址。
顺便给出源代码,很乱。

像这样一个一个版本的做不是办法,所以我告诉大家,我是怎么做的,以后碰到其他版本了大家可以自己做。

google调试lsass得到这篇文章
http://blogs.msdn.com/spatdsg/archive/2005/12/27/507265.aspx
在虚拟机和本机上都装个windbg,
然后虚拟机运行
dbgsrv.exe -t tcp:port=1234,password=spat
本机运行
windbg.exe -premote tcp:server=192.168.1.102,port=1234,password=spat -
p 596
其中spat是调试密码,192.168.1.102是虚拟机的ip,1234是远程调试端口,596是虚拟机的lsass.exe进程的pid。

怎么下断点呢,我是在OD反汇编里找下面这两句
CALL DWORD PTR DS:[<&ntdll.RtlCompareMem>; ntdll.RtlCompareMemory
CMP EAX,10
然后在windbg里下断点,
然后运行runas /user:administrator cmd,
输入密码看windbg是否断了下来,如果是看看传给RtlCompareMemory的参数是不是你输的密码的md4hash和用户密码的
md4hash。
如果没错的话,你就可以把它的call RtlCompareMemory随便跳到一个空白的地方,任你发挥然后再跳回来。
通用密码就是这样弄出来的。

那么记录密码是怎么做的呢?
在OD里搜
CALL msv1_0.MsvSamValidate ; \MsvSamValidate
因为这个函数其实就是判断密码是否与SAM中的密码一致,刚才的RtlCompareMemory就是在这个函数里被调用的。
因为我只想记录正确的密码,所以需要看这个函数的返回结果是什么。
但用户名和密码在哪里呢?我在MsvSamValidate的参数里找了很久都没有找到明文密码。
最后,通过查看泄露的win2000源代码,我发现了这两个函数:
NTSTATUS
LsaApLogonUserEx2 (
IN PLSA_CLIENT_REQUEST ClientRequest,
IN SECURITY_LOGON_TYPE LogonType,
IN PVOID ProtocolSubmitBuffer,
IN PVOID ClientBufferBase,
IN ULONG SubmitBufferSize,
OUT PVOID *ProfileBuffer,
OUT PULONG ProfileBufferSize,
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,
OUT PSECPKG_PRIMARY_CRED PrimaryCredentials,
OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY * SupplementalCredentials
)

NTSTATUS
MsvSamValidate (
IN SAM_HANDLE DomainHandle,
IN BOOLEAN UasCompatibilityRequired,
IN NETLOGON_SECURE_CHANNEL_TYPE SecureChannelType,
IN PUNICODE_STRING LogonServer,
IN PUNICODE_STRING LogonDomainName,
IN PSID LogonDomainId,
IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
IN PVOID LogonInformation,
IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel,
OUT PVOID * ValidationInformation,
OUT PBOOLEAN Authoritative,
OUT PBOOLEAN BadPasswordCountZeroed,
IN DWORD AccountsToTry
)

大量阅读源代码以及一步一步地跟踪后终于得到了用户名和密码的位置,
他们都是UNICODE_STRING结构,
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING *PUNICODE_STRING;

用户名的指针在LsaApLogonUserEx2的第3个参数所指向的偏移量为0C处,
密码的指针在LsaApLogonUserEx2的第15个参数所指向的偏移量为18处,
于是有了下面的代码,
MOV EAX,DWORD PTR SS:[EBP+10]
ADD EAX,0C
PUSH EAX
MOV EAX,DWORD PTR SS:[EBP+40]
ADD EAX,18
PUSH EAX
分别把用户名和密码的UNICODE_STRING指针给找出来了。
然后就是做好格式写文件了。
sprintf->CreateFileW->SetFilePointer->WriteFile->CloseHandle
这里告诉大家一个小技巧,那就是windows下的sprintf的支持PUNICODE_STRING,格式符为"%wZ",所以我一个"%wZ:
%wZ\r\n"就搞定了格式,而且自动转成了char*,爽。
细节大家可以去看我给出的源代码,文章结束。

ps
前几天搜索相关资料的时候发现了一个有趣的东西:
Login password filters in WinXP
http://www.codeproject.com/KB/winsdk/LoginFilter.aspx
作者说:
I can not emphasis enough how this could be misused. Once misused,
this becomes a password grabber.
用这个做password grabber不用好像替换任何dll,更环保:)

cly...@gmail.com

unread,
Dec 7, 2007, 4:48:53 AM12/7/07
to Ph4nt0m
晕,忘了贴地址,其实和上次一样。
生成器
http://clyfish.googlepages.com/fakemsv1_0.exe
源代码
http://clyfish.googlepages.com/fakemsv1_0.rar

On 12月7日, 下午5时46分, "clyf...@gmail.com" <clyf...@gmail.com> wrote:
> 先说下刚刚又更新了fakemsv1_0一个小错误,更新后win2k3sp1里输入错误密码就不会崩溃。
> 其实是跳错了一个地址。
> 顺便给出源代码,很乱。
>
> 像这样一个一个版本的做不是办法,所以我告诉大家,我是怎么做的,以后碰到其他版本了大家可以自己做。
>
> google调试lsass得到这篇文章http://blogs.msdn.com/spatdsg/archive/2005/12/27/507265.aspx
> Login password filters in WinXPhttp://www.codeproject.com/KB/winsdk/LoginFilter.aspx
Reply all
Reply to author
Forward
0 new messages