病毒木马常用手段之自我创建
2023-1-1 18:4:53 Author: 看雪学苑(查看原文) 阅读量:19 收藏


本文为看雪论坛优秀文章

看雪论坛作者ID:寒江独钓_

在分析样本时,我们会遇到各种骚操作,自我创建就是其中一种,简而言之就是将自身作为子进程运行,并且以子进程运行时会有不同的动作,如套娃创建子进程,执行shellcode等等。虽然这种手段并没有多么高明,但是在实际情况中常常会遇到,调试起来也比较麻烦,而且在真实环境中往往会更加复杂,所以掌握各种奇淫巧计是我等“杀人越货,行走江湖”必不可少的功夫,废话少说,开始开始实战!

一、编译源码

程序源代码如下:
//子进程要执行的代码void ChildProc(){    MessageBox(NULL, L"This is a child process!", L"DebugMe2", MB_OK);     ExitProcess(0);} //主函数void _tmain(int argc, TCHAR *argv[]){    TCHAR                   szPath[MAX_PATH] = { 0, };    STARTUPINFO                si = { sizeof(STARTUPINFO), };    PROCESS_INFORMATION        pi = { 0, };    CONTEXT                 ctx = { 0, };     _tprintf(L"This is a parent process!\n");     if (!GetModuleFileName(NULL, szPath, sizeof(TCHAR) * MAX_PATH))    {        printf("GetModuleFileName() failed! [%d]\n", GetLastError());        return;    }     // 创建子进程    if (!CreateProcess(        szPath,        NULL,        NULL,        NULL,        FALSE,        CREATE_SUSPENDED,        NULL,        NULL,        &si,        &pi))    {        printf("CreateProcess() failed! [%d]\n", GetLastError());        return;    }     // 修改EIP    ctx.ContextFlags = CONTEXT_FULL;    if (!GetThreadContext(pi.hThread, &ctx))    {        printf("GetThreadContext() failed! [%d]\n", GetLastError());        return;    }     ctx.Eip = (DWORD)ChildProc;     if (!SetThreadContext(pi.hThread, &ctx))    {        printf("SetThreadContext() failed! [%d]\n", GetLastError());        return;    }     // 恢复线程    if (-1 == ResumeThread(pi.hThread))    {        printf("ResumeThread() failed! [%d]\n", GetLastError());        return;    }     //等待返回    WaitForSingleObject(pi.hProcess, INFINITE);     CloseHandle(pi.hProcess);    CloseHandle(pi.hThread);}

二、程序编译好以后,我们使用OD进行调试分析

根据特征找到main函数,我的是VS2013编译的,你的特征可能和我的不一样 !

调用CreateProcessW以挂起方式创建子进程。
可以看到目前子进程处于挂起状态。
使用GetThreadContext获取子进程的主线程的CONTEXT结构体。

修改子进程的主线程的CONTEXT结构体中的EIP的值为ChildProc,然后调用SetThreadContext进行设置。
恢复子进程的主线程。
调用WaitForSingleObject进入等待状态直到子进程运行完毕。

点击确定后子程序结束运行并返回。
假如我们想要调试ChildProc函数,有很多方法可以用,比如在OD中直接将EIP的值设置为ChildProc的起始地址,或者将PE文件的EntryPoint修改为ChildProc的起始地址,但是很多时候,以上两种方法并不管用,除此之外还有一种方法,就是使用OD的实时调试模式。

三、实时调试模式

1、设置OD为实时调试模式

2、将虚拟地址00171000(ChildProc函数在内存的位置)转换为文件偏移地址(在文件中的位置)

得到的结果为400。
使用十六进制编辑器将对应的位置修改为CC并保存,如下图:
修改前

修改并保存
再次使用OD调试,在ResumeThread处下断点,单步步过。
因为OD已经被设置为实时调试器,所以当有异常触发时,会被系统自动调用,并将其附加到对应的进程上,此时就可以开始调试了,最后别忘了把CC恢复为原代码(0x6A)(Crtl+E快捷键),然后就可以愉快的调试啦!

四、总结

自我创建技术在病毒木马等恶意软件中非常常见,经常借助该技术躲避安全软件查杀,为了方便演示,所以示例程序比较简单,但是掌握各种调试技巧,在遇到复杂的程序时才能游刃有余,手到擒来!

看雪ID:寒江独钓_

https://bbs.pediy.com/user-home-941725.htm

*本文由看雪论坛 寒江独钓_ 原创,转载请注明来自看雪社区

# 往期推荐

1.CVE-2022-21882提权漏洞学习笔记

2.wibu证书 - 初探

3.win10 1909逆向之APIC中断和实验

4.EMET下EAF机制分析以及模拟实现

5.sql注入学习分享

6.V8 Array.prototype.concat函数出现过的issues和他们的POC们

球分享

球点赞

球在看

点击“阅读原文”,了解更多!


文章来源: http://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458489700&idx=1&sn=5edec580941254214fcbf5f6aa764c4b&chksm=b18ea3ee86f92af897fb74de629d24a911daf078576a434b954c96816997772795a386b9cf2b#rd
如有侵权请联系:admin#unsafe.sh