
ShellcodeFluctuation PoC를 Nim으로 포팅함
원본 저장소의 Nim 포트: https://github.com/mgeeky/ShellcodeFluctuation 모든 주석은 원본 저장소에서 그대로 복사해 왔습니다. 해당 기법을 이해하는 데 정말 큰 도움이 되었기 때문입니다. 기법 자체에 대한 더 자세한 정보는 원본 저장소의 README를 읽어보시길 적극 권장합니다!
의존성 설치:
nimble install winim ptr_math
이 메모리 암호화 기법이 OpSec 측면에서 최선은 아니라는 점을 잘 알고 있습니다. 이 기법은 정의된 영역만 정확히 암호화합니다. 예를 들어 C2 임플란트의 경우, 새로 실행된 모듈 메모리 주소는 Sleep 중에 암호화되지 않습니다. Heap 기반 탐지(Cobalt-Strike 구성 탐지 등)를 피하려면 여기에 Heap 암호화도 추가해야 합니다.
그래도 이 메모리 암호화 기법은 메인 C2 임플란트의 Sleep 중 자동 메모리 스캐너 탐지를 피하는 데 충분히 유용하게 사용할 수 있습니다. 저는 Covenant와 맞춤형 stageless Payload로 PoC를 성공적으로 테스트했습니다 이 링크 참조.
이 포트에서는 암호화/복호화 키와 Shellcode 주소, 그리고 보호 속성(RW) 같은 추가 값들을 수동으로 정의해야 합니다. 원본 저장소에서는 Shellcode 호출 주소가 자동으로 가져와졌습니다.
Example.nim 파일에는 시작하는 데 필요한 모든 것이 들어 있습니다. 물론 C2 Shellcode를 사용할 때는 Sleep을 직접 호출할 필요가 없습니다(이건 PoC를 위해 모든 것을 트리거하려는 목적일 뿐입니다). 그건 C2 자체가 처리해야 합니다. 현재 이 포트는 Win32 Sleep 함수를 사용하는 C2 프레임워크에서만 호환되지만, Hook을 다른 함수로 수정하면 동일한 방식으로 동작합니다.
import winim
import Fluctuation
echo "Trying to hook Sleep"
if (hookSleep()):
echo "Hooked Sleep successfully!"
type
PocArray = array[12, byte]
let names: PocArray = [byte 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA]
g_fluctuationData.shellcodeAddr = unsafeAddr names[0]
echo "Shellcode address:"
echo repr(g_fluctuationData.shellcodeAddr)
g_fluctuationData.shellcodeSize = size_t(len(names))
echo "Shellcode Size:"
echo repr(g_fluctuationData.shellcodeSize)
when defined(amd64):
g_fluctuationData.encodeKey = 0xDEADB33f
when defined(i386):
g_fluctuationData.encodeKey = 0xDEAD
g_fluctuationData.currentlyEncrypted = false
g_fluctuationData.protect = PAGE_READWRITE
g_fluctuate = FluctuateToRW
echo "Calling Sleep"
Sleep(2500)
echo "Everything went fine and as expected"
else:
echo "Failed to hook Sleep"
quit(1)
암호화 PoC 테스트는 예를 들어 다음과 같이 할 수 있습니다:
nim c --debuginfo --linedir:on Example.nim
디버거로 시작:
gdb Example.exe
Sleep 전후에 중단점(Breakpoint)을 설정:
# Before encryption
break Example.nim:31
# After encryption
break Fluctuation.nim:98
# Original value restored
break Example.nim:33
그런 다음 각 중단점에서 Shellcode 주소의 값을 다음과 같이 확인합니다:

NA로의 Fluctuation은 아직 작동하지 않습니다. 테스트에서 Vectored Exception Handler가 전혀 트리거되지 않았고 애플리케이션이 크래시되었기 때문입니다. 추후에 추가 테스트와 트러블슈팅을 진행해야 할 것 같습니다. 직접 테스트해 보셔도 좋습니다! :-)