
Freeze.rs는 일시 중단된 프로세스와 직접 시스템 콜을 사용하여 EDR을 우회하기 위해 RUST로 작성된 페이로드 툴킷입니다.
최신 버전의 Freeze.rs를 보거나 이슈를 제출하려면 https://github.com/Tylous/Freeze.rs를 참조하십시오.
이 프레임워크에서 사용된 기술에 대해 더 알고 싶다면 SourceZero 블로그와 원본 도구를 확인해 주세요.
Freeze.rs는 EDR 보안 제어를 우회하여 쉘코드를 은밀하게 실행하는 페이로드 생성 도구입니다. Freeze.rs는 여러 기술을 활용하여 Userland EDR 후크를 제거할 뿐만 아니라 다른 엔드포인트 모니터링 제어를 우회하는 방식으로 쉘코드를 실행합니다.
프로세스가 생성되면 Ntdll.dll이 가장 먼저 로드되는 DLL입니다. 이는 EDR DLL이 로드되기 전에 발생합니다. 즉, EDR이 로드되어 시스템 DLL의 어셈블리를 후킹하고 수정하기까지 약간의 지연이 있습니다. Windows Ntdll.dll의 시스템 콜을 살펴보면 아직 아무것도 후킹되지 않은 것을 볼 수 있습니다. 프로세스를 일시 중단 상태(시간이 멈춘 상태)로 생성하면 Ntdll.dll 외에는 다른 DLL이 로드되지 않음을 알 수 있습니다. 또한 EDR DLL이 로드되지 않았으므로 Ntdll.dll의 시스템 콜이 수정되지 않았음을 볼 수 있습니다.
이 깨끗한 일시 중단 프로세스를 사용하여 Freeze.rs 로더에서 후크를 제거하려면 프로그래밍 방식으로 깨끗한 일시 중단 프로세스의 메모리를 찾고 읽을 방법이 필요합니다. 여기서 ASLR(Address Space Layout Randomization)이 등장합니다. ASLR은 스택 메모리 손상 기반 취약점을 방지하기 위한 보안 메커니즘입니다. ASLR은 프로세스 내의 주소 공간을 무작위화하여 메모리 매핑된 모든 객체, 스택, 힙, 실행 프로그램 자체가 고유하도록 보장합니다. 여기서 흥미로운 점은 ASLR이 작동하지만, DLL과 같은 위치 독립적 코드에는 적용되지 않는다는 것입니다. DLL(특히 알려진 시스템 DLL)의 경우 주소 공간이 부팅 시 한 번 무작위화됩니다. 즉, 우리가 제어하는 프로세스를 포함한 모든 프로세스에서 ntdll.dll의 베이스 주소가 동일하므로 원격 프로세스 정보를 열거하지 않아도 ntdll.dll의 베이스 주소를 찾을 수 있습니다. 모든 DLL의 주소는 부팅 시 동일한 위치에 있기 때문에 우리 자신의 프로세스에서 이 정보를 가져올 수 있으며, 주소를 찾기 위해 일시 중단 프로세스를 열거할 필요가 없습니다.
이 정보를 바탕으로 API ReadProcessMemory를 사용하여 프로세스 메모리를 읽을 수 있습니다. 이 API 호출은 일반적으로 자격 증명 기반 공격의 일환으로 LSASS를 읽는 것과 관련이 있지만, 그 자체로는 본질적으로 악의적이지 않습니다. 특히 메모리의 임의 섹션만 읽는 경우 더욱 그렇습니다. ReadProcessMemory가 의심스러운 것으로 플래그되는 유일한 경우는 읽어서는 안 되는 것(예: LSASS의 내용)을 읽을 때입니다. EDR 제품은 ReadProcessMemory가 호출되었다는 사실 자체를 플래그하지 않아야 합니다. 이 함수에는 합법적인 운영상의 용도가 있으므로 많은 오탐(false positive)이 발생할 수 있기 때문입니다.
더 나아가 Ntdll.dll의 모든 시스템 콜이 저장된 .text 섹션만 읽음으로써 전체 DLL을 읽지 않을 수 있습니다.
이러한 요소를 결합하여 Ntdll.dll의 .text 섹션 복사본을 프로그래밍 방식으로 얻고, 쉘코드를 실행하기 전에 기존의 후킹된 .text 섹션을 덮어쓸 수 있습니다.
ETW는 기본 제공 시스템 콜을 활용하여 이 텔레메트리를 생성합니다. ETW는 Windows에 내장된 기본 기능이므로 보안 제품은 이 정보에 접근하기 위해 ETW 시스템 콜을 "후킹"할 필요가 없습니다. 결과적으로 ETW를 방지하기 위해 Freeze.rs는 여러 ETW 시스템 콜을 패치하여 레지스터를 비우고 실행 흐름을 다음 명령어로 반환합니다. ETW 패칭은 이제 모든 로더에서 기본값입니다.
Ntdll.dll만 복원되었으므로 쉘코드를 실행하는 모든 후속 호출은 Ntdll.dll에 있어야 합니다. Rust의 NTAPI 크레이트(다른 언어에서도 가능하지만 Rust에서 구현하기 매우 쉽습니다)를 사용하여 쉘코드 할당, 쓰기, 보호에 필요한 NT 시스템 콜을 정의하고 호출할 수 있습니다. 이렇게 함으로써 Kernel32.dll과 Kernelbase.dll에 있는 표준 호출을 효과적으로 건너뛸 수 있습니다. 이러한 DLL은 여전히 후킹되어 있을 수 있기 때문입니다.
Rust의 NTAPI 크레이트를 사용하면 이러한 모든 호출이 ntdll.dll 아래에 나타나지 않지만, 프로세스 내에는 여전히 존재합니다.
결과적으로:
이것은 Rust를 배우기 위한 재미있는 프로젝트로 시작하여 자체 프레임워크로 성장했습니다.
Freeze.rs는 Rust로 개발되었습니다.
Rust와 Rustup이 설치되어 있지 않다면 설치하십시오. OSX나 Linux에서 컴파일하는 경우 "x86_64-pc-windows-gnu" 타겟이 추가되어 있는지 확인하십시오. 다음 명령을 실행하세요:
rustup target add x86_64-pc-windows-gnu
완료되면 Freeze.rs를 컴파일할 수 있습니다. 다음 명령을 실행하거나 컴파일된 바이너리를 사용하세요:
cargo build --release
그러면 컴파일된 버전이 target/release에서 찾을 수 있습니다 (참고: --release를 넣지 않으면 파일은 target/debug/에 있습니다)
___________
\_ _____/______ ____ ____ ________ ____ _______ ______
| __) \_ __ \_/ __ \_/ __ \\___ // __ \ \_ __ \/ ___/
| \ | | \/\ ___/\ ___/ / /\ ___/ | | \/\___ \
\___ / |__| \___ >\___ >_____ \\___ > /\ |__| /____ >
\/ \/ \/ \/ \/ \/ \/
(@Tyl0us)
Soon they will learn that revenge is a dish... best served COLD & Rusty...
USAGE:
Freeze-rs [FLAGS] [OPTIONS]
FLAGS:
-c, --console 바이너리 페이로드 전용 - 페이로드 실행 시 상세한 콘솔 정보를 생성합니다. 이 옵션은 숨겨진 창 기능을 비활성화합니다.
-h, --help 도움말 정보를 출력합니다.
-n, --noetw ETW 이벤트 생성을 방지하는 ETW 패칭을 비활성화합니다.
-s, --sandbox 다음을 확인하여 샌드박스 회피를 활성화합니다:
엔드포인트가 도메인에 가입되어 있습니까?
엔드포인트에 2개 이상의 CPU가 있습니까?
엔드포인트에 4GB 이상의 RAM이 있습니까?
-V, --version 버전 정보를 출력합니다.
OPTIONS:
-E, --Encrypt <ENCRYPT> AES 256, ELZMA 또는 RC4 암호화를 사용하여 쉘코드를 암호화합니다.
-I, --Input <INPUT> 원시 64비트 쉘코드의 경로입니다.
-O, --Output <OUTPUT> 출력 파일의 이름입니다 (예: loader.exe 또는 loader.dll). 정의된 파일 확장자에 따라 Freeze가 DLL 또는 EXE를 생성할지 결정됩니다.
-p, --process <PROCESS> 생성할 프로세스의 이름입니다. 이 프로세스는 C:\Windows\System32\에 존재해야 합니다. 예: 'notepad.exe'
-e, --export <export> DLL에 대한 사용자 지정 내보내기 함수 이름을 정의합니다.
Freeze.rs는 .exe 또는 .dll 파일을 생성할 수 있습니다. 이를 지정하려면 -O 명령줄 옵션이 바이너리의 경우 .exe, DLL의 경우 .dll로 끝나도록 하십시오. 현재 다른 파일 형식은 지원되지 않습니다. DLL 파일의 경우 Freeze.rs는 추가 내보내기 기능을 추가할 수도 있습니다. 이렇게 하려면 -export 옵션과 함께 특정 내보내기 함수 이름을 사용하십시오.
쉘코드 암호화는 EDR 및 기타 보안 제품에 의해 탐지 및 분석되는 것을 방지하는 중요한 기술입니다. Freeze.rs는 AES, ELZMA, RC4를 포함한 여러 암호화 방법을 제공합니다.
AES(Advanced Encryption Standard)는 데이터 암호화에 널리 사용되는 대칭 암호화 알고리즘입니다. Freeze.rs는 AES-256 비트 크기를 사용하여 쉘코드를 암호화합니다. AES로 쉘코드를 암호화하는 장점은 강력한 암호화를 제공하고 암호화 라이브러리에서 널리 지원된다는 것입니다. 그러나 고정 블록 크기를 사용하면 패딩 오라클 공격과 같은 특정 공격에 취약할 수 있습니다.
ELZMA는 악성 코드에서 코드를 난독화하는 데 자주 사용되는 압축 및 암호화 알고리즘입니다. ELZMA를 사용하여 쉘코드를 암호화하려면 먼저 ELZMA 알고리즘을 사용하여 쉘코드를 압축합니다. 그런 다음 압축된 데이터를 임의의 키로 암호화합니다. 암호화된 데이터와 키는 익스플로잇 코드에 포함됩니다. ELZMA를 사용하여 쉘코드를 암호화하는 장점은 하나의 알고리즘으로 압축과 암호화를 모두 제공한다는 점입니다. 이는 익스플로잇 코드의 크기를 줄이고 탐지를 더 어렵게 만드는 데 도움이 될 수 있습니다.
RC4는 악성 코드에서 쉘코드 암호화에 자주 사용되는 대칭 암호화 알고리즘입니다. 가변 길이 키를 사용할 수 있는 스트림 암호로, 단순성과 속도로 유명합니다.
Freeze.rs는 먼저 프로세스를 생성한 다음 백그라운드로 이동시키는 기술을 사용합니다. 이는 두 가지 효과가 있습니다. 첫째, 프로세스를 숨기는 데 도움이 되고, 둘째, EDR 제품에 탐지되지 않도록 합니다. 바로 백그라운드에서 프로세스를 생성하는 것은 매우 의심스러울 수 있으며 악성 행위의 지표가 될 수 있습니다. Freeze.rs는 프로세스가 생성되고 EDR의 후크가 로드된 후 'GetConsoleWindow' 및 'ShowWindow' Windows 함수를 호출하고 창 속성을 숨김으로 변경하여 이를 수행합니다.
-console 명령줄 옵션이 선택되면 Freeze.rs는 프로세스를 백그라운드에서 숨기지 않습니다. 대신 Freeze.rs는 로더가 수행하는 작업을 보여주는 여러 디버그 메시지를 추가합니다.