能力值:
( LV4,RANK:50 )
|
-
-
26 楼
大侠口误了吧
Minimum supported client
Windows XP
|
能力值:
( LV12,RANK:750 )
|
-
-
27 楼
原因是wdigest.dll的 SpAcceptCredentials实现时,复制了一份密码,然后使用 LsaProtectMemory对密码进行了简单加密,晕
signed int __stdcall [B]SpAcceptCredentials[/B](int a1, int a2, int PrimaryCredentials, int a4)
{
signed int v4; // ebx@1
int v5; // esi@1
int v6; // eax@2
int v7; // eax@8
unsigned __int16 v8; // ax@15
int v9; // ecx@18
int i; // eax@20
__int16 v12; // [sp+Ch] [bp-8h]@1
UNICODE_STRING tmpPass; // [sp+Eh] [bp-6h]@1
v4 = 0;
v12 = 0;
*(_DWORD *)&tmpPass.Length = 0;
LOWORD(tmpPass.Buffer) = 0;
v5 = 0;
if ( PrimaryCredentials )
{
v6 = *(_DWORD *)(PrimaryCredentials + 44);
if ( v6 & 1 )
{
if ( v6 & 4 )
{
v4 = UnicodeStringDuplicatePassword((PUNICODE_STRING)&v12, (PUNICODE_STRING)(PrimaryCredentials + 24));
if ( v4 >= 0 )
{
if ( tmpPass.Length )
(*(void (__stdcall **)(_DWORD, _DWORD))(g_LsaFunctions + 176))(
*(_DWORD *)&tmpPass.MaximumLength,
tmpPass.Length);
v4 = LogSessHandlerPasswdSet(PrimaryCredentials, &v12);
}
}
else
{
v7 = DigestAllocateMemory(68);
v5 = v7;
if ( v7 )
{
LogonSessionInit(v7);
*(_DWORD *)(v5 + 24) = a1;
*(_DWORD *)(v5 + 16) = *(_DWORD *)PrimaryCredentials;
*(_DWORD *)(v5 + 20) = *(_DWORD *)(PrimaryCredentials + 4);
v4 = UnicodeStringDuplicate(v5 + 28, PrimaryCredentials + 8);
if ( v4 >= 0 )
{
v4 = UnicodeStringDuplicate(v5 + 36, PrimaryCredentials + 16);
if ( v4 >= 0 )
{
v4 = UnicodeStringDuplicate(v5 + 52, PrimaryCredentials + 48);
if ( v4 >= 0 )
{
v4 = UnicodeStringDuplicate(v5 + 60, PrimaryCredentials + 56);
if ( v4 >= 0 )
{
v4 = [B]UnicodeStringDuplicatePassword[/B](
(PUNICODE_STRING)(v5 + 44),
(PUNICODE_STRING)(PrimaryCredentials + 24));// 这里复制了密码 windbg可以断下看到明文密码
if ( v4 >= 0 )
{
v8 = *(_WORD *)(v5 + 46);
if ( v8 )
(*(void (__stdcall **)(_DWORD, _DWORD))(g_LsaFunctions + 176))(*(_DWORD *)(v5 + 48), v8);//
// CredFreeCredentialsFn *CrediFreeCredentials;
// PLSA_PROTECT_MEMORY [B]LsaProtectMemory[/B]; <--
//PLSA_PROTECT_MEMORY LsaUnprotectMemory;
// 测试表明一执行完这个函数
// pass里面的明文变动了!!!!!
//
[B]LogSessHandlerInsert[/B](v5);
v5 = 0;
}
}
}
}
}
}
else
{
v4 = 0x80090300u;
}
}
}
}
v9 = *(_DWORD *)&tmpPass.MaximumLength; // 这里安全清楚复制的临时pass
if ( *(_DWORD *)&tmpPass.MaximumLength )
{
if ( tmpPass.Length )
{
for ( i = tmpPass.Length; i; --i )
*(_BYTE *)v9++ = 0;
}
}
StringFree(&v12);
if ( v5 )
LogonSessionFree(v5);
return v4;
}
int __stdcall [B]LogSessHandlerInsert[/B](int a1)
{
struct _LIST_ENTRY *v2; // ecx@1
RtlEnterCriticalSection(&l_LogSessCritSect);
v2 = l_LogSessList.Flink;
*(_DWORD *)a1 = l_LogSessList.Flink;
*(_DWORD *)(a1 + 4) = &l_LogSessList;
v2->Blink = (struct _LIST_ENTRY *)a1;
l_LogSessList.Flink = (struct _LIST_ENTRY *)a1;
RtlLeaveCriticalSection(&l_LogSessCritSect);
return 0;
}
这个LsaProtectMemory是一个很神奇的函数!!!请大侠研究 我要睡觉了
g_LsaFunctions + 176 + 4 -》 LsaUnprotectMemory
|
能力值:
( LV2,RANK:10 )
|
-
-
28 楼
楼上v587~
|
能力值:
( LV2,RANK:10 )
|
-
-
29 楼
直接dll名字 就可以的~
|
能力值:
( LV12,RANK:470 )
|
-
-
30 楼
boywhp大牛v5啊。 不过我不清楚ms的Minimum supported client与server差别在哪里?client支持就可以call了?server支持是远程call木?
本人的系统 xp sp3 wdigest.dll有这个函数
g_LsaFunctions是在SpInitialize中初始化的,看起来是第三个参数
NTSTATUS SpInitialize( __in ULONG_PTR PackageId, __in PSECPKG_PARAMETERS Parameters, __in PLSA_SECPKG_FUNCTION_TABLE FunctionTable ); typedef struct _LSA_SECPKG_FUNCTION_TABLE { PLSA_CREATE_LOGON_SESSION CreateLogonSession; PLSA_DELETE_LOGON_SESSION DeleteLogonSession; PLSA_ADD_CREDENTIAL AddCredential; PLSA_GET_CREDENTIALS GetCredentials; PLSA_DELETE_CREDENTIAL DeleteCredential; PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap; PLSA_FREE_LSA_HEAP FreeLsaHeap; PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer; PLSA_FREE_CLIENT_BUFFER FreeClientBuffer; PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer; PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer; PLSA_IMPERSONATE_CLIENT ImpersonateClient; PLSA_UNLOAD_PACKAGE UnloadPackage; PLSA_DUPLICATE_HANDLE DuplicateHandle; PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS SaveSupplementalCredentials; PLSA_CREATE_THREAD CreateThread; PLSA_GET_CLIENT_INFO GetClientInfo; PLSA_REGISTER_NOTIFICATION RegisterNotification; PLSA_CANCEL_NOTIFICATION CancelNotification; PLSA_MAP_BUFFER MapBuffer; PLSA_CREATE_TOKEN CreateToken; PLSA_AUDIT_LOGON AuditLogon; PLSA_CALL_PACKAGE CallPackage; PLSA_FREE_LSA_HEAP FreeReturnBuffer; PLSA_GET_CALL_INFO GetCallInfo; PLSA_CALL_PACKAGEEX CallPackageEx; PLSA_CREATE_SHARED_MEMORY CreateSharedMemory; PLSA_ALLOCATE_SHARED_MEMORY AllocateSharedMemory; PLSA_FREE_SHARED_MEMORY FreeSharedMemory; PLSA_DELETE_SHARED_MEMORY DeleteSharedMemory; PLSA_OPEN_SAM_USER OpenSamUser; PLSA_GET_USER_CREDENTIALS GetUserCredentials; PLSA_GET_USER_AUTH_DATA GetUserAuthData; PLSA_CLOSE_SAM_USER CloseSamUser; PLSA_CONVERT_AUTH_DATA_TO_TOKEN ConvertAuthDataToToken; PLSA_CLIENT_CALLBACK ClientCallback; PLSA_UPDATE_PRIMARY_CREDENTIALS UpdateCredentials; PLSA_GET_AUTH_DATA_FOR_USER GetAuthDataForUser; PLSA_CRACK_SINGLE_NAME CrackSingleName; PLSA_AUDIT_ACCOUNT_LOGON AuditAccountLogon; PLSA_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough; CredReadFn *CrediRead; CredReadDomainCredentialsFn *CrediReadDomainCredentials; CredFreeCredentialsFn *CrediFreeCredentials; PLSA_PROTECT_MEMORY LsaProtectMemory; PLSA_PROTECT_MEMORY LsaUnprotectMemory; PLSA_OPEN_TOKEN_BY_LOGON_ID OpenTokenByLogonId; PLSA_EXPAND_AUTH_DATA_FOR_DOMAIN ExpandAuthDataForDomain; PLSA_ALLOCATE_PRIVATE_HEAP AllocatePrivateHeap; PLSA_FREE_PRIVATE_HEAP FreePrivateHeap; PLSA_CREATE_TOKEN_EX CreateTokenEx; CredWriteFn *CrediWrite; CrediUnmarshalandDecodeStringFn *CrediUnmarshalandDecodeString; PLSA_REGISTER_IDENTITY_PROVIDER RegisterIdentityProvider; PLSA_GET_EXTENDED_CALL_FLAGS GetExtendedCallFlags; PLSA_DUPLICATE_HANDLE DuplicateTokenHandle; PLSA_GET_SERVICE_ACCOUNT_PASSWORD GetServiceAccountPassword; PLSA_UPDATE_LOGON_SESSION_DATA UpdateLogonSessionData; } LSA_SECPKG_FUNCTION_TABLE, *PLSA_SECPKG_FUNCTION_TABLE; typedef struct SECPKG_FUNCTION_TABLE { PLSA_AP_INITIALIZE_PACKAGE InitializePackage; PLSA_AP_LOGON_USER LogonUser; PLSA_AP_CALL_PACKAGE CallPackage; PLSA_AP_LOGON_TERMINATED LogonTerminated; PLSA_AP_CALL_PACKAGE_UNTRUSTED CallPackageUntrusted; PLSA_AP_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough; PLSA_AP_LOGON_USER_EX LogonUserEx; PLSA_AP_LOGON_USER_EX2 LogonUserEx2; SpInitializeFn *Initialize; SpShutdownFn *Shutdown; SpGetInfoFn *GetInfo; SpAcceptCredentialsFn *AcceptCredentials; SpAcquireCredentialsHandleFn *AcquireCredentialsHandle; SpQueryCredentialsAttributesFn *QueryCredentialsAttributes; SpFreeCredentialsHandleFn *FreeCredentialsHandle; SpSaveCredentialsFn *SaveCredentials; SpGetCredentialsFn *GetCredentials; SpDeleteCredentialsFn *DeleteCredentials; SpInitLsaModeContextFn *InitLsaModeContext; SpAcceptLsaModeContextFn *AcceptLsaModeContext; SpDeleteContextFn *DeleteContext; SpApplyControlTokenFn *ApplyControlToken; SpGetUserInfoFn *GetUserInfo; SpGetExtendedInformationFn *GetExtendedInformation; SpQueryContextAttributesFn *QueryContextAttributes; SpAddCredentialsFn *AddCredentials; SpSetExtendedInformationFn *SetExtendedInformation; SpSetContextAttributesFn *SetContextAttributes; SpSetCredentialsAttributesFn *SetCredentialsAttributes; SpSetExtendedInformationFn *SpChangeAccountPasswordFn; SpQueryMetaDataFn *QueryMetaData; SpExchangeMetaDataFn *ExchangeMetaData; SpGetCredUIContextFn *GetCredUIContext; SpUpdateCredentialsFn *UpdateCredentials; SpValidateTargetInfoFn *ValidateTargetInfo; } SECPKG_FUNCTION_TABLE, *PSECPKG_FUNCTION_TABLE; typedef struct _SECPKG_PARAMETERS { ULONG Version; ULONG MachineState; ULONG SetupMode; PSID DomainSid; UNICODE_STRING DomainName; UNICODE_STRING DnsDomainName; GUID DomainGuid; } SECPKG_PARAMETERS, *PSECPKG_PARAMETERS, SECPKG_EVENT_DOMAIN_CHANGE, *PSECPKG_EVENT_DOMAIN_CHANGE;
除此以外还有一份_g_NtDigestFunctionTable表保存了一系列函数
int __stdcall SpInitialize(int a1, _DWORD a2, int a3) { int v3; // edi@3 _DWORD v4; // esi@11 DWORD nSize; // [sp+Ch] [bp-2Ch]@1 int v7; // [sp+10h] [bp-28h]@1 WCHAR Str; // [sp+14h] [bp-24h]@1
g_TimeForever = -1; g_strNtDigestUTF8ServerRealm[0] = 0; g_strNtDigestUTF8ServerRealm[1] = 0; g_strNTDigestISO8859ServerRealm[0] = 0; g_strNTDigestISO8859ServerRealm[1] = 0; g_NtDigestPackageId = a1; v7 = 1; nSize = 16; l_bDigestInitialized = 1; dword_7EACE17C = 2147483647; g_NtDigestState = 1; g_LsaFunctions = a3; RtlInitUnicodeString(&g_ustrNtDigestPackageName, L"WDigest"); 后面省略
|
能力值:
( LV12,RANK:440 )
|
-
-
31 楼
各位大神雄起啊!
|
能力值:
( LV2,RANK:10 )
|
-
-
32 楼
這種技術似乎很容易就背抵抗了= =,只要稍微再hook和inject動手腳,就無法取得了= =
感覺還不錯,但是太容易悲劇了。
|
能力值:
( LV12,RANK:750 )
|
-
-
33 楼
这个应该是Windows实现的问题,怎么能保存密码到内存呢?怎么着也只能保存hash哈
|
能力值:
( LV2,RANK:10 )
|
-
-
34 楼
有意思 收下
|
能力值:
( LV12,RANK:470 )
|
-
-
35 楼
好久不写东西了,继续下
我的机器上
lsass进程空间里面
eax=[742EC184]=74520088+b0=74520138
在地址74520138是LSASRV.7448FE76
这个函数是lsasrv.dll里面的内部函数
7448FE76 ; int __stdcall LsaProtectMemory(unsigned __int8 *, unsigned __int32)
int __stdcall LsaProtectMemory(PVOID Buffer, ULONG BufferSize) { return LsaEncryptMemory((unsigned __int8 *)Buffer, BufferSize, 1); }
int __stdcall LsaUnprotectMemory(PVOID Buffer, ULONG BufferSize) { return LsaEncryptMemory((unsigned __int8 *)Buffer, BufferSize, 0); }
可见两者是调用的同一个函数来加密解密,这个函数用的rc4算法,如下
int __stdcall LsaEncryptMemory(unsigned __int8 *a1, unsigned __int32 a2, int a3) { int result; // eax@1 unsigned __int8 *v4; // esi@1 unsigned __int32 v5; // edi@4 int v6; // [sp+8h] [bp-110h]@4 int i; // [sp+Ch] [bp-10Ch]@4 char v8; // [sp+10h] [bp-108h]@7
result = __security_cookie; v4 = a1; if ( a1 && a2 ) { if ( a2 & 7 ) { rc4_key(&v8, g_cbRandomKey, g_pRandomKey); result = rc4(&v8, a2, a1); } else { v6 = g_Feedback; result = dword_74520C9C; v5 = a2 >> 3; for ( i = dword_74520C9C; v5; --v5 ) { result = CBC(desx, 8, v4, v4, g_pDESXKey, a3, &v6); v4 += 8; } } } return result; }
其中LsaInitializeProtectedMemory中会初始化g_cbRandomKey和g_pRandomKey以及g_pDESXKey,
在某种意义上,个人认为,RC4已经是hash的一种吧,也许后续还有其他算法辅助?不过我不懂算法
读密码的程序应该可以不注入dll,而是读取lsass的内存数据,自己完成解密的,算法以及key可以抄代码
其他的部分前面的大牛已经分析的差不多了,详细的流程什么的等牛人来写吧,干活去咯
|
能力值:
( LV3,RANK:30 )
|
-
-
36 楼
[QUOTE=zhuwg;1047913]好久不写东西了,继续下
我的机器上
lsass进程空间里面
eax=[742EC184]=74520088+b0=74520138
在地址74520138是LSASRV.7448FE76
这个函数是lsasrv.dll里面的内部函数
7448FE76 ; int __stdcall LsaProte...[/QUOTE]
RC4 是流加密算法,知道密钥了,是能解密回来的。
|
能力值:
( LV2,RANK:10 )
|
-
-
37 楼
少年们 各种给力 =..=~ 向你们致敬~
|
能力值:
( LV2,RANK:10 )
|
-
-
38 楼
不能让帖子沉了 等待各种底层帝啊 =..=~
|
能力值:
( LV2,RANK:10 )
|
-
-
39 楼
犀利!!!!
|
能力值:
( LV2,RANK:10 )
|
-
-
40 楼
刚开始也是拒接访问把防火墙和杀毒软件关掉后就成功了,xp sp3中文版
|
能力值:
( LV2,RANK:10 )
|
-
-
41 楼
好厉害……牛死了
|
能力值:
( LV2,RANK:10 )
|
-
-
42 楼
好东西~~~~~~~~~~~
|
能力值:
( LV3,RANK:20 )
|
-
-
43 楼
各种给力~~~
|
能力值:
( LV2,RANK:10 )
|
-
-
44 楼
犀利!给力!雄起!!
|
能力值:
( LV2,RANK:10 )
|
-
-
45 楼
深深地佩服奋斗在一线底层工作的同学们
|
能力值:
( LV2,RANK:10 )
|
-
-
46 楼
逆向过程中发现,法国佬对于不同session时的DLL注入:
1、XP下是可以任意跨Session的,不存在问题
2、Vista之上需要跨Session,好在有NtXXXX可以直接跨..不存在问题.
现在唯一的问题是如何实现Win2K3在远程登录时的跨Session注入DLL然后读取那部分数据并解密,最终获得明文密码。
试着根据论坛内的某帖子自己写了个CreateThread,Session倒是垮了,但最后lsass.exe被搞崩溃了..
|
能力值:
( LV2,RANK:10 )
|
-
-
47 楼
强大,看不懂,先收藏了
|
能力值:
( LV2,RANK:10 )
|
-
-
48 楼
xp sp3 成功.
|
能力值:
( LV2,RANK:10 )
|
-
-
49 楼
看的云里雾里
马克下~
|
能力值:
( LV2,RANK:10 )
|
-
-
50 楼
表示关注。求源码。哈哈
|
|
|