
분할 정복 방식을 적용하여 EDR을 우회합니다.
Divide and Conquer(분할 정복)은 복잡한 문제를 더 단순한 하위 문제들로 나누어 해결하기 위해 프로그래밍에서 흔히 적용되는 알고리즘입니다. 우리는 이 접근 방식을 공격 보안(offensive security)에 다른 목적으로 적용할 수 있습니다: EDR을 혼란스럽게 만들어 우리의 활동을 추적하지 못하게 하고, 어떤 알림도 발생시키지 못하게 하는 것입니다. 이는 최근 야생에서 발견되는 거의 모든 피싱 캠페인에서 볼 수 있는 것과 유사합니다: 최종 페이로드를 직접 실행하는 대신 긴 감염 체인을 만들어 여러 파일을 단계별로 실행하는 방식(예: .url -> .one -> .js -> .bat -> .dll)입니다. 실행되는 각 파일은 그 자체만으로는 악성으로 분류하기 어려운 단순한 작업(다른 파일 다운로드, 레지스트리 변경, 디렉터리 간 파일 이동 또는 이름/확장자 변경 등)을 수행하여 최종 실행을 위한 환경을 준비합니다.
저는 이 간단한 아이디어를 다른 것에 적용하여 테스트하기로 결정했습니다. 이 경우에는 원격 프로세스 인젝션(remote process injection)입니다. 이 저장소에 제시된 코드는 새로운 것이 전혀 아닙니다. 오히려 원격 프로세스에 셸코드를 인젝션하는 가장 일반적이고 직관적인 방법 중 하나일 것입니다: NtOpenProcess, NtAllocateVirtualMemory, NtWriteVirtualMemory, NtProtectVirtualMemory 및 NtCreateThreadEx를 사용하는 것입니다. 유일한 차이점은 이러한 호출 각각 후에 NtCreateUserProcess를 사용하여 프로세스를 포크(fork)한다는 점입니다. 포크된 프로세스는 RIP + 1부터 실행을 계속하고 메모리가 부모 프로세스에서 완전히 복사되므로, 5개의 서로 다른 프로세스를 사용하여 원격 프로세스 인젝션을 수행할 수 있습니다. 후속 API 호출에 필요한 모든 핸들이 올바르게 상속되도록만 하면 됩니다.
이런 식으로 셸코드 인젝션 절차를 더 단순한 작업들로 나누고, 각각을 분리된 컨텍스트(프로세스)에서 실행합니다.
저는 이 PoC를 현재 가장 널리 사용되는 세 가지 EDR(MDE, CrowdStrike, SentinelOne)을 대상으로 테스트했습니다. 결과는 그 자체로 설명합니다: 포크 없이 PoC를 실행했을 때는 3개 중 2개 EDR이 원격 프로세스 인젝션 알림을 발생시켰지만, 포킹 메커니즘을 도입한 후에는 어느 EDR도 알림을 발생시키지 않았습니다.
물론, 포크 메커니즘을 사용하더라도 원시 텔레메트리(raw telemetry)에서 프로세스 생성, 스레드 생성, 그리고 모든 교차 프로세스 동작에 해당하는 이벤트를 볼 수 있습니다. 하지만 EDR이 해당 활동을 악성으로 분류하기에는 충분하지 않은 것 같으며, 이것이 이 PoC의 요점을 증명합니다. 악성 행위를 더 단순한 작업들로 나누고 각 작업을 서로 다른 프로세스에서 실행함으로써 EDR을 혼란스럽게 만들어 어떤 알림도 발생시키지 못하게 할 수 있습니다.
이와 동일한 결과는 다른 방식으로도 달성할 수 있습니다. 저는 코드를 단순화하고 교차 프로세스 활동을 줄이기 위해 포크 메커니즘을 사용했을 뿐입니다.
직접 테스트해 보려면 fork() 함수 호출이 포함된 코드와 포함되지 않은 코드를 컴파일한 다음, 원하는 EDR이 있는 환경에서 두 페이로드를 모두 실행하세요.
문자열 리터럴을 난독화하기 위해 LITCRYPT 플러그인을 사용하고 있으므로(Dinvoke_rs 코드에만 해당), 코드를 컴파일하기 전에 환경 변수 LITCRYPT_ENCRYPT_KEY를 설정해야 합니다:
C:\Users\User\Desktop\Split> set LITCRYPT_ENCRYPT_KEY="yoursupersecretkey"
그런 다음 코드를 컴파일하고 도구를 실행하기만 하면 됩니다:
C:\Users\User\Desktop\Split> cargo build --release
C:\Users\User\Desktop\Split\target\release> split.exe -h
이 기술만으로는 EDR을 우회하기에 충분하지 않습니다. 코드가 전혀 opsec적이지 않다면 어차피 발각될 가능성이 매우 높습니다. 이것은 만능 해결책이 아니라 도구에 추가할 수 있는 또 하나의 회피 계층일 뿐입니다. 그럼에도 불구하고 이 저장소에 제시된 코드는 다음과 같은 이유를 포함하여 전혀 opsec적이지 않습니다:
한편, 저는 언급된 EDR들을 대상으로만 이 접근 방식을 테스트했으며, 다른 EDR도 함께 우회될 수 있을지는 알 수 없습니다. 직접 테스트해보고 결과가 어땠는지 알려주세요 ;)