gh0st源码分析
流程理解
客户端通过本地模板并写入信息生成服务端-install.exe 具体逻辑将提前放在.rdata中的dll取出,并注册服务在svchost下dll的内容是删去install.exe并且自行隐藏,然后取出加密后的ip解密,向客户端发送随机事件名,响应后根据发来的包决定转接哪个Manager,如FIle,Screen等
代码结构
1 | gh0st/ |
源码分析
客户端部分
从模板install.exe中生成服务端exe1 | void CBuildView::OnBuild() |
这里每次改动dll或者install.exe的时候都要按照svchost->install->gh0st的顺序全部重新编译,所以自己复现了一个直接凭借install.exe生成目标文件的代码
1 |
|
服务端部分
install
install的模板1 | __declspec(noinline) |
svchost
1 | DWORD WINAPI main(char *lpServiceName) |
刚注册进来 系统调用ServiceMain ServiceMain简单完善一下后续 然后开线程调用main
main将端口号解密出来 判断是否唯一 给自己提一个端口权限 然后重新注册一个服务 把install删了
后面把加密后的端口弄出来 然后先连随便一个网站 然后解密出来端口号等信息后面登录 在登录socketClient.Connect中 会有新线程产生 也就是工作线程
m_hWorkerThread = (HANDLE)MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WorkThread, (LPVOID)this, 0, NULL, true);
工作线程先接受socket 这里在没有发socket的时候会阻塞住 接受到之后就开始解析 具体逻辑还要往里进看OnRead
1 | WorkThread 堵塞等待接收socket |
这里的Manager取决与前文中登录后的
CKernelManager manager(&socketClient, strServiceName, g_dwServiceType, strKillEvent, lpszHost, dwPort);
socketClient.setManagerCallBack(&manager);
这里实现的便是设置Manager为KernelManager
所以这里调用的OnReceive就是分发Manager
1 | void CKernelManager::OnReceive(LPBYTE lpBuffer, UINT nSize) |
FileManager
1 | void CFileManager::OnReceive(LPBYTE lpBuffer, UINT nSize) |
这里的收到的包基本都是路径 进行的操作其实也就是找到路径对应的管理 然后进行操作就成
ScreenManager
1 | void CScreenManager::OnReceive(LPBYTE lpBuffer, UINT nSize) |