关于windows的系统文件保护。转载:http://hi.baidu.com/w1n_r00tkit/blog/item/b4354900691aa2067aec2c6f.html

来源:互联网 发布:域名怎么做 编辑:程序博客网 时间:2024/04/30 11:27
关于windows的系统文件保护

http://hi.baidu.com/w1n_r00tkit/blog/item/b4354900691aa2067aec2c6f.html

http://eyuanhermit.blog.hexun.com/29625080_d.html

.方法1 兼容的方法
这是个非常兼容的方法我通过逆向一些微软的工具得到的。这个方法被那些工具所使用,用于修改被保护的文件。
下面将讲述它是如何工作的:
它使用了一个从sfc.dll中导出的未公开的函数SfcTerminateWatcherThread,序号是2。
正如函数名表达的意思一样:-)它可以终止监视线程比如那些处理目录变化通知的线程。
所以我们将在winlogon上下文里调用这个函数从而关闭掉SFP。我写过一篇文章是关于
感染winlogon的,回忆一下:
首先你需要提升权限,使SeDebugPrivilege函数可用。administrator用户或者一个有
SeDebugPrivilege权限的用户可以做到这一点。剩下的就是在远程线程里调用函数,
读取代码。
这个方法在Win2k,WinXP可用,我打赌他在W2k3上也可用,但是现在还不行所以没有测试。
如果你测试过了请告诉我。
BTW 你可能会问,sfc.dll不处理SFP的时候它怎么可能还起作用?
好吧,其实从sfc.dll导出的2号函数被重定向到了sfc_os.dll:-)

#include <windows.h>
#include <assert.h>
#include <stdio.h>
#pragma check_stack (off)
DWORD thread_func (FARPROC sfc_terminate)
{
   sfc_terminate();
   return 0;
}
void after_thread_func(void)
{
}
#pragma check_stack
int adjust_privileges(void)//提升权限
{
HANDLE token_handle;
int ret=0;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token_handle))
{
   LUID luid;
   if(LookupPrivilegeValue(NULL, "SeDebugPrivilege", &luid))
   {
    TOKEN_PRIVILEGES tk_priv;
    tk_priv.PrivilegeCount=1;
    tk_priv.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
    tk_priv.Privileges[0].Luid=luid;
    if(AdjustTokenPrivileges(token_handle,
     FALSE,
     &tk_priv,
     0,
     NULL,
     NULL)) ret=1;
   }
   CloseHandle(token_handle);
}
return ret;
}
void main(int argc, char **argv)
{
HANDLE remote_thread;
if(argc!=2)
{
   printf("Usage: sfc_disable <winlogon_pid>/n");
   exit(0);
}
DWORD wpid=atoi(argv[1]);
assert(wpid);
HMODULE sfc=LoadLibrary("sfc.dll");
assert(sfc);
FARPROC sfc_terminate=GetProcAddress(sfc, (char *) 2);
assert(sfc_terminate);
assert(adjust_privileges());
HANDLE process=OpenProcess(PROCESS_ALL_ACCESS, FALSE, wpid);
if(!process)
{
   printf("Error while opening process/n");
   exit(0);
}
LPVOID remote_mem=VirtualAllocEx(process,
   NULL,
   (SIZE_T) ((char *)after_thread_func-(char *)thread_func),
   MEM_COMMIT,
   PAGE_READWRITE);
if(!remote_mem)
{
   printf("Error while commiting memory in the remote process/n");
   goto clean_up;
}
if(!WriteProcessMemory(process,
   remote_mem,
   (char *) thread_func,
   (SIZE_T) ((char *)after_thread_func-(char *)thread_func),
   (SIZE_T *) 0))
{
   printf("Error %d while writing to the remote process/n", GetLastError());
   goto clean_up;
}
remote_thread=CreateRemoteThread(process,
   NULL,
   0,
   (LPTHREAD_START_ROUTINE) remote_mem,
   // (LPTHREAD_START_ROUTINE) sfc_terminate
   (LPVOID) sfc_terminate,
   0,
   NULL);
if(!remote_thread)
{
   printf("Error while creating remote thread in the process/n");
   goto clean_up;
}

if(WaitForSingleObject(remote_thread, 10*1000)==WAIT_TIMEOUT)
   printf("Timeout occured while waiting for the remote thread/n");
CloseHandle(remote_thread);
clean_up:
if(remote_mem) VirtualFreeEx(process, remote_mem, 0, MEM_RELEASE);
CloseHandle(process);
}

