ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[win2k-sfp.txt]ÄÄÄ ;---------------------------------------------------------------------------- ;Win2K infection ; ;by GriYo / 29A ;---------------------------------------------------------------------------- If we run any up-to-date Win32 virus under Windows2000 you will find out a nasty dialog box with message like this: "A file replacement was attempted on the protected system file . To maintain system stability, the file has been restored to the correct Microsoft version. If problems occur with your application, please contact the application vendor for support." Heh! Windows2000 keeps a list of protected system files, and will abort any attempt of replacing or modifiying them while showing the above message. Looking around Windows2000 DDK we can find more about this... "SFP protects system files by detecting when a file replacement is attempted on a protected system file. SFP is triggered when it receives a directory change notification on a file in a protected directory. Once this notification is received, SFP will determine which file was changed. If the file is protected, SFP will look up the file signature in a catalog file to determine if the new file is the correct Microsoft version. If the file version is incorrect, the system attempts to replace it with the new file from the dllcache directory. If the new file version is not located in the dllcache directory, the system finds the replacement file on the distribution media." Looking at the registry we can find some keys related to SFP: HKEY_LOCAL_MACHINE \SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon SfcBugcheck SfcDisable SfcQuota SfcScan One of this looks like what we are looking for, SfcDisable. This key value may be FLASE (00h) or TRUE (01h), so let go and set it to true... Fuck! Bad luck, nothing changes. SfcDisable will efectively disable SFP, but only for next boot. And the worst, this will alert the user on next boot, when a message box will appear informing us that SFP has been disabled. After this SFP *free* session the system will re-enable it. While playing with Windows 2000 beta 2 i found that setting this key to a value that is not 00h nor 01h ( setting it to 04h for instance ) will prevent the system from showing the menttioned message box on next boot. This is good, until the system re-enables SFP again and a scan is performed on protected files. At that time the system will warn us about the change on modified files. At the time im writting this article Windows 2000 is on beta 3 build 2072. I dont expect drastically changes on SFP implementation, so lets look closer to its internals. Looking at WINLOGON.EXE import section i came across this descriptor: SFC.DLL Hint/Name Table: 0001BA80 TimeDateStamp: FFFFFFFF ForwarderChain: FFFFFFFF First thunk RVA: 00001690 Ordn Name 1 2 SFC.DLL is the library that contains current SFP routines, lets dump the APIs exported by it: exports table: Name: sfc.dll Characteristics: 00000000 TimeDateStamp: 37741427 Version: 0.00 Ordinal base: 00000001 # of functions: 0000000B # of Names: 00000004 Entry Pt Ordn Name 0000743A 1 000073D2 2 00003D70 3 00003DA9 4 00003DB5 5 00003DED 6 00003E21 7 00003F0B 8 SfcGetNextProtectedFile 00003FA0 9 SfcIsFileProtected 00008D1D 10 SfcWLEventLogoff 00008C5A 11 SfcWLEventLogon Bored of browsing thru all this shit i decided to play with the API SfcIsFileProtected. Given a file name this function will tell us if the file is under SFP protection or not. Look this C example: if ( SfcIsFileProtected( NULL, szFileName) == 0) { printf ( "Not protected.\n") ; } else { printf ( "Yes, its protected.\n") ; } Using this API we can prevent the virus from infecting protected files that are for sure components of the operating system. This files wont spread the virus from the infected machines to others. I never saw CALC.EXE offered on a warez site. This may be the solution by now... Now its your time! -- GriYo / 29A I'm not in the business... ...I am the business ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[win2k-sfp.txt]ÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[Sfc.c]ÄÄÄ // // Sfc check // // A stupid but useful program to check if a file is protected // by System File Protection // // Tested under Windows 2000 Professional Build 2128 // // GriYo / 29A // #include "stdio.h" #include #include int main( int argc, char* argv[]) { OSVERSIONINFO VersionInformation ; HMODULE hSFC ; FARPROC a_SfcIsFileProtected ; FARPROC a_SfcGetNextProtectedFile ; WCHAR wszFileName[ MAX_PATH] ; PROTECTED_FILE_DATA pfd ; printf( "Sfp check by GriYo / 29A\n\n") ; if ( argc > 2) { printf( "Usage:\n\n" "%s <--- List protected files\n\n" "or\n\n" "%s /f:filename <--- Check if file is protected\n\n", argv[ 0], argv[ 0]) ; return -1 ; } VersionInformation.dwOSVersionInfoSize = sizeof( OSVERSIONINFO) ; if ( GetVersionEx( &VersionInformation) == 0) { printf( "Error: Api GetVersionEx() failed\n\n", argv[ 0]) ; return -1 ; } if ( ( VersionInformation.dwPlatformId != VER_PLATFORM_WIN32_NT) || ( VersionInformation.dwMajorVersion != 5)) { printf( "Error: This program only runs under Windows 2000\n\n") ; return -1 ; } if ( ( hSFC = LoadLibrary( "SFC.DLL")) == NULL) { printf( "Error: SFC.DLL not found\n\n", argv[ 0]) ; return -1 ; } if ( argc == 2) { // // SfcIsFileProtected // // [This is preliminary documentation and subject to change.] // // The SfcIsFileProtected function determines whether the specified // file is protected. Applications should avoid replacing protected // system files. // // BOOL WINAPI SfcIsFileProtected( IN HANDLE RpcHandle, // must be NULL // IN LPCWSTR ProtFileName) ; // // Parameters: // // ProtFileName // // [in] Pointer to a string that specifies the name of the // file. // // Return Value: // // If the file is protected, the return value is a nonzero // value. // // If the file is not protected, the return value is zero. // // Requirements : // // Windows NT/2000: Requires Windows 2000. // Windows 95/98: Unsupported. // Windows CE: Unsupported. // Header: Declared in sfc.h. // Import Library: Use sfc.lib. // // See Also: // // SfcGetNextProtectedFile // if ( ( a_SfcIsFileProtected = GetProcAddress( hSFC, "SfcIsFileProtected")) == NULL) { FreeLibrary( hSFC) ; printf( "Error: Api SfcIsFileProtected not found\n\n", argv[ 0]) ; return -1 ; } MultiByteToWideChar(CP_ACP, 0, argv[ 1], -1, wszFileName, MAX_PATH) ; if ( a_SfcIsFileProtected( NULL, wszFileName)) printf( "Protected file\n\n") ; else printf( "Unprotected file\n\n") ; } else { // // SfcGetNextProtectedFile // // [This is preliminary documentation and subject to change.] // // The SfcGetNextProtectedFile function retrieves the complete list of protected // files. Applications should avoid replacing these files. // // BOOL WINAPI SfcGetNextProtectedFile( IN HANDLE RpcHandle, // must be NULL // IN PPROTECTED_FILE_DATA ProtFileData) ; // // Parameters: // // ProtFileData [in/out] Receives the list of protected files. The format // of this structure is as follows: // // typedef struct _PROTECTED_FILE_DATA { // WCHAR FileName[ MAX_PATH] ; // DWORD FileNumber ; // } PROTECTED_FILE_DATA, *PPROTECTED_FILE_DATA ; // // Before calling this function the first time, set the FileNumber // member to zero. // // Return Value: // // If the function succeeds, the return value is nonzero. // // If there are no more protected files to enumerate, the return value // is zero. // // Requirements: // // Windows NT/2000: Requires Windows 2000. // Windows 95/98: Unsupported. // Windows CE: Unsupported. // Header: Declared in sfc.h. // Import Library: Use sfc.lib. // // See Also: // // SfcIsFileProtected // if ( ( a_SfcGetNextProtectedFile = GetProcAddress( hSFC, "SfcGetNextProtectedFile")) == NULL) { FreeLibrary( hSFC) ; printf( "Error: Api SfcGetNextProtectedFile not found\n\n", argv[ 0]) ; return -1 ; } printf( "List of protected files:\n\n") ; pfd.FileNumber = 0 ; while( SfcGetNextProtectedFile( NULL, &pfd) != 0) { printf( "%ws\n", &pfd.FileName) ; } } FreeLibrary( hSFC) ; return 0; } ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[Sfc.c]ÄÄÄ