gpt4 book ai didi

c - 使用 CryptUnprotectData 解密 WEP wlan 配置文件 key

转载 作者:太空狗 更新时间:2023-10-29 17:10:11 25 4
gpt4 key购买 nike

我正在尝试使用 CryptUnprotectData 解密 WEP 配置文件的 key .我获取配置文件 key 的方法是使用 netsh 导出配置文件。

netsh wlan export profile name="MyWEP" folder="./"

现在,我手动将 key Material 从 netsh 命令生成的 .xml 文件复制到我的程序中。我正在解密的方式是 -

DATA_BLOB DataOut, DataVerify;
DataOut.cbData = encryptData.length();
DataOut.pbData = (BYTE*)("I_Manually_Copy_The_WEP_Key_Here");

if (CryptUnprotectData( &DataOut,
NULL,
NULL,
NULL,
NULL,
0,
&DataVerify))
{
printf("The decrypted data is: %s\n", DataVerify.pbData);
}
else
{
printf("Failed. Error Code: %d", GetLastError());
}

但我收到错误代码 13 引用无效数据。我究竟做错了什么 ?在 Win 7 及更高版本上,我可以直接使用 WlanGetProfile使用参数 WLAN_PROFILE_GET_PLAINTEXT_KEY 。但是我在 Vista 上有 NO 选项而不是使用 CryptUnprotectData 函数。我看过类似的帖子here , here但没有得到太多有用的信息。此外,我使用具有相同用户登录凭据的相同系统。任何人都可以建议我如何进行吗?

PS:我在Windows Desktop SDK 论坛上发过同样的问题,但是还没有得到回复。在 SO 上试试运气。

最佳答案

我喜欢有关 Windows 安全的问题。因此,如果我偶尔看到这样的问题,我会尝试解决它。​​

在您的情况下,您已经通过使用 netsh.exe wlan export profile ... 完成了第一步从 XML 文件中的 WLAN 配置文件导出数据。该文件包含 <keyMaterial>元素。元素内的数据是编码为十六进制的二进制数据:(类似 01000000D08C9DDF0115D1118C7A00C0... )。

所以您首先需要做的是将字符串解码为二进制数据。您可以使用 CryptStringToBinaryCRYPT_STRING_HEX将字符串解码为二进制的参数。

下一步将填写DATA_BLOB使用二进制数据并调用 CryptUnprotectData得到结果,但是......有小问题。如何阅读 WlanGetProfile 的文档以下

By default, the keyMaterial element returned in the profile pointed to by the pstrProfileXml is encrypted. If your process runs in the context of the LocalSystem account on the same computer, then you can unencrypt key material by calling the CryptUnprotectData function.

Windows Server 2008 and Windows Vista: The keyMaterial element returned in the profile schema pointed to by the pstrProfileXml is always encrypted. If your process runs in the context of the LocalSystem account, then you can unencrypt key material by calling the CryptUnprotectData function.

所以为了能够解密 key ,我们必须调用 CryptUnprotectDataLocalSystem 安全上下文中。如果您的程序已经在 LocalSystem 上下文中运行,您可以直接执行此操作。如果不是这样,但您有管理权限或至少有调试权限,您可以从计算机上运行的其他进程“借用”LocalSystem token 。例如,可以获取“winlogon.exe”进程的进程 token 并模拟它。

以下演示程序使用 NtQuerySystemInformation 枚举进程我个人更喜欢的方法(参见我的 old answer )。可以使用 EnumProcesses或其他众所周知的方法来做同样的事情。这是对我有用的代码

#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
#pragma comment (lib, "Crypt32.lib")

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)

typedef enum _SYSTEM_INFORMATION_CLASS {
SystemProcessInformation = 5
} SYSTEM_INFORMATION_CLASS;

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;

typedef LONG KPRIORITY; // Thread priority

typedef struct _SYSTEM_PROCESS_INFORMATION_DETAILD {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER SpareLi1;
LARGE_INTEGER SpareLi2;
LARGE_INTEGER SpareLi3;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
ULONG HandleCount;
BYTE Reserved4[4];
PVOID Reserved5[11];
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION_DETAILD, *PSYSTEM_PROCESS_INFORMATION_DETAILD;

typedef NTSTATUS (WINAPI *PFN_NT_QUERY_SYSTEM_INFORMATION)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT OPTIONAL PULONG ReturnLength
);

//
// The function changes a privilege named pszPrivilege for
// the current process. If bEnablePrivilege is FALSE, the privilege
// will be disabled, otherwise it will be enabled.
//
BOOL SetCurrentPrivilege (LPCTSTR pszPrivilege, // Privilege to enable/disable
BOOL bEnablePrivilege) // to enable or disable privilege
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
BOOL bSuccess = FALSE;

if (!LookupPrivilegeValue(NULL, pszPrivilege, &luid)) return FALSE;

