Amadey 악성코드: 정적 탐지 vs 메모리 기반 탐지 비교 연구
- Open (new tab):
/files/Memory_Reveals_Truth.pdf
PDF가 보이지 않으면 여기로 열어보세요:
/files/Memory_Reveals_Truth.pdf
관련 영상
정적 탐지와 메모리 기반 탐지의 구조적 차이
정적 탐지는 디스크에 존재하는 악성코드 파일 자체를 분석하여 알려진 패턴이나 서명으로 식별하는 기법입니다. 예를 들어 바이러스 백신은 악성 바이너리의 고유 바이트 서명이나 문자열을 데이터베이스와 대조하여 탐지합니다. 그러나 Amadey와 같은 현대 악성코드는 이러한 정적 서명 탐지를 우회하기 위해 파일을 암호화하거나 난독화합니다. Amadey의 경우 악성 페이로드 내 문자열들을 2중으로 인코딩(사용자 정의 인코딩 + Base64) 하여 정적 분석과 탐지를 어렵게 만듭니다[1]. 이처럼 정적 탐지는 패커(packer)나 암호화로 감싸진 악성코드에 취약하며, 파일 해시나 고정 서명에 의존하므로 폴리모픽(polymorphic) 변종들을 잡아내기 어렵습니다[2][3]. 실제로 Amadey는 다양한 난독화 및 MaaS 형태로 유포되며, 표면적인 파일 해시나 특정 문자열 서명만으로는 변종을 놓칠 수 있습니다.
반면 메모리 기반 탐지는 실행 중인 프로세스의 메모리를 직접 스캔하여 악성 행위를 식별하는 기법입니다. 이는 악성코드가 실행되면서 자신을 복호화하거나 다른 프로세스에 로드할 때 드러나는 실제 페이로드를 포착합니다. 예를 들어 폴리모픽 악성코드는 실행 시 결국 메모리상에 복호화된 코드로 나타나기 때문에, 메모리 포렌식 분석을 통해 난독화를 우회하고 본질적 악성 코드를 확인할 수 있습니다[4]. 또한 메모리 탐지는 코드 인젝션이나 프로세스 할로잉(process hollowing) 같은 기법도 잡아낼 수 있습니다. 예를 들어 악성코드가 합법적 프로세스를 생성한 뒤 그 메모리를 악성 코드로 덮어씌우면(프로세스 할로잉), 디스크 상에는 정상 파일만 존재하므로 정적 탐지가 불가능합니다. 그러나 메모리 기반 탐지에서는 프로세스의 메모리 이미지와 디스크 이미지를 비교하여 불일치를 발견함으로써 이러한 메모리 내 코드 대체 흔적을 탐지할 수 있습니다[5]. 즉, 정적 탐지가 **“파일이 어떻게 생겼는가”**에 초점을 둔다면, 메모리 탐지는 **“프로세스가 실제 무엇을 하고 있는가”**에 주목하여 런타임의 악성 행위를 밝혀냅니다[4][6].
요약하면, 정적 탐지는 속도와 효율은 높지만 패킹/난독화에 취약하며, 메모리 탐지는 리소스가 더 들지만 실행 시 드러나는 실제 악성코드를 포착하여 우회당하기 어렵다는 구조적 차이가 있습니다. 특히 파일을 메모리에 풀어 실행하는 로더/드로퍼 계열 악성코드(예: Amadey, SmokeLoader 등)에 대해서는 메모리 기반 접근이 훨씬 효과적입니다[4].
메모리 상의 실행 Invariant와 회피 어려움
악성코드가 **메모리상에서 드러내는 “실행 invariant(불변 특징)”**이란, 다양한 변종이나 난독화 방식에도 불구하고 악성 행위를 위해서는 어쩔 수 없이 지켜야 하는 핵심 코드나 데이터 패턴을 의미합니다. 이는 일종의 공통된 알고리즘적 서명으로, 공격자가 파일 단에서는 바꾸더라도 실행 단계에서 결국 나타날 수밖에 없는 특징입니다. Amadey 사례를 보면, 이 악성코드는 명령어 문자열을 복호화한 뒤 C2 통신 등에 사용하는데, 복호화 키로 사용되는 다수의 32글자 길이의 고정 HEX 문자열들이 메모리에 나타납니다[7]. 심지어 Amadey 바이너리에는 개발 당시 경로로 추정되는 “\Amadey\Release\Amadey.pdb” 문자열이 남아 있었는데, 이는 변종이 재패킹되어도 메모리에 로드되면 드러날 수 있는 흔적입니다[8]. 정적 탐지 단계에서 이들은 암호화되어 감춰져 있지만, 실행 시에는 반드시 복호화되어 사용되므로 메모리에서 포착이 가능합니다.
이러한 실행 중 불변 패턴은 공격자가 임의로 바꾸기 어려운 근본적 동작을 반영합니다[9]. 예를 들어 랜섬웨어를 생각하면, 아무리 코드 구조를 바꿔도 파일 암호화 루틴과 복호화 키 출력이라는 기능 자체는 invariant로 남습니다[9]. 마찬가지로 정보탈취형 악성코드는 브라우저 쿠키나 계정 정보를 훔쳐야 하므로 “cookies.sqlite” 같은 브라우저 데이터베이스 경로나 **“installedBrowsers”**와 같은 키워드가 메모리에 나타날 수밖에 없습니다[10]. RedLine 스틸러의 한 변종을 메모리 분석한 결과, DownloadAndExecuteUpdate, StringDecrypt, ChromeGetRoamingName, SystemInfoHelper와 같이 기능을 나타내는 문자열들이 공통적으로 확인되었는데[10], 이는 해당 악성행위(업데이트 다운로드 실행, 문자열 복호화, 크롬 데이터 경로 사용, 시스템 정보수집 등)가 변종 간 일관되게 수행됨을 의미합니다. 공격자가 이러한 핵심 로직을 매번 완전히 새로 작성하지 않는 한, 이들 문자열과 API 호출 패턴은 메모리상에 계속 나타나므로 탐지에 활용할 수 있습니다.
공격자가 이러한 실행 invariant를 회피하기 어려운 이유는 크게 두 가지입니다. 첫째, 기능 유지의 제약 때문입니다. 악성코드가 목표로 하는 동작(예컨대 Amadey의 시스템 정보 수집 및 C2 통신)은 변하지 않으므로, 해당 기능을 구현하는 핵심 코드 구조나 데이터는 일정 부분 공통으로 남을 수밖에 없습니다[9]. 둘째, 회피를 위한 비용 부담이 큽니다. 만약 공격자가 메모리 invariant 자체를 제거하려면, 메타모픽(metamorphic) 기법처럼 코드를 실행 때마다 의미가하게 완전 변형하거나 JIT 컴파일/인터프리터 방식으로 실시간 생성해야 합니다[11][12]. 그러나 이러한 기법은 개발 난이도가 극도로 높고, 실행 시 성능 오버헤드도 발생합니다. 예를 들어 동일한 두 숫자 덧셈도 매 번 무작위로 다른 방식으로 구현하거나, 코드를 실행 직전에 해독했다 다시 암호화하는 식으로 동작하려면 시스템 리소스를 소모하고 오류 가능성도 높아집니다[13]. 일반적인 악성코드는 그렇게까지 복잡한 엔진을 탑재하지 않으며, MaaS 형태로 빠르게 배포되는 Amadey나 RedLine 등의 사례에서는 개발 효율성을 위해 오히려 코어 로직을 재사용하는 경향이 있습니다. 실제로 Emotet 같은 금융 트로잔도 매일 수천 변종이 생성되지만 행위 패턴은 유사했고, 폴리모픽 패킹만 활용했을 뿐 페이로드 내부 로직은 장기간 유지된 바 있습니다[3][14]. 요컨대 Invariant를 완전히 제거하려는 시도는 공격자에게 득보다 실이 크기 때문에, 변종이 거듭되어도 일정한 메모리 패턴이 남게 되고, 이는 방어자가 장기적인 탐지 포인트로 활용할 수 있습니다.
기술적 사례: Amadey의 한 변종을 메모리 덤프해 분석한 연구에 따르면, 고유한 함수 호출 시퀀스들이 드러났습니다. 예컨데 아래와 같은 x86 명령어 흐름은 Amadey에서 일관되게 등장하는 루틴입니다.
// Amadey 메모리 덤프에서 추출된 코드 시퀀스 (예시)
$sequence_0 = { 89 45 F4 83 7D F4 08 74 4F 8D 85 E8 FD FF FF 89 04 24 E8 ?? ?? ?? ?? C7 04 24 ?? ?? ?? ?? }
이 패턴을 디스어셈블리해보면, 지역 변수 값을 비교하여 분기하고 메모리 버퍼를 할당해 특정 함수로 호출하는 논리가 드러납니다 (예: mov [ebp-0xC], eax; cmp [ebp-0xC], 8; je …; lea eax, [ebp-0x218]; …)[15]. 이처럼 복잡한 바이트열도 결국 특정 기능을 수행하는 코드의 모습을 하고 있으며, Amadey 계열에서는 변종 간에도 유사한 제어 흐름을 보여 탐지에 응용되었습니다[16][17]. 공격자가 이를 우회하려면 내부 알고리즘 자체를 바꾸는 수준의 개편이 필요하지만, 그러면 악성코드의 신뢰성과 개발 비용 문제가 생기므로 쉽지 않습니다. 결국 **메모리 상에 드러나는 이러한 실행 invariant는 공격자 입장에서 “어쩔 수 없이 노출되는 약점”**인 셈입니다.
YARA 룰을 통한 메모리 기반 탐지 효율성과 일반화 가능성
메모리 기반 탐지를 실제 수동으로 수행하는 것은 어렵기 때문에, YARA 룰과 같은 패턴 매칭 도구가 널리 활용됩니다. YARA는 텍스트/바이너리 패턴을 정의하여 악성코드 군을 식별할 수 있는 유연한 규칙 언어로, 정적 검사뿐 아니라 메모리 덤프나 프로세스 메모리에도 적용 가능합니다[4][18]. 특히 YARA는 해시 매칭보다 일반화된 패턴을 사용하므로, 폴리모픽 변종에 대응한 invariant 탐지에 유용합니다[9].
메모리 기반 YARA 탐지의 효율성은 높은 탐지율과 낮은 오탐율로 나타납니다. 잘 설계된 YARA 룰은 한 악성코드 패밀리의 다양한 샘플을 아울러 식별할 수 있습니다[9]. 예를 들어 CloudSEK 연구진이 공개한 Amadey 탐지 YARA 룰을 보면, 디스크 상의 “MZ” 헤더 확인 이후 Amadey 전용 PDB 경로 문자열 또는 복호화 키 패턴을 찾는 조건으로 구성되어 있어, 패킹이 풀린 Amadey라면 변종에 상관없이 탐지될 수 있게 했습니다[7][19]. 이는 정적 탐지에 해당하는 룰이지만, 실질적으로 Amadey의 **핵심 정체성(내부 모듈명, 키 패턴)**을 노렸기 때문에 일종의 invariant 탐지로 볼 수 있습니다. 나아가 YARA-Signator 같은 도구는 메모리 덤프나 언팩된 파일의 디스어셈블리에서 고유한 바이트 시퀀스를 자동 추출하여 YARA 룰을 생성해줍니다[20]. 이렇게 생성된 룰은 API 호출, 제어 흐름, 상수 데이터 참조 패턴을 포함하므로, 간단한 바이트 치환 난독화로는 회피하기 어렵습니다[15][21]. 실제로 YARA-Signator 기반 Amadey 룰에는 5~7개의 명령어로 이루어진 시퀀스 여러 개가 strings로 정의되어, Amadey 변종 코드에서 반복 출현하는 고유 시그니처로 사용되었습니다[16][22].
일반화 가능성 측면에서, 메모리 기반 탐지 룰은 얼마나 보편적인 invariant를 포착했는지에 따라 범용성이 결정됩니다. 한편으로, 너무 특정 샘플에 맞춘 메모리 패턴은 변종이 약간만 바뀌어도 놓칠 수 있습니다. 예컨대 YARA-Signator 제작자는 “Malpedia에 수록된 단일 샘플 기반으로 생성된 규칙은 일반화 수준에 한계가 있을 수 있다”라고 언급하였는데[23], 이는 곧 메모리 탐지 룰도 지속적인 업데이트와 검증이 필요함을 시사합니다. 실제 현장에서 메모리 YARA를 설계할 때는 여러 변종의 메모리 공통 덤프를 비교하여 일치하는 패턴을 추출하거나, 악성 행위 자체를 나타내는 문자열/코드 조합을 선택하는 식으로 포괄성을 높이는 전략이 요구됩니다. 다행히 Amadey나 RedLine 같은 상용 악성코드는 한 시점의 버전에서 핵심 로직이 크게 변하지 않으므로, 한두 개 룰로도 수많은 변종을 커버하는 높은 효율을 보입니다[9]. 예를 들어 앞서 소개한 RedLine 탐지 YARA에서는 8개의 문자열 조건 중 6개만 일치하면 변종을 악성으로 분류하는데, 이로써 경로 문자열, 함수명, 프로토콜, DB 파일명 등 다양한 특징을 조합하여 오탐을 낮추면서 웬만한 변종은 모두 탐지하는 일반화 효과를 거두고 있습니다[10][24].
물론 과도한 일반화는 오탐 위험을 높일 수 있으므로, 메모리 YARA 룰은 특정 악성 행위에만 나타나는 패턴인지 정상 소프트웨어에도 있을 수 있는지를 고려해야 합니다. 이를 위해 메모리 기반 YARA는 종종 프로세스 컨텍스트 조건이나 사이즈 제한 등을 추가합니다. 예를 들어 Mandiant가 공개한 메모리 전용 다운로더 PEAKLIGHT 탐지 YARA에서는, PowerShell 스크립트 내부에서만 나타날 법한 구문 패턴 7개 중 4개 이상 발견되고 스크립트 크기가 10KB 미만일 때 룰이 매칭되도록 조건을 걸었습니다[25][26]. 이런 추가 조건은 일반화된 패턴이라도 특정 악성 시나리오에만 반응하게 만들어 탐지 정확도를 높입니다.
아래 표는 정적 서명 탐지와 메모리 기반 탐지의 비교를 요약한 것입니다:
| 탐지 방식 | 장점 | 단점 | 회피 난이도 |
|---|---|---|---|
| 정적 탐지 (파일 기준) | 빠른 검사, 알려진 서명 정확 탐지 | 패킹/암호화에 취약, 새로운 해시/서명 누락 위험 | 낮음 (패커로 쉽게 우회 가능) |
| 메모리 기반 탐지 | 난독화 우회 가능 (복호화된 실제 코드 탐지), 실행 행위 기반 탐지 (파일리스 공격 탐지) | 실시간 메모리 스캔 오버헤드, 전문 도구 필요 | 높음 (코드 로직 자체 변경 필요) |
위 표에서 보듯 정적 탐지는 우회 난이도가 낮아 Amadey처럼 간단한 문자열 인코딩만으로도 우회를 허용하지만[1], 메모리 탐지는 코드 내부 알고리즘까지 바꾸지 않는 이상 피하기 어려운 높은 난이도를 공격자에게 요구합니다. 따라서 YARA와 같은 규칙 기반 도구를 활용한 메모리 탐지는 효율성과 일반화 면에서 현대 악성코드 대응에 효과적이며, 실제로 많은 보안 업체들이 샌드박스 실행 후 메모리 스캔을 통해 가족별 악성코드를 식별하는 기법을 활용하고 있습니다[4][27].
악성코드 패밀리 간 메모리 수렴성 비교 (Amadey vs. RedLine vs. FormBook vs. SmokeLoader)
이제 Amadey 외에 다른 악성코드 패밀리에서도 **유사한 메모리 수렴성(공통 패턴)**이 나타나는지 살펴보겠습니다. 메모리 수렴성이란 각기 다른 변종들이 최종적으로 메모리상에서 비슷한 형태나 동작을 보이는 현상을 말합니다. 이는 해당 악성코드 패밀리가 수행하는 고유 악성행위가 비슷하기 때문에 생기는 현상으로 볼 수 있습니다.
Amadey (트로이목마/로더) – 앞서 분석한 대로 주요 문자열 복호화 루틴과 키 패턴, Mutex 생성, C2 통신 스레드 생성 코드 등이 메모리에서 일관되게 나타납니다[7][28]. Amadey는 MaaS 봇넷으로써 시스템 정보 수집 후 다수 추가 페이로드를 다운로드하는 것이 주 임무이므로, HTTP POST로 시스템 정보를 보내는 루틴(예: OS 버전, 사용자명 등을 문자열로 조합해 전송) 또한 변종에 상관없이 메모리에 공통 구현되어 있습니다[29][30]. 즉 네트워크 통신 구조, 문자열 디코딩 등에서 메모리 수렴성이 높습니다.
RedLine (정보탈취형 스틸러) – 러시아 해커 포럼에서 판매되는 유명 정보탈취 악성코드로, 웹 브라우저 저장 비밀번호, 자동완성 데이터, 암호화폐 지갑 정보 등을 훔칩니다[31]. RedLine은 종종 .NET으로 개발되어 런타임 시 어셈블리를 로드하거나 자체 보호를 위해 난독화되지만, 메모리상에서는 브라우저 프로파일 경로, SQLite 쿠키 DB 경로 (“cookies.sqlite”), 탈취 대상 애플리케이션 리스트 등의 문자열이 평문으로 드러납니다[32]. 또한 FTP/IM 클라이언트 명칭, 암호화폐 지갑 키워드 등도 탈취 대상에 따라 하드코딩되어 있어, 이러한 값들이 메모리에서 invariant로 검출됩니다. RedLine의 경우 다양한 버전이 등장해도 **탈취 대상과 방법(예: 파일 경로 열람, 시스템 정보 수집)**이 유사하기에, 메모리 수렴성이 높아 하나의 YARA 룰로도 여러 버전을 검출한 사례가 있습니다[33].
FormBook (정보탈취형/로더) – FormBook은 프로세스 인젝션에 특화된 고유한 런패킹(run-PE) 크립터를 사용하는 것으로 유명합니다[34]. 이 **“Babushka Crypter”**는 여러 계층으로 페이로드를 암호화한 뒤 최종 페이로드를 다른 프로세스 메모리에 실행시키는데, 이 과정에서 메모리에 일정한 패턴이 나타납니다. 예를 들어 자신을 CreateProcess로 실행한 후 대상 프로세스 메모리에 PE 헤더를 쓰고 섹션을 복사한 뒤 OEP로 점프하는 코드 흐름은 FormBook 계열에 공통된 invariant입니다. 해당 루틴은 메모리 상에서 DLL 스톰핑/인젝션에 수반되는 API 호출 (예: VirtualAllocEx, WriteProcessMemory, SetThreadContext, ResumeThread 등) 패턴으로 식별할 수 있습니다. 실제로 이 Babushka 인젝터의 행위 패턴은 유명해서, 시큐리티 연구자들이 FormBook류를 식별하는 YARA룰에도 이를 반영하고 있습니다[34]. 정리하면 FormBook 계열은 다층 암호화를 거치지만 결국 메모리상에서 나타나는 인젝션 행위는 유사하게 수렴합니다.
SmokeLoader (로더) – 2011년부터 활동한 오래된 로더 악성코드인 SmokeLoader 역시 파일 최소화 및 메모리 로딩 전략을 씁니다. 최신 SmokeLoader 변종은 **“stager”**라는 전단계 모듈이 자신을 난독화하고 분석 방해를 한 뒤, 주된 악성 모듈을 explorer.exe 프로세스 메모리에 인젝션하는 구조를 가집니다[35]. 이때 메모리 내부에서는 항상 explorer 프로세스의 메모리에 존재하지만 PE 이미지상 디스크에는 없는 모듈이 발견되는 공통 특징이 있습니다. 따라서 메모리 포렌식으로 explorer 등에 비정상적으로 로드된 코드 영역을 찾으면 SmokeLoader를 식별할 수 있습니다. 또한 SmokeLoader 메인 모듈은 영구성 확보(레지스트리 Run키 등록 등), C2 비콘 통신, 추가 모듈 로드 등의 기능을 수행하는데[36], 이러한 행위도 변종마다 유사해서 메모리상 API 호출 시퀀스 (예: 자신을 시작 프로그램에 복제, 원격 서버에 주기적 접속)가 수렴성을 보입니다. SmokeLoader는 2024년 당국 단속으로 일시 중단되었다 2025년에 프로토콜만 변경된 채 부활할 정도로 코어 로직이 유지되었고[37], 이는 메모리 기반 탐지 측면에서 과거 룰을 업데이트하여 계속 탐지할 수 있음을 의미합니다.
위 사례들을 종합하면, Amadey, RedLine, FormBook, SmokeLoader와 같은 악성코드 패밀리들은 각기 전파 방식이나 세부 구현은 달라도 “메모리 상에서 드러나는 핵심 악성 행위” 측면에서 일정한 수렴성을 보인다는 것을 알 수 있습니다. 이는 곧 메모리 기반 탐지 전략이 한 패밀리에 대해 마련되면 유사 변종뿐 아니라 동족 악성에도 응용될 수 있다는 전망을 줍니다. 예를 들어 Loader류 악성코드 전반의 공통 메모리 특징(프로세스 할로잉, 코드 인젝션 패턴 등)을 일반화한 YARA 룰을 만들어두면, 새로운 로더 악성코드가 등장해도 상당 부분 탐지 커버리지가 확보될 수 있습니다. 이처럼 메모리 invariant에 주목한 탐지는 서로 다른 악성코드 패밀리 간의 교차 탐지도 어느 정도 가능하게 해주며, 궁극적으로 일반화된 방어를 구현하는 데 기여합니다[9].
공격자의 회피 시도와 그 비용 (성능 및 개발 복잡도)
메모리 기반 탐지가 효과적이므로, 역으로 공격자는 이를 무력화하기 위한 시도를 할 수 있습니다. 그러나 앞서 논의했듯 이러한 시도에는 상당한 **비용(cost)**이 따릅니다. 주요 회피 방안과 그 한계를 살펴보면 다음과 같습니다:
코드 메타모픽 변형 – 공격자는 메타모픽 엔진을 도입하여 실행될 때마다 코드 자체를 재구성하도록 만들 수 있습니다. 예컨대 같은 기능을 매번 다른 명령어와 순서로 구현하거나[12], 무작위로 레지스터 할당을 바꾸고 더미 코드를 삽입하는 등의 기법입니다. 이렇게 하면 변종마다 메모리 상 기계어 패턴이 달라져 정형화된 YARA 시그니처로 잡기 어려워질 수 있습니다. 하지만 이 접근은 개발 난이도가 가장 높습니다. 동등한 기능 구현을 위한 다양한 코드패스 생성에는 복잡한 컴파일러 수준의 로직이 필요하고, 잘못하면 코드 버그나 충돌이 발생할 수 있습니다[11][38]. 또한 이렇게 생성된 코드가 항상 의도대로 동작하는지 검증하기 어렵고, 새로운 안티바이러스 진단을 유발할 가능성도 있습니다. 일반적인 공격자 입장에서 메타모픽 기능을 지속적으로 유지보수하는 것은 비용 부담이 커서, 역사적으로도 고도화된 바이러스나 APT 멀웨어 일부에만 제한적으로 사용되었습니다[3][39].
코드 지속 암/복호화 (메모리 상 암호화) – 또 다른 방법은 악성코드가 자기 자신의 코드를 실행 중에도 암호화된 형태로 유지하고, 필요한 순간에만 복호화하여 잠시 실행한 뒤 다시 메모리에서 지우는 것입니다. 이를테면 특정 함수 호출 직전에 해당 코드 부분을 복호화하고 실행한 후 즉시 메모리에서 제거하거나 다시 암호화하는 방식입니다. 이러면 메모리 스캔 시점에 따라 악성 패턴이 안 잡힐 수 있습니다. 그러나 이 역시 성능상의 문제가 큽니다. 매 함수나 루프마다 복호화/암호화 연산을 하면 CPU 사용량이 늘고 실행 속도가 저하됩니다. 특히 실시간으로 메모리를 지웠다가 다시 할당하는 작업은 레지던트 악성코드의 효율성을 떨어뜨리고 오류 발생 가능성을 높입니다. 그리고 EDR 솔루션들은 메모리 할당/보호 속성 변화를 후킹하여 추적하기 때문에, 이러한 시도도 완전한 은폐책은 되지 못합니다 (예: RWX 메모리 영역 생성과 삭제 빈도가 비정상적이면 경고). 따라서 공격자가 이런 기법을 도입하면 자신의 악성코드가 느려지고 불안정해지는 비용을 감수해야 합니다.
가상머신/인터프리터 내 실행 – 일부 고급 회피기법으로, 악성 페이로드를 자체 가상 머신 바이트코드로 변환한 뒤 메모리에 가상 머신 인터프리터만 올려서 동작하게 만드는 방법이 있습니다. 이 경우 메모리에는 인터프리터만 존재하고 실제 악성 행위는 가상 머신 안에서 해석되므로, 겉보기에는 패턴이 안 드러날 수 있습니다. 그러나 인터프리터 자체가 새로운 패턴이 되므로 이것도 장기적으로는 탐지 가능해집니다. 수십 KB 이상의 VM 해석기 코드가 메모리에 상주하면 오히려 특이한 메모리 특징이 되어 EDR에 탐지될 수 있고, 해당 VM의 명령 집합을 리버스 엔지니어링 당하면 결국 더 강인한 서명이 만들어집니다. 또한 VM을 사용하면 명령어 처리 오버헤드로 실행 성능이 저하됩니다. 공격자는 이러한 복잡한 커스텀 VM 개발과 유지보수 부담을 져야 하며, 이는 일반 금융정보 탈취나 로더 목적의 악성코드로서는 과투자에 가깝습니다.
기타 회피 기법 – 안티 메모리 스캔 기술로, 자신을 디버거로 위장해 OpenProcess로 메모리 읽기를 차단하거나, 페이지 권한을 교묘히 설정하여 접근하면 크래시를 유발하는 식의 방어도 이론적으로 가능합니다. 하지만 이를 구현하면 정상 동작에 지장을 줄 수 있고, 윈도우 API 후킹 등으로 충분히 우회당할 수 있습니다. 또한 EDR과의 치킨게임 양상이 되어, 방어 측에서도 커널 드라이버 등을 통해 더욱 강제적인 메모리 검사 기법을 적용할 수 있습니다. 일반적으로 공격자가 취하는 현실적인 회피는 최대한 패킹과 난독화를 강화하고, 지속적으로 변종을 만들어 정적 IOC 수명을 단축시키는 정도에 그칩니다[40][41]. 메모리 단계까지 신경 쓰는 공격자는 극소수이며, 그런 경우에도 위에서 논의한 대가를 치르게 마련입니다.
결론적으로, 공격자가 메모리 기반 탐지를 완전히 따돌리려면 개발 복잡도나 운영 안정성 측면에서 막대한 비용을 감수해야 합니다. 이는 방어자에게 유리한 지형을 만들어줍니다. 메모리상의 invariant를 노린 탐지 전략은 단기간에 무력화되기 어렵고, 설령 공격자가 대응하더라도 그 부담은 공격자 측에 전가됩니다. 예컨대 Amadey 제작자가 탐지를 피하려고 핵심 코드 흐름을 전면 수정하면, 그 기간 동안 서비스가 원활히 운영되기 힘들 것이고, 오히려 눈에 띄는 변화로 보안 커뮤니티에 포착될 가능성이 높습니다. 따라서 메모리 기반 탐지는 장기적으로 유효한 방어 수단으로 평가됩니다. 실제로 다계층 보안 체계에서는 정적, 동적, 행위 기반 탐지와 함께 메모리 포렌식 기반 탐지를 조합하여 활용함으로써, 신종 위협에 대한 종합적인 대응력을 높이고 있습니다[42][43]. Amadey를 비롯한 여러 악성코드 사례 분석을 통해 보았듯이, 메모리에는 거짓말이 없으며(runtime doesn’t lie), 이 점이 방어자가 끝까지 악성코드의 실체를 밝히는 열쇠가 될 것입니다.
참고 자료 (References)
【1】 Splunk Threat Research Team – “Amadey Threat Analysis and Detections” (2023)[1][29]
【6】 CloudSEK Research – “Amadey with AV Disabler drops RedLine – YARA rules” (2023)[7][20]
【11】 InventiveHQ – “Why Hash Lookup Fails Against Polymorphic Malware (Memory-Based Detection)” (2026)[4][5]
【29】 Amr Ashraf – “RedLine Stealer Analysis – YARA rule” (2023)[32][33]
【14】 Malpedia – “Formbook – unique RunPE crypter behavior”[34]
【34】 TheHackerNews – “SmokeLoader Returns with New Changes” (2025)[35][37]