Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
BOF_ExecuteAssembly — 탐지 회피 기법을 사용하여 beacon 내에서 .NET 어셈블리를 실행하는 Cobalt Strike용 Beacon Object File. | Kitploit
도구/GitHubGitHub/ntdallas/bof_executeassembly
Privilege EscalationIDS/IPS EvasionShellcodePost-ExploitationCommand and ControlRed TeamingBinary Exploitation
GitHubntdallas/bof_executeassembly

BOF_ExecuteAssembly

탐지 회피 기법을 사용하여 beacon 내에서 .NET 어셈블리를 실행하는 Cobalt Strike용 Beacon Object File.

저장소 보기
195278개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

BOF Execute-Assembly

Cobalt Strike용 Beacon Object File로, 회피 기법을 사용하여 비콘에서 .NET 어셈블리를 실행합니다.

개요

핵심 아키텍처

root@kitploit:~
┌──────────────────────────────────────────────────────────────────────────────┐
│                         Cobalt Strike Beacon                                 │
│                         (Parent Process)                                     │
└──────────────────────────────────┬───────────────────────────────────────────┘
                                   │
                                   │ beacon_inline_execute()
                                   │ - Parse packed arguments
                                   │ - Call go()
                                   ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│                      BOF Execute-Assembly Entry (go)                         │
