
Beacon이 생성한 파일을 디스크 대신 메모리에 기록하는 CobaltStrike 툴킷
MemFiles는 CobaltStrike용 툴킷으로, 운영자가 Beacon 프로세스에서 생성된 파일을 대상 시스템의 디스크에 쓰는 대신 메모리에 쓸 수 있게 해줍니다. Windows 7, 10, 11에서 성공적으로 테스트되었으며, 해당 서버 버전도 문제없이 작동할 것입니다. MemFiles는 x64 Beacon에서만 사용할 수 있습니다.
이는 NTDLL.dll 내의 여러 NtAPI를 후킹하고 해당 API에 대한 호출을 Beacon 프로세스 메모리 공간에 주입된 함수로 리디렉션하여 수행합니다.
MemFiles는 Beacon 프로세스에 깨끗하고 후킹되지 않은 NTDLL 사본이 있다고 가정합니다. EDR 후크가 여전히 적용된 Beacon 프로세스에서는 MemFiles의 작동 가능성에 대해 어떠한 보장도 하지 않습니다. MemFiles를 사용하기 전에 NTDLL을 복구/새로 고치십시오!
MemFiles 툴킷 내에 "특수한" 존재하지 않는 디렉터리가 정의됩니다. 이 특수 디렉터리에 기록되는 모든 파일은 MemFiles에 의해 캡처되어 메모리에 기록되며, 이후 Teamserver로 다운로드할 수 있습니다.
MemFiles는 Beacon 프로세스 내에서 실행되고 출력을 특정 디렉터리로 보내도록 지시할 수 있는 대부분(전부는 아님)의 도구와 호환됩니다. 작동에 관리자 권한이 필요하지 않습니다.
여기에는 다음이 포함됩니다:
-BOF
-inline-executeAssembly와 같은 도구를 사용하여 인라인으로 실행되는 .NET 어셈블리
-Inline-Execute-PE와 같은 도구를 사용하여 인라인으로 실행되는 PE
이 모든 것은 관련 NtAPI가 후킹된 Beacon 프로세스 내부에서 실행되므로 호환됩니다.
MemFiles는 다음 항목과는 작동하지 않습니다:
-execute-assembly
-shell
-run
이들은 모두 NtAPI가 후킹되지 않은 별도의 프로세스를 생성하기 때문에 호환되지 않습니다.
MemFiles는 Beacon 프로세스 내에서 실행될 때 Rubeus, SharpHound, Procdump 및 Powershell과 같은 도구로 성공적으로 테스트되었습니다.

저장소를 클론하고 선택적으로 /PIC/Source/NtCreateFile.c 및 /PIC/Source/NtOpenFile.c의 56행에 정의된 hookdir 변수를 변경합니다. 이 변수는 MemFiles가 생성되는 파일을 가로채야 함을 알리는 "특수" 디렉터리입니다. hookdir 변수는 기본적으로 "redteam"으로 설정되어 있습니다. 이 변수가 대상 시스템의 실제 디렉터리가 아닌지, 그리고 두 파일에서 동일한지 확인하십시오!

'make all'을 실행하여 필요한 BOF와 PIC 함수를 모두 컴파일하십시오.
MemFiles.cna를 CobaltStrike Client에 로드하십시오. CobaltStrike가 실행되는 디렉터리가 사용자에 의해 쓰기 가능한지 확인하십시오. MemFiles는 작동에 필요한 데이터의 가용성을 보장하기 위해 해당 위치에 텍스트 파일(memfiles.txt)을 생성합니다.
MemFiles는 Teamserver에 콜백하는 각각의 새 Beacon에 설치되도록 구성할 수 있습니다. 이는 MemFiles->Config 메뉴 항목을 사용하여 수행됩니다. 기본적으로 MemFiles는 새 Beacon에 자동 설치되지 않습니다. 이는 전역 설정입니다. 두 Client가 Teamserver에 연결되어 있고 둘 다 MemFiles.cna를 로드한 경우, Client A가 "비콘 초기 설치" 설정을 전환하면 Client B에도 변경 사항이 적용됩니다!

