我担心有人利用木马对我的机器进程进行线程注入。
我现在看到的有两种情况:一是注入DLL,我可以通过在进程中查找DLL名找到;二是直接注入线程,这种情况我考虑可以通过Hook这个  CreateRemoteThread函数来发现。不知各位还有没有发现其他的注入远程线程的情况,以及相应的解决办法呢?
谢谢大虾们!

解决方案 »

  1.   

    你担心自己的进程被注入线程,那么由两种方法可以用来防范:1 监测。简单说,就是用另外一个程序来监测你的进程,采用快照的办法枚举它的所有模块,一旦发现有了不应当有的模块,立刻终止这个非法模块。2 自我保护。可以通过设置本进程的DACL,阻止任何用户(升了级的系统管理员除外)在本进程中执行CreateRemoteThread这个API,或者干脆拒绝一切形式的OpenProcess访问。
      

  2.   

    并不是我设计程序的进程,而我的window系统的所有进程。我担心的是所有进程都
    有可能被远程植入。
    请主要回答我问的问题,即我列出的两种情况是不是远程注入线程的唯一两种情况?
      

  3.   

    谢谢lianglp,请问:利用缓冲区溢出,也是溢出后执行一段代码,这段代码不用执行createremotethread就
    可以植入线程么?那我怎么能发现呢?这两点我不太明白,可能问的很初级,请不要介意。
      

  4.   

    缓冲区益出相对远程插入线程较复杂很多。
    一般情况它利用函数返回地址特征自动调用目标地址,这样就可以在目标地址中创建
    线程便开始执行。如果这种情况,可以HOOK创建线程函数来判断地址是否为自己模块内的
    地址;如果返回到目标地址中时就执行操作而不返回原来函数地址,就根本没有办法知道。实际上这种技术复杂性不是在于这种情况,而是在什么地方找到缓冲区益出以及写
    入返回地址值。
      

  5.   

    lianglp() :我并不是要检查我自己的进程里有没有被别人注入线程,而是我的整个windows系统
    有没有被人进入。所以我hook创建线程函数,可否判断window系统的所有进程有没有
    被人试图注入线程么?可否联系一下,希望和你交流一下。
     
    我的QQ是14521770,愿意的话留一下你的QQ或直接和我联系
      

  6.   

    关注!
    ------------------------------------
    体验速度,体验CSDN新版论坛助手:http://community.csdn.net/Expert/TopicView.asp?id=3108679
      

  7.   

    lianglp:   对不起,你的QQ号在我单位机器里,我家里的QQ不知为何不显示你的名字,我无法在周六上午找到你,希望见谅!
      

  8.   

    直接注入线程的方法多了,光hook CreateRemoteThread 是不够的
      

  9.   

    可是不通过CreateRemoteThread也可以create remote thread的,所以……很难防的!
      

  10.   

    关注,另外,fzd999(花差花差) ,你说到“立刻终止这个非法模块。”,请问如何终止一个模块呢?FreeLibrary吗?这样对进程是否有影响呢?
      

  11.   

    是不是这种情况你没有考虑:
    我在B进程里用VirtualAllocEx在A里分配一块可执行内存区,当然进行复制等的操作忽略掉不写了,然后我修改进程A的IVT表,Hook一个关键函数来指向我刚才分配的内存?这个方式很久以前我就实现了,你依靠上面的两种方式是不能看到的,虽然不是远程线程,但是效果一个样
      

  12.   

    TO jozu(jozu) 
    能否给各代码看看?
      

  13.   

    整个windows注入?乖乖,想注入ring0的系统线程?不得了哈。
      

  14.   

    防范rootkit入侵可以采用很多方法,并且没有哪个呆瓜会用什么“整个Windows注入”的方法。累,且显眼。
      

  15.   

    首先我们以rootkit中所使用的技术,将其分为两类:
    *通过更改系统结构来隐藏某对象的(如运行的进程)和
    *更改内核执行路径(例:勾连那些负责枚举活动进程的内核函数)来达到同样目的的.--更改系统数据结构的rootkit这类的rootkit不太多.有意思的例子包括fu rootkit(见[3]),通过删除内核中PsActiveProcessList链上的进程对象来隐藏进程. ZwQuerySystemInformation等函数是不能发现这些隐藏进程的.但同时,因为Windows的线程分派器(dispatcher, scheduler)使用另外的数据结构,这些"隐藏"进程仍可运行(被分配到CPU使用时间).Windows的线程分派器使用以下三个(注1)数据结构:*pKiDispatcherReadyListHead
    *pKiWaitInListHead
    *pKiWaitOutListHead后两个是处于"等待"状态的线程链头.他们之间稍有不同,但对我们来说并不重要.从上面的信息我们可以找到一种检测隐藏进程的方法.及读取线程分派器使用的数据结构,而不是PsActiveProcessList.当检测rootkit时我们应该尽可能的触及更底层的内核数据结构.有一点应该注意,直接从线程分派器使用的链中删除要隐藏的进程是不可能的,因为隐藏的进程将分配不到CPU使用时间.--更改执行路径的rootkit这类的rootkit较为普及.他们通过修改或增加内核或系统DLL中的指令来达到目的.检测这类rootkit的问题是,我们不知道rootkit在什么地方做了那些修改.它可以勾连DLL中的函数,系统服务列表(System Service Table),改变内核函数的内容或修改内核中一些奇怪的函数指针.--执行路径分析(Execution Path Analysis)EPA关注这样一个事实:如果入侵者通过修改执行路径隐藏了一些对象,那么当调用一些典型的系统和库的函数时,系统将运行一些多余的指令.举个例子,如果入侵者为了隐藏文件和进程而修改了ZwQueryDirectoryFile()和ZwQuerySysteminformation (),那样和干净的系统相比,这些系统函数就会执行更多的指令.不管入侵者采用勾连或在代码中加入jmp指令,或其他任何方法.指令增加的原因是 rootkit必须进行它的任务(在这个例子中是隐藏文件和进程).但是Windows 2000的内核是一个非常复杂的程序,即使在干净的系统中,某些系统函数每次运行的指令个数也是不同的.然而我们可以用统计学来解决这个问题.但首先,我们需要一种测定指令个数的方法......--指令计数器的实现单步执行模式是Intel处理器的一个好的特性,我们可以用它来实现指令计数.当处理器处在这个模式时,每执行完一条指令,系统将产生一个除错异常(debug exception, #DB).要进入这个模式,需要设置EFLAGS寄存器中的TF位(详见[6]).当执行int指令时,处理器会自动清TF位并进行权限切换.这意味着,如果要进行内核模式下的指令计数,则必须在中断处理程序开头设置TF位.因为我们将要测定一些系统服务中的指令个数,勾连中断向量0x2e,也就是Windows 2000下的系统服务调用门会变得很有效.但是,因为存在用户模式的rootkit,也应该测定在ring3级运行的指令个数.只要在用户模式下设置TF位一次就可以了,从内核返回时,处理器会自动恢复这一位.以上的计数方法通过内核驱动器实现.如图2所示,驱动加载后勾连IDT 0x1和0x2e.为和用户级程序交互.驱动勾连一个系统调用,用户级程序通过这个特定的系统调用来开关计数器.--一些测试我们可以使用上一段中描述的方法来测定任意系统服务中执行的指令个数.例如,来检查是否有人试图隐藏任意文件,我们可以开始一个简单的测试:pfStart();
    FindFirstFile("C:\\WINNT\\system32\\drivers", &FindFileData);
    int res = pfStop();如果有rootkit隐藏任意文件,则执行的指令数要比干净的系统多.如果运行这个测试上百次,并计算执行指令数的平均值,我们会发现这个值是非常不确定的.考虑Win2k的复杂性,这一点也不让人吃惊.但对于我们的检测目的来说,这种现象是不能接受的.但如果我们将得到的那些值的频率分布用条形图表示出来,会发现图中有一个明显的频率高点.如图4和5中所表示那样的,即使是在系统负载很大时,频率高点所对应的数值保持不变.很难解释这个令人吃惊的现象,可能是因为在循环中同一个系统服务被调用几百次后,与这个系统服务相关的缓冲最后会被填入固定的值.假想现在有人安装了隐藏文件的rootkit,如果我们重复测试并绘制相应的条形图,就会发现频率高点向右移了,这是因为rootkit需要进行隐藏文件的工作.在现在的代码实现中,只进行了少量的测试,包括典型的服务如:文件系统读取,枚举进程,枚举注册表项以及Socket读取.这些测试将有效地检测出著名的NTRootkit(见[1]),或最近比较流行的Hacker Defender(见[4]),包括它自带的网络后门,当然还包括很多其他的后门.但要检测出一些更好的后门还要加入一些新的测试.--误报和执行路径跟踪虽然对频率高点的检测有助于我们处理系统的不确定因素,但有时会发现测试得到的值有小的差值,一般来说不大于20.有时这会是一个很严重的问题,因为我们不能确定那些多出来的指令意味着被入侵或只是正常的误差.为解决这个问题,我们使用了执行路径记录模式.和单一的EPA模式比较,系统增加了对执行路径的记录(包括地址和运行的指令),首先,系统记录下正常情况下的执行路径,以后的每一次运行将产生diff文件(正常系统和现行系统之间的比较).我们应该使用好的反编译器来分析那些不一样的地方,以此判定他们是否可疑.图6是一个diff文件的例子.现阶段的diff文件只记录下指令的地址,以后可能将两次测试的不同结果存为PE格式文件,并可用IDA等工具分析.--检测 ”offset-in-the-code” 的变化想象有这样一个rootkit,它基本和上面提到的 fu rootkit (见[3]) 一样,但不从PsActiveProcessList中,而是从分派器使用的数据结构中移除进程.我说过那不可能,因为隐藏的进程将分配不到运行时间......然而,rootkit可以同时更改分派器代码中所使用数据结构的地址(offset),换句话说,就是使其使用不同的链表.但只有分派器使用这个”新的” 链表,而系统其他地方还是使用”旧的”链表...... (见图7).虽然这种技术不会改变执行指令的个数,我们还是能检测到它,但需要进一步的完善现有的工具.这项功能现在还没有实现,但应该不是很难.--针对EPA的攻防我们可以想到一些能骗过EPA类检测工具的方法,先把它们分为两类.
    1. 针对特定工具的欺骗
    2. 对EPA类技术的通用攻击首先,我们考虑一下通用的攻击方法和怎样防止这类攻击.接着讨论针对特定工具的攻击以及怎样通过多态来预防.--对EPA类技术的通用攻击首先,恶意程序可以勾连包含除错处理程序(debug handler)地址的IDT入口1,这样将暂停记录运行的指令数.当它完成工作时,再恢复 IDT入口1.这样rootkit中所执行的指令数不会被记录.我们可以使用intel的除错寄存器来防止这类的攻击.可以使用DR0和DR1寄存器对IDT入口1进行写保护.并且为防止rootkit向除错处理程序的开始处写入Jmp指令,还需对其进行读保护.换句话说,我们不想让rootkit发现除错处理程序的地址.但单纯对IDT入口进行读保护是不行的,系统会蓝屏.但有一简单的解决方法,就是增加额外的一层.见图9.还有一种攻击的方法,在rootkit运行时,其将TF位清零,并在恶意操作完成时恢复TF位,这样检测工具也只能发现运行的指令数和正常的系统有细微差别.另外,rootkit还能检查TF位, 如发现被跟踪,则不进行恶意操作.这种行为并不会影响rootkit的正常工作,因为只有被检测的进程才被设置TF位.我们可以防止这种攻击,应该注意到的是运行每一个系统指令前,都会运行我们的除错处理程序.以下是简单的防预方法:如果除错处理程序发现上一个运行指令是pushf(将EFLAGS寄存器压入堆栈),则运行如下操作.and [esp], 0xfffffeff;及清TF位.同样,如果下一条指令是popf(从堆栈载入EFLAGS的值),则运行如下操作.or [esp],0x100;及设TF位.这样rootkit就不能更改TF位.这样的预防几乎可够了,但还不充分.Rootkit仍能以以下方法发现其被跟踪:setTFbit();
    if (checkTFbit()!=1) {
        //we are traced!
    }所以我们需要更改反检测部分的操作,使其可以记录TF位有没有被rootkit更改(比如增加一个TFbitset变量).popf/pushf不是存取EFLAGS寄存器的唯一指令,其它像iret/int等指令也可以[注2],因此还要加入对这些指令的检测.对EGLAGS寄存器的防护部分还没有被实现.一部分原因是通过对diff文件的分析也可以发现这类攻击.但以后会增加相应代码.--对特定工具的攻击如果攻击者了解关于特定检测工具的一切,他会有很多种欺骗的手段.比如,可以更改保存指令数的那个变量.不过这类攻击具有很强的针对性,如果有很多不同(或非单一版本)的EPA类工具,这样的攻击将不会有效.当然,我们还是希望可以阻止这类攻击,强大的多态代码生成器可能是唯一的方法.当管理员安装检测工具是,会产生一个独特的内核驱动和测试程序.多态代码生成器部分还没有被实现.--相关工作像文章开头所述,笔者还没有发现任何对rootkit的检测方法,不是基于存储扫描的.EPA技术并不被OS所局限,笔者在linux下也实现了一相关工具,参5中有对其的详述以及简单的代码实现.
      

  16.   

    不论是什么办法注入,总归就是要让目标进程运行这个代码就好说了,比如说可以先VirtualAllocEx分配目标进程的内存,然后在里面写入代码WriteProcessMemory,这些代码可以做任何你想做的事情,然后查找一个肯定要运行的函数,比如说SendMessage什么的(很多窗口函数都会调用SendMessage来设置或者获取窗口状态),然后改写SendMessage的代码,让他转到你分配的内存里面去,然后做你想做的事,然后再让他跳回来,这样别人根本还不知道发生了什么,你就已经在里面做了你想做的事情了
      

  17.   

    EPA也只是简单的进行统计分析而已,它并不会智能得区分代码是善意或是恶意,难保不会误判.
      

  18.   

    请问 codewarrior(会思考的草)"通过删除内核中PsActiveProcessList链上的进程对象来隐藏进程"怎么实现呀?
      

  19.   

    写个Driver,从ntoskrnl中导入PsActiveProcessList,这是一个双向链表,在上面删除属于你的进程对象的节点