│  ┌────────────────────────────────────────────────────────────────────────┐  │
│  │ Configuration Parsing                                                  │  │
│  │  • ProxyMethod (None/Draugr/Timer/RegWait)                             │  │
│  │  • AmsiEvasion (None/Patch/HWBP)                                       │  │
│  │  • EtwEvasion (None/Patch)                                             │  │
│  │  • PipeName, AppDomainName, Assembly bytes, Arguments                  │  │
│  └────────────────────────────────┬───────────────────────────────────────┘  │
│                                   │                                          │
│  ┌────────────────────────────────▼───────────────────────────────────────┐  │
│  │ Framework Initialization                                               │  │
│  │  • InitVxTable() - Resolve syscall numbers                             │  │
│  │    └─> NtProtectVirtualMemory, NtContinue, NtCreateEvent,              │  │
│  │        NtSetEvent, NtWaitForSingleObject, NtClose                      │  │
│  │  • DraugrInit() - Setup synthetic stack frames                         │  │
│  │    └─> Locate RtlUserThreadStart, BaseThreadInitThunk                  │  │
│  └────────────────────────────────┬───────────────────────────────────────┘  │
│                                   │                                          │
│  ┌────────────────────────────────▼───────────────────────────────────────┐  │
│  │ DLL Loading (ProxyLoadLibraryA)                                        │  │
│  │  • amsi.dll, OleAut32.dll, mscoree.dll, User32.dll                     │  │
│  │                                                                        │  │
│  │  PROXY_NONE:     LoadLibraryA() directly                               │  │
│  │  PROXY_DRAUGR:   DRAUGR_API(LoadLibraryA) - spoofed stack              │  │
│  │  PROXY_TIMER:    CreateTimerQueue → Timer callback                     │  │
│  │  PROXY_REGWAIT:  RegisterWaitForSingleObject → Event callback          │  │
│  └────────────────────────────────┬───────────────────────────────────────┘  │
│                                   │                                          │
│  ┌────────────────────────────────▼───────────────────────────────────────┐  │
│  │ AMSI Evasion Setup                                                     │  │
│  │                                                                        │  │
│  │  AMSI_PATCH:                         AMSI_HWBP:                        │  │
│  │  ┌─────────────────────────┐         ┌──────────────────────────────┐  │  │
│  │  │ 1. Backup 4 bytes       │         │ 1. Add VEH Handler           │  │  │
│  │  │ 2. NtProtectVirtualMem  │         │ 2. RtlCaptureContext         │  │  │
│  │  │    (RW)                 │         │ 3. Set DR0 = AmsiScanBuffer  │  │  │
│  │  │ 3. Write:               │         │ 4. Enable DR7 breakpoint     │  │  │
│  │  │    48 31 C0  xor rax,rax│         │ 5. NtContinue (apply ctx)    │  │  │
│  │  │    C3        ret        │         │                              │  │  │
│  │  │ 4. NtProtectVirtualMem  │         │ On AmsiScanBuffer call:      │  │  │
│  │  │    (restore)            │         │   → #BP Exception            │  │  │
│  │  └─────────────────────────┘         │   → VEH redirects to RET     │  │  │
│  │                                      │   → RAX = 0                  │  │  │
│  │                                      └──────────────────────────────┘  │  │
│  └────────────────────────────────┬───────────────────────────────────────┘  │
│                                   │                                          │
│  ┌────────────────────────────────▼───────────────────────────────────────┐  │
│  │ ETW Evasion (if enabled)                                               │  │
│  │  • NtProtectVirtualMemory(NtTraceEvent, RW)                            │  │
│  │  • Backup 4 bytes                                                      │  │
│  │  • Write: 48 31 C0 C3 (xor rax,rax; ret)                               │  │
│  │  • NtProtectVirtualMemory(restore protection)                          │  │
│  └────────────────────────────────┬───────────────────────────────────────┘  │
│                                   │                                          │
│  ┌────────────────────────────────▼───────────────────────────────────────┐  │
│  │ Output Redirection Setup                                               │  │
│  │  ┌──────────────────────────────────────────────────────────────────┐  │  │
│  │  │ 1. CreateNamedPipeW(\\.\pipe\{CustomName})  → hPipe              │  │  │
│  │  │ 2. CreateFileW(pipe path)                   → hFile              │  │  │
│  │  │ 3. AllocConsole() + ShowWindow(SW_HIDE)     → Hidden console     │  │  │
│  │  │                                                                  │  │  │
│  │  │ 4. PEB Manipulation:                                             │  │  │
│  │  │    • Backup: hCurrentStdOut = PEB->ProcessParameters->StdOut     │  │  │
│  │  │    • Backup: hCurrentStdErr = PEB->ProcessParameters->StdErr     │  │  │
│  │  │    • Redirect: PEB->StdOut = hFile                               │  │  │
│  │  │    • Redirect: PEB->StdErr = hFile                               │  │  │
│  │  └──────────────────────────────────────────────────────────────────┘  │  │
│  └────────────────────────────────┬───────────────────────────────────────┘  │
│                                   │                                          │
│  ┌────────────────────────────────▼───────────────────────────────────────┐  │
│  │ CLR Hosting & Assembly Execution (ExecuteAssembly)                     │  │
│  │  ┌──────────────────────────────────────────────────────────────────┐  │  │
│  │  │ 1. CLR Version Detection                                         │  │  │
│  │  │    • Scan assembly bytes for "v2.0.50727" or "v4.0.30319"        │  │  │
│  │  │                                                                  │  │  │
│  │  │ 2. CLR Initialization                                            │  │  │
│  │  │    • CLRCreateInstance → ICLRMetaHost                            │  │  │
│  │  │    • GetRuntime(v2/v4) → ICLRRuntimeInfo                         │  │  │
│  │  │    • GetInterface → ICorRuntimeHost                              │  │  │
│  │  │    • Start()                                                     │  │  │
│  │  │                                                                  │  │  │
│  │  │ 3. AppDomain Management                                          │  │  │
│  │  │    • GetDefaultDomain() → Default AppDomain                      │  │  │
│  │  │    • CreateDomain(CustomName) → Isolated AppDomain               │  │  │
│  │  │                                                                  │  │  │
│  │  │ 4. Assembly Loading                                              │  │  │
│  │  │    • Create SAFEARRAY (VT_UI1) with assembly bytes               │  │  │
│  │  │    • SafeArrayAccessData → Copy assembly to safe array           │  │  │
│  │  │    • CustomAppDomain->Load_3(safearray) → Load in memory         │  │  │
│  │  │                                                                  │  │  │
│  │  │ 5. Argument Preparation                                          │  │  │
│  │  │    • Parse space-delimited arguments                             │  │  │
│  │  │    • Create SAFEARRAY(VT_BSTR) for each argument                 │  │  │
│  │  │    • Wrap in VARIANT structure                                   │  │  │
│  │  │                                                                  │  │  │
│  │  │ 6. Execution                                                     │  │  │
│  │  │    • Assembly->EntryPoint() → Get Main() MethodInfo              │  │  │
│  │  │    • MethodInfo->Invoke_3(arguments) → Execute                   │  │  │
│  │  │       └─> Assembly writes to Console                             │  │  │
│  │  │           └─> Redirected to hFile → Named Pipe                   │  │  │
│  │  │                                                                  │  │  │
│  │  │ 7. Cleanup                                                       │  │  │
│  │  │    • Release COM interfaces (MethodInfo, Assembly, etc.)         │  │  │
│  │  │    • UnloadDomain(CustomAppDomain) → Full unload                 │  │  │
│  │  │    • FreeLibrary(mscoree.dll)                                    │  │  │
│  │  └──────────────────────────────────────────────────────────────────┘  │  │
│  └────────────────────────────────┬───────────────────────────────────────┘  │
│                                   │                                          │
│  ┌────────────────────────────────▼───────────────────────────────────────┐  │
│  │ Output Capture & Display                                               │  │
│  │  • Restore PEB: StdOut/StdErr = original handles                       │  │
│  │  • Allocate buffer (0x10000 bytes)                                     │  │
│  │  • ReadFile(hPipe) → Capture assembly output                           │  │
│  │  • BeaconPrintf(CALLBACK_OUTPUT, output) → Display to operator         │  │
│  └────────────────────────────────┬───────────────────────────────────────┘  │
│                                   │                                          │
│  ┌────────────────────────────────▼───────────────────────────────────────┐  │
│  │ Cleanup & Restoration                                                  │  │
│  │  • free(pAssemblyStdOut)                                               │  │
│  │  • NtClose(hFile, hPipe)                                               │  │
│  │  • FreeConsole()                                                       │  │
│  │                                                                        │  │
│  │  if (AMSI_PATCH):                                                      │  │
│  │    • RestoreAmsi() - Write original 4 bytes back                       │  │
│  │                                                                        │  │
│  │  if (AMSI_HWBP):                                                       │  │
│  │    • RemoveHwbp() - Clear debug registers                              │  │
│  │    • RemoveVectoredExceptionHandler(VehHandler)                        │  │
│  │                                                                        │  │
│  │  if (ETW_PATCH):                                                       │  │
│  │    • RestoreEtw() - Write original 4 bytes back                        │  │
│  │                                                                        │  │
│  │  • Restore PEB: StdOut/StdErr = original                               │  │
│  └────────────────────────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────────────────────┘
                                   │
                                   │ Return to Beacon
                                   ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│                     Beacon continues execution                               │