.方法2 更好的方法
这个方法是我现在知道的最好的方法。它只能在XP下用(w2k3可能也行??)
而且它没准是微软的某种后门:-),关键在哪?
当我寻找WINXP在实现SFP上的变化时,首先我发现SFP现在已经不再sfc.dll里了
更多的是在sfc_os.dll里所以我打开IDA开始浏览代码。没花多少时间我找到了。
XP的SFP实现里有一个简洁的方法可以基于文件禁用SFP一分钟。不相信我?测试
一下吧:-)
[cpp]//---- beginning of sfp_exc.c ----
#include <windows.h>
#include <assert.h>
#include <stdio.h>
typedef DWORD (* SFPEXC)(DWORD, wchar_t *, DWORD);
void wmain(int argc, wchar_t **argv)
{
   HMODULE sfc_os;
   SFPEXC sfp_exc;
   assert(argc==2);
   assert(sfc_os=LoadLibrary("sfc_os.dll"));
   assert(sfp_exc=(SFPEXC) GetProcAddress(sfc_os, (char *) 5));
   assert(!sfp_exc(0, argv[1], -1));
   wprintf(L"File %s should now be unprotected for 1 minute", argv[1]);
}
//---- end of sfp_exc.c ----[/cpp]
用这种方法必须使用administrator用户,因为代码会检查。它使用了一个
未公开的5号导出函数SfcFileException,如其名。它首先检查文件是不是被保护
如果是,它分配一个标志给文件。现在当监视线程因替换、修改、删除原因被调用
来保护文件时,它首先检查这个文件是否应该被排除。如果有标志的话就检查是否到达
一分钟的间隔时间。如果没有标志那就什么也不干,只是继续执行:-)
.最后
希望我这篇文章里的两个小程序可以帮助我们比以前更愉快的干掉SFP。


刚才去Google上搜了一下,居然还有如此简单的办法!sfc_os.dll导出的第五号函数!
typedef DWORD(__stdcall *CPP) (DWORD param1, PWCHAR param2, DWORD param3);

void Disable_WFP()
{

HINSTANCE hmod=LoadLibrary("sfc_os.dll");

CPP SetSfcFileException;

// the function is stored at the fifth ordinal in sfc_os.dll

SetSfcFileException= (CPP)GetProcAddress(hmod,(LPCSTR)5);

SetSfcFileException(0, L"c://windows//system32//calc.exe",-1);

//Now we can modify the system file in a complete stealth.

}

http://www.bitsum.com/aboutwfp.asp

Hacking Windows File Protection

WindowsFile Protection (WFP) is a mechanism that protects system files frombeing modified or deleted. Introduced in Windows 2000, Windows FileProtection was a leap forward in operating system stability since itprotected the core modules from being corrupted or updated except byservice packs or hotfixes sent from Microsoft.

Abig problem prior to Windows 2000 was 'DLL Hell'. Applications wouldoften update system modules with their own versions, regardless ifother applications already installed were depending on a differentversion of that same module. Although Microsoft recommended thatapplication programmers place modules into the program's folder insteadof the system folder, few programmers did. WFP solved DLL Hell, alongwith many other issues.

In order to protect theintegrity of the system, Microsoft did not document a way to disableWFP. If they had, programmers would surely begin to circumvent it andhave their application installers overwrite system modules with theirown versions. Booting to Safe Mode was the only wayMicrosoft provided for replacing a protected file. In theory, this wasa good idea. However, programmers and power users sometimes desire thepower to replace or delete protected modules without the cumbersomeprocess of booting to safe mode and back.

Enter the hacks.