if (!OpenProcessToken (GetCurrentProcess(),
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
&hToken
)) return FALSE;

//
// first pass. get current privilege setting
//
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0;

AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
&tpPrevious,
&cbPrevious);

if (GetLastError() == ERROR_SUCCESS) {
//
// second pass. set privilege based on previous setting
//
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;

if(bEnablePrivilege)
tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
else
tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
tpPrevious.Privileges[0].Attributes);

AdjustTokenPrivileges(
hToken,
FALSE,
&tpPrevious,
cbPrevious,
NULL,
NULL);

if (GetLastError() == ERROR_SUCCESS) bSuccess=TRUE;

CloseHandle(hToken);
}
else {
DWORD dwErrorCode = GetLastError();

CloseHandle(hToken);
SetLastError(dwErrorCode);
}

return bSuccess;
}

DWORD GetProcessIdByProcessName (LPCWSTR pszProcessName)
{
SIZE_T bufferSize = 1024*sizeof(SYSTEM_PROCESS_INFORMATION_DETAILD);
PSYSTEM_PROCESS_INFORMATION_DETAILD pspid = NULL;
HANDLE hHeap = GetProcessHeap();
PBYTE pBuffer = NULL;
ULONG ReturnLength;
PFN_NT_QUERY_SYSTEM_INFORMATION pfnNtQuerySystemInformation = (PFN_NT_QUERY_SYSTEM_INFORMATION)
GetProcAddress (GetModuleHandle(TEXT("ntdll.dll")), "NtQuerySystemInformation");
NTSTATUS status;
int uLen = lstrlenW(pszProcessName)*sizeof(WCHAR);

__try {
pBuffer = (PBYTE) HeapAlloc (hHeap, 0, bufferSize);
#pragma warning(disable: 4127)
while (TRUE) {
#pragma warning(default: 4127)
status = pfnNtQuerySystemInformation (SystemProcessInformation, (PVOID)pBuffer,
bufferSize, &ReturnLength);
if (status == STATUS_SUCCESS)
break;
else if (status != STATUS_INFO_LENGTH_MISMATCH) { // 0xC0000004L
_tprintf (TEXT("ERROR 0x%X\n"), status);
return 1; // error
}

bufferSize *= 2;
pBuffer = (PBYTE) HeapReAlloc (hHeap, 0, (PVOID)pBuffer, bufferSize);
}

for (pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD)pBuffer; ;
pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD)(pspid->NextEntryOffset + (PBYTE)pspid)) {

if (pspid->ImageName.Length == uLen && lstrcmpiW(pspid->ImageName.Buffer, pszProcessName) == 0)
return (DWORD)pspid->UniqueProcessId;

if (pspid->NextEntryOffset == 0) break;
}
}
__finally {
pBuffer = (PBYTE) HeapFree (hHeap, 0, pBuffer);
}
return 0;
}

int _tmain()
{
BOOL bIsSuccess, bImpersonated = FALSE;
HANDLE hProcess = NULL, hProcessToken = NULL;
DATA_BLOB DataOut, DataVerify;
// !!! in the next line you should copy the string from <keyMaterial>
WCHAR szKey[] = L"01000000D08C9DDF0115D1118C7....";
BYTE byKey[1024];
DWORD cbBinary, dwFlags, dwSkip;
DWORD dwProcessId = GetProcessIdByProcessName(L"winlogon.exe");
if (dwProcessId == 0) return 1;

bIsSuccess = SetCurrentPrivilege(SE_DEBUG_NAME, TRUE);
if (!bIsSuccess) return GetLastError();

__try {
hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwProcessId);
if (!hProcess) __leave;
bIsSuccess = OpenProcessToken (hProcess, MAXIMUM_ALLOWED, &hProcessToken);
if (!bIsSuccess) __leave;
bIsSuccess = ImpersonateLoggedOnUser(hProcessToken);
if (!bIsSuccess) __leave;
bImpersonated = TRUE;

cbBinary = sizeof(byKey);
bIsSuccess = CryptStringToBinary (szKey, lstrlenW(szKey), CRYPT_STRING_HEX, // CRYPT_STRING_HEX_ANY
byKey, &cbBinary, &dwSkip, &dwFlags);
if (!bIsSuccess) __leave;
DataOut.cbData = cbBinary;
DataOut.pbData = (BYTE*)byKey;

if (CryptUnprotectData (&DataOut, NULL, NULL, NULL, NULL, 0, &DataVerify)) {
_tprintf(TEXT("The decrypted data is: %hs\n"), DataVerify.pbData);
}
}
__finally {
if (bImpersonated)
RevertToSelf();
if (hProcess)
CloseHandle(hProcess);
if (hProcessToken)
CloseHandle(hProcessToken);
}

return 0;
}

关于c - 使用 CryptUnprotectData 解密 WEP wlan 配置文件 key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10765860/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com