MemFiles는 BOF를 실행하는 4개의 대상 지향 명령과 프로젝트 데이터 구조를 조작하는 1개의 내부 명령으로 구성됩니다.
대상 지향:
내부 데이터 구조:
meminit은 Beacon 프로세스에 MemFiles를 설치하는 역할을 담당합니다.
MemFiles가 후킹하는 NtAPI 목록은 다음과 같습니다:
meminit은 다음 주요 작업을 수행합니다:
memlist는 특정 Beacon에 대해 MemFiles가 현재 메모리에 저장한 모든 파일을 표시하는 데 사용됩니다.

여러 필드가 표시되며, 사용자에게 가장 관련성이 높고 관심 있는 필드는 파일 이름과 저장된 데이터의 길이입니다.
memfetch는 특정 Beacon에 대해 MemFiles가 메모리에 저장한 파일을 실제로 검색하는 데 사용됩니다.
기본적으로 memfetch는 "핸들"이 닫힌 MemFiles에 의해 저장된 모든 파일을 검색합니다. 이 설계 선택은 프로그램/애플리케이션이 아직 쓰기를 완료하지 않은 파일을 다운로드하려고 할 때 발생할 수 있는 문제를 피하기 위한 것입니다.
즉, 프로그램/애플리케이션이 파일에 대해 연 핸들을 닫지 못하면 해당 파일은 memfetch로 다운로드되지 않습니다.
이는 memfetch와 함께 "force" 인수를 사용하여 완화할 수 있습니다. 즉, 'memfetch force'는 핸들의 상태와 관계없이 메모리에서 모든 파일을 검색합니다.
memfetch가 메모리에서 검색한 파일은 다운로드로 Teamserver에 다시 전송되며, CobaltStrike의 Downloads 탭을 통해 Teamserver에서 Client로 동기화할 수 있습니다.
파일이 Teamserver에 의해 다운로드되면 Beacon 프로세스의 메모리에서 제거되고 memlist로 표시되는 해당 항목도 제거됩니다.
memclean은 Beacon 프로세스에서 MemFiles를 정리하고 제거하는 역할을 담당합니다.
MemFiles의 일반적인 사용 사례는 이를 설치하고 Beacon의 수명 기간 동안 설치된 상태로 두는 것입니다. 그러나 MemFiles를 도구와 함께 사용하여 파일 출력을 캡처하고 검색한 다음, 해당 아티팩트가 메모리에 남지 않도록 MemFiles를 제거하려는 경우 memclean을 사용하여 meminit이 실행되기 전의 원래 상태로 Beacon 프로세스를 되돌릴 수 있습니다.
여기에는 다음이 포함됩니다:
memclean이 이러한 작업을 수행하기 전에 메모리에 저장된 모든 파일을 강제로 다운로드한다는 점에 유의하십시오. 단일 도구와 함께 MemFiles를 사용한 다음 제거하려는 경우 memfetch를 건너뛰고 memclean만 사용하여 파일을 검색하고 동시에 Beacon 프로세스에서 MemFiles를 제거할 수 있습니다.
memtable은 MemFiles가 현재 설치된 Beacon에 대한 정보를 표시하고 추적하는 데 사용됩니다. 또한 전역 구성 정보를 표시합니다.
각 CobaltStrike Client는 고유한 memtable을 가지고 있습니다. MemFiles는 모든 연결된 CobaltStrike Client 간에 데이터 동기화를 보장하기 위해 많은 노력을 기울이며, 모든 운영자가 모든 Beacon에서 MemFiles를 사용할 수 있도록 합니다. 자세한 내용은 "설계 고려 사항 및 해설"을 참조하십시오.