│                     (BOF memory cleaned up)                                  │
└──────────────────────────────────────────────────────────────────────────────┘

프록시 방식

방법설명
None직접 API 호출
DraugrDraugr를 통한 스택 위조 API 호출
RegwaitRegisterWaitForSingleObject 콜백 실행

AMSI 우회 방법

방법설명
NoneAMSI 우회 없음
PatchAMSI!AmsiScanBuffer 메모리 패치 (xor rax,rax; ret)
HWBPVEH를 통한 AMSI!AmsiScanBuffer 하드웨어 중단점 후크

ETW 우회 방법

방법설명
NoneETW 우회 없음
PatchNTDLL!NtTraceEvent 메모리 패치 (xor rax,rax; ret)

추가 설정

매개변수설명예시
PipeName어셈블리 출력 캡처를 위한 명명된 파이프 이름P1p3N4m3
AppDomain어셈블리 격리를 위한 사용자 지정 .NET AppDomain 이름Tot4lL3g1t

프록시 로딩 방식 세부사항

1. 직접 (PROXY_NONE)

root@kitploit:~
LoadLibraryA("amsi.dll") → 직접 호출

2. Draugr (PROXY_DRAUGR)

root@kitploit:~
DRAUGR_API(LoadLibraryA, "amsi.dll")
    │
    ├─ 합성 스택 구성
    ├─ 반환 주소 스푸핑
    └─ 간접 실행

3. 타이머 큐 (PROXY_TIMER)

root@kitploit:~
CreateTimerQueue() → CreateTimerQueueTimer(
    callback = LoadLibraryA,
    parameter = "amsi.dll",
    dueTime = 100ms
) → 대기 → DeleteTimerQueueEx()

4. RegisterWait (PROXY_REGWAIT)

root@kitploit:~
CreateEvent() → RegisterWaitForSingleObject(
    event,
    callback = LoadLibraryA,
    context = "amsi.dll"
) → SetEvent() → UnregisterWait()

AMSI 우회 세부사항

메모리 패치 (AMSI_PATCH)

root@kitploit:~
패치 전:                    패치 후:
AmsiScanBuffer:                  AmsiScanBuffer:
  4C 8B DC     mov r11, rsp        48 31 C0     xor rax, rax
  49 89 5B 08  mov [r11+8], rbx    C3           ret
  ...                              ...

결과: 모든 검사는 S_OK(깨끗함) 반환

방법:

  1. 원본 4바이트 저장
  2. 메모리 보호를 RW로 변경
  3. xor rax, rax; ret 쓰기
  4. 메모리 보호 복원
  5. 정리 시 원본 바이트 복원

하드웨어 중단점 (AMSI_HWBP)

root@kitploit:~
설정:
    1. AddVectoredExceptionHandler
    2. RtlCaptureContext
    3. DR0 = AmsiScanBuffer 주소 설정
    4. DR7 중단점 플래그 활성화
    5. NtContinue (컨텍스트 적용)

