科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件利用钩子技术控制进程创建(附源代码)

利用钩子技术控制进程创建(附源代码)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文大胆假设,目标进程是以一种用户模式(外壳函数,CreateProcess(),用一系列的本机API调用的手工的进程创建,等等)创建的。

作者:朱先忠编译 来源:天极网 2007年10月17日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
check()函数是怎样做出决定的?一旦它收到一个指向服务参数的指针参数,它就可以检查这些参数。首先,它检查标志和属性-如果有一部分没有被要求作为一个可执行映像映射,或如果要求的页面保护不允许执行,那么我们可以确定NtCreateSection()调用与进程创建毫无关系。在这种情况下,check()直接返回TRUE。否则,它将检查该潜在文件的扩展-毕竟,SEC_IMAGE属性和允许执行的页面保护可能被要求来映射某个DLL文件。如果该潜在文件不是一个.exe文件,那么,check()将返回TRUE。否则,它给用户模式代码一个作出决定的机会。因此,它仅把文件名和路径写到交换缓冲区,并且对它循环查询,直到它得到响应为止。

  在打开我们的驱动程序前,我们的应用程序创建一个运行下面函数的线程:

void thread()
{
 DWORD a,x; char msgbuff[512];
 while(1)
 {
  memmove(&a,&outputbuff[0],4);
  //如果什么也没有,Sleep() 10毫秒并再检查
  if(!a){Sleep(10);continue;}
  //看起来象我们的权限被询问。
  //如果被怀疑的文件已经存在于空白列表中,
  // 则给出一个积极的响应。
  char*name=(char*)&outputbuff[8];
  for(x=0;x<stringcount;x++)
  {
   if(!stricmp(name,strings[x])){a=1;goto skip;}
  }
  //要求用户允许运行该程序
  strcpy(msgbuff, "Do you want to run ");
  strcat(msgbuff,&outputbuff[8]);
  //如果用户的答复是积极的,那么把这个程序添加到空白列表中
  if(IDYES==MessageBox(0, msgbuff,"WARNING",MB_YESNO|MB_ICONQUESTION|0x00200000L))
   {a=1; strings[stringcount]=_strdup(name);stringcount++;}
  else a=0;
  // 把响应写入缓冲区中,而由驱动程序之后取回它
  skip:memmove(&outputbuff[4],&a,4);
  //告诉驱动程序继续
  a=0;
  memmove(&outputbuff[0],&a,4);
 }
}

  这段代码是显然的-我们的线程每10毫秒查询交换缓冲区。如果它发现我们的驱动程序已经把它的请求寄到了该缓冲区中,它就检查被允许在本机上运行的程序列表中的文件的文件名和路径。如果发现匹配,它直接给出一个OK响应。否则,它显示一个消息窗口,询问用户是否允许有问题的程序执行。如果响应是积极的,我们就把有问题的程序添加到允许在本机上运行的软件列表中。最后,我们把用户响应写入缓冲区,也就是说,把它传递到我们的驱动程序。因此,该用户就能完全控制它的PC上的进程的创建-只要我们的程序运行,在没有用户所给予权限的情况下,绝对没有办法来启动该PC上的任何进程。

  正如你所见,我们让内核方式代码等待用户反应。这是否是一种聪明的举措呢?为了回答这个问题,你必须问你自己你是否正在堵住任何关键的系统资源-一切都依赖于具体的情况。在我们的情况下,一切发生在IRQLPASSIVE_LEVEL级上,并没有包含对IRPs的处理,并且必须等待用户响应的线程并不十分重要。因此,在我们的情况下,一切工作正常。然而,本例仅为演示之目的而编写。为了实际地使用它,以一个自动启动的服务的方式来重写我们的应用程序是很重要的。在这种情况下,我建议我们解除LocalSystem帐户,并且,在NtCreateSection()被用LocalSystem帐户特权在一个线程的上下文中调用的情况下,可以继续实际的服务实现而不施行任何检查-不管怎么说,LocalSystem帐户仅运行那些在注册表中指定的可执行程序。因此,这样的一种解除不会是与我们的安全相妥协的。

  四、 结论

  最后,我必须指出,钩住本机API很明显是现已存在的最强有力的编程技术之一。本文通过一个例子向你展示通过钩住本机API可以实现的能力-正如你所见,我们已设法防止未被授权的程序的执行-这可以通过钩住单一的本机API函数来实现。你可以进一步扩展这个方法,并且获得对硬件设备、文件IO操作、网络流量等等的完全控制。然而,我们现在的解决方案并不是准备为内核模式API调用者所用-一旦内核模式代码被允许直接调用ntoskrnl.exe的输出,则这些调用就不需要经由系统服务发送者进行了。

  本文源码在运行Windows XP SP2的若干机器上成功地测试过。尽管我还没在任何另外的环境下面测试它,我相信它应该到处工作正常-不管怎么说,它从未使用任何系统特定的结构。为了运行这个示例,所有你要做的是放置protector.exe和protector.sys到相同的目录下,并且运行protector.exe。直到protector.exe的应用程序窗口被关闭为止;否则,每次你都会被提示你试图运行任何可执行程序。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章