meminit 명령을 사용하여 Beacon에서 MemFiles를 초기화합니다. MemFiles->Config 메뉴에서 옵션을 전환하여 자동으로 수행되도록 구성할 수 있습니다.

MemFiles가 초기화되면 이제 선호하는 도구를 사용하여 파일을 메모리에 쓸 수 있습니다! 방법은 특정 도구에 따라 다릅니다. 일부는 여러 파일을 출력할 디렉터리를 지정할 수 있게 하고, 다른 일부는 도구가 생성하는 단일 파일의 절대 경로를 지정할 수 있게 합니다. 몇 가지 예는 아래에서 볼 수 있습니다:
여기서는 SharpHound가 생성된 모든 파일을 c:\redteam\ 디렉터리(우리의 특수 MemFiles 디렉터리)로 출력하고 파일을 압축하지 않도록 지정합니다. MemFiles는 프로그램이 메모리에서 파일을 읽는 것을 지원하지 않고 쓰기만 지원하므로 SharpHound의 압축 기능은 작동하지 않습니다.

"dump" 명령이 Rubeus와 함께 사용되며, 모든 콘솔 출력을 (특수 디렉터리에 있는) 파일로 보내도록 지시합니다.

이 예에서는 Inline-Execute-PE를 사용하여 powershell.exe를 Beacon 프로세스에 로드하고 'Get-ADUser'를 실행하여 도메인 사용자 목록을 검색합니다. 파이프와 'out-file'을 사용하면 데이터를 메모리에 쓴 다음 검색할 수 있습니다.

파일을 검색하려면 memfetch를 실행하십시오:

MemFiles 사용이 끝났거나 Beacon 프로세스에 설치된 상태로 두고 싶지 않으면 memclean을 실행하십시오:

위 예에서는 아직 다운로드되지 않은 파일이 하나 있었습니다. memclean은 MemFiles를 제거하기 전에 이 파일을 다운로드하고 메모리에서 제거합니다.
memtable을 사용하여 MemFiles의 상태와 구성을 확인하십시오. 장기간 작업하는 동안 죽었거나 오래된 Beacons의 항목을 memtable에서 지워 복잡함을 피하십시오.

소개에서 강조했듯이 MemFiles는 작동하려면 Beacon 프로세스에 깨끗한 NTDLL 사본이 필요합니다. 이는 NtFunction의 원래 바이트를 읽고 특정 바이트를 트램펄린으로 복사하기 때문에 필요한데, 트램펄린은 나중에 MemFiles가 간섭해서는 안 되는 NtFunction에 대한 정상적인 호출을 완료하는 데 사용됩니다. 이 주제는 "기술적 세부 사항, 설계 고려 사항 및 해설" 섹션에서 더 자세히 다룹니다.
MemFiles는 각 파일에 대해 초기 1048576바이트를 할당합니다. 데이터가 메모리에 기록되면 더 큰 파일을 보관하기 위해 필요에 따라 이 할당을 확장할 수 있고 확장합니다.
MemFiles 구조체에 저장된 파일 이름은 대체 NtCreateFile 함수에 전달되는 인수에서 구문 분석됩니다. MemFiles는 파일 경로 인수에서 "특수" 디렉터리를 찾고, 그 끝으로 이동한 다음, "특수" 디렉터리와 파일 이름을 구분하는 '\' 문자를 처리하기 위해 포인터를 1만큼 증가시키는 다소 단순한 방식으로 이를 수행합니다. 예를 들어 'C:\users\tom\redteam\myfile.txt' 경로에서 MemFiles는 'redteam'을 찾고 백슬래시 문자를 처리한 다음 'myfile.txt'를 파일 이름으로 선택합니다.
MemFiles는 파일 경로의 선행 디렉터리에 대해 신경 쓰지 않습니다. MemFiles의 관점에서 'C:\redteam\myfile.txt'와 'c:\users\tom\appdata\local\redteam\myfile.txt'는 동일하게 유효한 경로입니다.