실행 흐름:
    AmsiScanBuffer 호출됨
        │
        ▼
    #BP 예외 (EXCEPTION_SINGLE_STEP)
        │
        ▼
    VEH 핸들러가 가로챔
        │
        ├─ RIP == AmsiScanBuffer 확인
        ├─ RIP = FindRetInstruction(AmsiScanBuffer) 설정
        ├─ RAX = 0 (S_OK) 설정
        └─ TF(트랩 플래그) 설정
        │
        ▼
    RAX=0으로 반환

ETW 우회 세부사항

NtTraceEvent 패치 (ETW_PATCH_NTDLL)

root@kitploit:~
전:                          후:
NtTraceEvent:                    NtTraceEvent:
  4C 8B D1     mov r10, rcx        48 31 C0     xor rax, rax
  B8 XX XX     mov eax, syscall    C3           ret

출력 캡처 메커니즘

root@kitploit:~
표준 어셈블리 (BOF 없음):         BOF Execute-Assembly:
    Assembly → Console.WriteLine        1. \\.\pipe\{name} 생성
        │                                   │
        ▼                                   ▼
    출력 손실                         2. 파이프를 파일 핸들로 열기
                                           │
                                           ▼
                                        3. PEB 핸들 리디렉션:
                                           • StdOut → 파이프
                                           • StdErr → 파이프
                                           │
                                           ▼
                                        4. 어셈블리 실행
                                           │
                                           ▼
                                        5. ReadFile(파이프)
                                           │
                                           ▼
                                        6. BeaconPrintf → 운영자

우회 기법

탐지 벡터

ETW-TI(Threat Intelligence) 콜백

메모리 보호 변경:

  • NtProtectVirtualMemory 호출은 EtwTiLogReadWriteVm을 통해 기록됨
  • AMSI 패치는 amsi.dll .text 섹션에서 RW→RX 전환 발생
  • ETW 패치는 ntdll.dll .text 섹션에서 RW→RX 전환 발생

탐지: 로드된 모듈의 메모리 보호 변경은 강력한 지표입니다.

커널 콜백

명명된 파이프 생성:

  • \\.\pipe\* 경로를 사용한 NtCreateFile은 미니필터 드라이버에 표시됨
  • 파이프 기반 출력 리디렉션은 탐지 가능한 아티팩트를 생성함

모듈 로딩:

  • EDR 커널 드라이버가 LdrLoadDll 이벤트를 기록함
  • 타이머 큐/RegisterWait 남용은 행동 기반 탐지를 유발할 수 있음

스레드 컨텍스트 조작 (HWBP 방식):

  • 디버거 없이 하드웨어 중단점을 사용하는 것은 의심스러움

행동 지표

  • 숨겨진 콘솔 생성 (AllocConsole + ShowWindow(SW_HIDE))
  • PEB 수정 (StandardOutput/StandardError 핸들 변경)
  • 비콘 프로세스에 CLR 로딩 (네이티브 실행 파일에 비해 비정상적)
  • 사용자 지정 AppDomain 생성 (기본이 아닌 도메인은 의심스러움)
  • 디버거 없이 VEH 핸들러 등록 (HWBP 방식)

사용법

스크립트 로드

root@kitploit:~
Cobalt Strike → Script Manager → Load → BOF_ExecuteAssembly.cna

설정

root@kitploit:~
메뉴: Additionals postex → Execute-Assembly Config

BOF Custom

예제

root@kitploit:~
BOF_ExecuteAssembly --assembly /tmp/Ghostpack-CompiledBinaries/Rubeus.exe --args help

Mimikatz

root@kitploit:~
beacon> help BOF_ExecuteAssembl

Help

컴파일

Dockerfile 사용:

root@kitploit:~
sudo docker build -t ubuntu-gcc-13 .
sudo docker run --rm -it -v "$PWD":/work -w /work ubuntu-gcc-13:latest make

또는 시스템에 nasm, make, mingw-w64(gcc-13 호환)가 설치된 경우:

root@kitploit:~
make

출력: Bin/BOF_ExecuteAssembly.o

탐지 벡터

크레딧

  • anthemtotheego: https://github.com/anthemtotheego/InlineExecute-Assembly/tree/main
  • TheWover: https://github.com/TheWover/donut
도구 다운로드
Timer타이머 큐 콜백 실행
기법우회 대상
간접 시스템 콜사용자 영역 API 후크 (EDR/AV)
Draugr 스택 스푸핑호출 스택 검사 도구
AMSI 패치/HWBP.NET 어셈블리 스캔
ETW 패치이벤트 기반 모니터링
프록시 DLL 로딩LoadLibrary 스택프레임 모니터링
명명된 파이프 가변성파이프 모니터링
사용자 지정 AppDomain기본 AppDomain 모니터링