InWindows 2000, a hidden registry value to fully disable WFP existed.Unfortunately, this didn't last long after I discovered and posted itto NTBugTraq. Microsoft soon tweaked their code so that the hiddenregistry value was neutralized (curiously, it wasn't completely removedfrom the code). I then created patches to re-enable this undocumentedvalue. Appendix A describes the history of the discovery of the undocumented registry value and creation of the patches to re-enable it.

Since that time, many other techniques to disable or circumvent Windows File Protection have been discovered.

How the System File Checker monitors files for changes

The executable portion of WFP is called the System File Checker (SFC). It exists throughout SFC.DLL, SFC_OS.DLL, SFCFILES.DLL, and SFC.EXE.

Thecontents of SFC.DLL and SFC_OS.DLL have changed between Windows 2000and Windows XP. In Windows XP, SFC_OS.DLL contains all the core codeand SFC.DLL is merely a proxy to it. The exports of SFC.DLL areforwarded on to SFC_OS.DLL. The SFCFILES.DLL module is simply a dataholder that contains a list of all files protected by WFP.

At startup the winlogon service invokes the unnamed export ordinal 1 of SFC_OS.DLL, SfcInitProt. This API launches a new free thread called the 'SFC Watcher Thread'.This thread creates a series of directory change notification events,one for each folder that contains a protected file. TheWaitForMultipleObjects API is then called within loop to wait for anyof these events to be signalled. Upon event signaling, the modifiedfile(s) are determined and replaced with copies found in the cachefolder, if one exists there. If it doesn't, the user is prompted toinsert the Windows installation CD so that the file can be replacedfrom the copy found on it.

Therefore,SFC actually allows for files to be replaced or modified, thenoverwrites them. A few second delay is incorporated so that time isgiven for write operations to 'settle down' before the affected file(s)are restored.

Knowing how SFC worksmeans that one can easily disable it by terminating the watcher threador by closing the directory change notification event handles. Thisleads us to methods 1 and 2:

The core of Windows File ProtectionSFC.DLLWFP executable content. In XP only a proxy to SFC_OS.DLL.SFC_OS.DLLWFP executable content.SFCFILES.DLLContains list of protected files. Exports SfcGetFiles API.SFC.EXESystem File Checker utility. Utility to scan WFP protected files for changes and replace altered versions.

Hack Method 1: Disable WFP for specific folders until the computer is next rebooted via manual handle manipulation

Thefirst technique to disable WFP is to close the directory changenotification handles by enumerating the handles that winlogon hasopened, determining which ones correspond to the folder(s) we wish todeprotect by querying and comparing the handle names, then closingthose handles via ntdll.NtDuplicateHandle (orkernel32.DuplicateHandle). This method is used by WfpAdmin.

Hack Method 2: Disable WFP completely until the computer is next rebooted via undocumented SFC API

Thesecond technique is to terminate the SFC Watcher Thread thatcontinually waits for and responds to the directory change notificationevents to be signalled. Doing this manually isn't very practical sinceit is diffucult to be sure the right thread has been located.Fortunately, the SFC_OS.DLL exposes a nice unnamed export at ordinal 2:SfcTerminateWatcherThread.. This API acceptsno parameters and does exactly as its name implies. However, there isone caveat to using this function: It must be invoked in the processthat created the SFC Watcher Thread: winlogon. To accomplish this,virtual memory needs to be allocated in the winlogon process space anda thread procedure that invokes SfcTerminateWatcherThread copied intothat memory. The thread procedure should then be invoked usingkernel32.CreateRemoteThread and WFP will be disabled until the winlogonprocess restarts (computer is rebooted).

Ordinal 2:
DWORD WINAPI SfcTerminateWatcherThread();

The return value is 0 if success, or 1 if an error occurred .

Hack Method 3: Disable WFP on a specific file for 1 minute via undocumented SFC API

The SFC_OS.DLL module exports another very useful undocumented, unnamed API at oridinal 5: SfcFileException.This handy API will register a temporary SFC exception for specificfile, allowing the file to be updated. The period the exception is inplace is currently one minute.

Ordinal 5:
DWORD WINAPI SfcFileException(DWORD dwUnknown0, PWCHAR pwszFile, DWORD dwUnknown1);

dwUnknown0Unknown. Set to 0pwszFileFilenamedwUnknown1Unknown. Set to -1

The return value is 0 if success, or 1 if an error occurred (usually that the file is not protected by WFP).

An example call to this API is:
SetSfcFileException(0, L"c://windows//notepad.exe",-1);

Hack Method 4: Disable WFP permanently via patches and undocumented registry value

Priorto Windows 2000 SP1 there was an undocumented registry value that wouldfully disable WFP. This is the famous 0xffffff9d value I discoveredwhile reverse engineering SFC.DLL in Windows2000. Unfortunately, soonafter its discovery Microsoft disabled it. Fortunately, the core codeto disable WFP was left in SFC.DLL (later moved to SFC_OS.DLL).Therefore, a simple patch to SFC.DLL or SFC_OS.DLL will re-enable thisvalue. I've created patches for 2K and XP and have generalized thepatching procedure so the patch may be applied to all current and(hopefully) future versions of the SFC module without having to worryabout a specific patch address.

General patch procedure:

For Windows 2000, the patch is applied to SFC.DLL.
For Windows XP and 2003, the patch is applied to SFC_OS.DLL.

Copy the target file to a temporary one.

Search for the bytes '83 F8 9D 75 07 8B C6'.
Replace the '8B C6' with '90 90'.

You must correct the checksum of the image by using our PEChkSum utility. It can be obtained here.

Now set the temporary file to replace the original at boot-time by using our MoveLatr utility. It can be obtained here.

Set the SFCDisable value described below and then reboot the computer to complete the process.

Undocumented SFCDisable value:

Key: HKEY_LOCAL_MACHINE/Software/Policies/Microsoft/Windows NT/Windows File Protection
Value name: SFCDisable
Value: 0xFFFFFF9D

Hack Method 5: Disable WFP permanently for specific files via patching the protected file list

Moresimple than patching executable code is simply patching the list offiles contained in SFCFILES.DLL. First, copy SFCFILES.DLL to atemporary file. Using a hex editor (i.e. UltraEdit), search for filesto disable protection on inside the temporary file. Once found,replacing the first character of the file name with 0 (that is: value 0NOT ascii '0' character). After completing the modifications, correctthe checksum using our PEChkSum utility and set the temporary file to replace the original at boot-time using our MoveLatr utility. Reboot the computer to finish the process.

-Jeremy Collake
jeremy@bitsum.com

Like this article? Please feed me by donating to jeremy@bitsum.com via paypal ;).

The End



The following are original publications preserved for historical reasons, misc. technical details, or other useless stuff.
Stop reading here.


Appendix A: Original publication of undocumented registry setting to fully disable WFP
(no longer works without binary patches)



NTBugTraq Posting:

W2k undocumented registry setting fully disables Windows File Protection

From: Jeremy Collake (collake@CHARTER.NET)
Date: Sat Jun 24 2000 - 05:16:46 CDT

  • 6:13am 6/24

    Summary: Undocumented registry setting allows for
        Windows File Protection (aka System File Checker)
        to be fully disabled.

    HowTo: Set the SFCDisable value (see Q222473) to
       0xffffff9d.

    Ok, after spending 6 hours in the guts of sfc.dll, sfcfiles.dll,
    and winlogon.exe I have *finally* discovered how to permanently
    disable windows file protection. The more I dug into the internals
    of SFC, the more I began to think that it would not be as easy as
    I first thought it would be - and indeed Microsoft does not want it
    to be easy. Windows File Protection, while annoying, does provide
    a good degree of system stability and even some level of virus/trojan
    protection by preventing system files from being modified without
    at least notifying the user. Therefore, I was *very* shocked when
    I was looking through a disassembly of sfc.dll and came to the code
    that checks the value of the SfcDisable in the WinLogon key.
    I see in the code of ordinal 2 (which is the initialization function
    that winlogon calls), sticking out like a sore thumb, this:

    76986A89 push 1
    76986A8B cmp eax, ebx
    76986A8D pop esi
    76986A8E jz loc_76986B97
    76986A94 cmp eax, esi
    76986A96 jz loc_76986B7A
    76986A9C cmp eax, 2
    76986A9F jz loc_76986B69
    76986AA5 cmp eax, 3
    76986AA8 jz short loc_76986AE0
    76986AAA cmp eax, 4
    76986AAD jz short loc_76986ACF
    76986AAF cmp eax, 0FFFFFF9Dh
    76986AB2 push ebx
    76986AB3 jz loc_76986B86
    76986AB9 push offset byte_76981898
    76986ABE push edi
    76986ABF call sub_7698877D
    76986AC4 mov dword_769901D4, ebx
    76986ACA jmp loc_76986B97

    Ok, values 0, 1, 2, 3, and 4 are documented at
    http://support.microsoft.com/support/kb/articles/Q222/4/73.ASP , but
    what the heck is this 0ffffff9dh value that it accepts?! As you can
    see, any value other than 0,1,2,3,4 and 0ffffff9dh are assumed to be
    zero, which is the default of SFC enabled with popups enabled. So,
    without further delay, I went and plugged 0ffffff9dh into the SfcDisable
    value to see what was up. Rebooted. I'll be darned, Microsoft provided
    a very,very simple way to fully disable WFP!

    When booting with this value in the SFCDisable value in the WinLogon
    key (HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Winlogon), an
    event is written to the system log, ID 64032 from Windows File
    Protection, with the description:
    "Windows File Protection is not active on this system. ".

    All attempts to replace/delete protected system files succeeded,
    just as if I were in safe mode :). I rebooted a few more times and
    verified that it is the one value (other than 4=popus disabled) that
    is not reset to 0 after the first boot.

    Needless to say, this is not what Microsoft intended.

    Well, it's now 6am, hopefully I haven't mucked this up too much in
    my delerium.

    Jeremy Collake
    collake@charter.net
    http://www.collakesoftware.com



  • Appendix B: Original publication of binary patches to SFC.DLL or SFC_OS.DLL

     

    Binary Patches:

    Ifyou would like to re-enable the undocumented value to disable WindowsFile Protection, you may apply the appropriate patch and then replacethe DLL in the 2k/XP recovery console (boot to CD). Be sure to set thechecksum in the PE header by using Bitsum Technology's SetCSUM utilityafter patching.

    How to find the patch offset yourself for current and hopefully future version of SFC.DLL or SFC_OS.DLL:

    Search for the hex byte sequence: '83 F8 9D 75 07 8B C6' and replacethe '8B C6' with '90 90'. If more than one occurance of this sequenceis found, do not patch unless you know what you are doing. Email me at jeremy@bitsum.comfor more aid. Please do not email me with requests for instructions onhow to actually apply the patches listed here. They are intentionallykept technical to prevent layman modification of windows system fileswhich could result in an unbootable system, or worse.

    This patch changes the instruction 'mov eax,esi' to two 'nop's. At thislocation of execution when the undocumented registry value is given,eax holds 0ffffff9d and esi is 0. Therefore, this patch prevents eaxfrom being nullified before the switch on the registry value held ineax that follows.


    Windows2000 SP2:

    file:            SFC.DLL
    virtual offset: 76986C11
    physical offset: 6211
    original:        8BC6
    new:             9090

    Windows 2000 SP4:

    file:            SFC.DLL
    virtual offset: 76986CDB
    physical offset: 62DB
    original:        8BC6
    new:             9090


    WindowsXP:

    file:            SFC_OS.DLL
    virtual offset: 76C6EEB8
    physical offset: 0E2B8
    original:        8BC6
    new:             9090

    WindowsXP SP1:

    file:            SFC_OS.DLL
    virtual offset: 76C6EFBB
    physical offset: 0E3BB
    original:        8BC6
    new:             9090

    原创粉丝点击