
SMB1 서버로, C 언어로 작성된 NTLMv2 해시 가로채기용 도구입니다.
NTLMv2 해시를 가로채기 위한 SMB1 서버로, C 언어로 작성되었습니다.
이 프로젝트의 목표는 상태 머신으로서 SMB1 서버를 구현하여 클라이언트의 요청을 올바르게 수락하고 응답함으로써 클라이언트를 속여 NTLM 인증을 완료하게 하고, 이를 통해 클라이언트 자신의 NTLMv2 해시(hashcat/john과 호환되는 형식)를 노출시키는 것입니다.
공격적 보안/레드팀 활동 및 교육 목적(SMB1/NTLM 프로토콜 연구)을 위한 도구로, 소유한 환경 또는 명시적 동의가 있는 환경에서만 독점적으로 사용해야 합니다.
이 서버는 합법적인 SMB1 서버인 척하며 클라이언트를 3단계 상태 머신으로 안내합니다:

| 상태 | 전이 |
|---|---|
1. NEGOTIATE | SMB NEGOTIATE가 도착하면, 서버 응답에 따라 상태가 2. CHALLENGE로 이동 |
2. CHALLENGE | NTLM_NEGOTIATE가 도착하면, 서버 응답에 따라 상태가 3. AUTH로 이동 |
3. AUTH | NTLM_AUTH가 도착하면, 서버 응답에 따라 상태가 1. NEGOTIATE로 복귀 |
구현 수준에서는 4바이트로 구성된 외부 NetBIOS "엔벨로프"를 고려해야 하며, 마지막 3바이트는 SMB 패킷의 길이(바이트 단위)를 나타냅니다.
각 클라이언트 연결은 상태 구조체(server.h의 client_t)를 통해 추적되며, 상태 머신의 상태 외에도 다음을 유지합니다:
rx_buf)와 그 길이 — 소켓에서 읽었지만 아직 완전히 처리되지 않은 데이터를 버퍼링tx_buf, 오프셋 tx_off) — 클라이언트로 보낼 데이터를 버퍼링하지만 아직 완전히 전송되지 않음netbios_header_recv 및 netbios_msg_len 필드데이터 수신 시 최소 4바이트(NetBIOS 헤더)가 수신되었는지 확인하고, SMB 메시지의 길이를 결정하며, 상태 필드를 업데이트한 후 마지막으로 메시지를 처리하여 다음 수신을 위해 클라이언트 상태를 업데이트합니다.
서버의 메인 루프는 poll()을 기반으로 하여 여러 연결을 비차단 방식으로 동시에 처리합니다:

NTLM 인증이 완료되면 서버는 화면에([INTERCEPTED] ...) 사용자 이름, 호스트 이름, 도메인 및 캡처된 NTLMv2 해시를 다음 형식으로 출력합니다:
username::domain:server_challenge:ntlmv2_response:blob
hashcat(모드 -m 5600) 또는 john과 같은 크래킹 도구와 함께 사용할 준비가 된 형식입니다.
gcc/clang) 및 POSIX 툴체인(코드는 BSD 소켓, poll(), signal() 등을 사용하므로 Linux/Unix 계열 환경을 대상으로 함).Makefile이 포함되어 있습니다:
make # 메인 서버 빌드 -> ./impostor
make debug # 디버그 빌드(심볼, -O0, AddressSanitizer/UBSan)
make clean # 생성된 오브젝트 파일 및 실행 파일 제거
make run # 서버 빌드 및 실행
또는 동등한 수동 컴파일 명령은 다음과 같습니다:
gcc -o impostor server.c smb1_parser.c spnego_decoder.c asn1_parser.c ntlm_parser.c
./impostor [port]
port(선택 사항): 서버가 수신 대기하는 TCP 포트. 생략하면 server.h에 정의된 기본 포트(SERVER_PORT, 9000)가 사용됩니다. 1~65535 사이의 값이어야 합니다.시작 시 서버는 배너, 버전 및 구성 정보(포트, 최대 클라이언트 수)를 출력한 후 연결을 수신 대기합니다. NTLMv2 해시가 캡처되면 가로챈 데이터(사용자 이름, 호스트 이름, 도메인, 해시)가 화면에 출력됩니다. 서버는 intHandler가 처리하는 Ctrl+C(SIGINT)로 중지할 수 있습니다.
___ ___ _ ___
|_ _|_ __ ___ _ __ / _ \ ___| |_ / _ \ _ __
| || '_ ` _ \| '_ \| | | / __| __| | | | '__|
| || | | | | | |_) | |_| \__ \ |_| |_| | |
|___|_| |_| |_| .__/ \___/|___/\__|\___/|_|
|_| (v.1.0) by Lcky
[*] Version: 1.0
[*] Author: Lcky <luca9vinci at gmail dot com>
[*] Server Info
Port: 9090
Max Clients: 50
[*] Listening on port 9090
[*] Waiting for connections...
[INTERCEPTED] Username: test
[INTERCEPTED] Hostname: KALILINUX-2023-02
[INTERCEPTED] Domain : WORKGROUP
[INTERCEPTED] Hash : test::WORKGROUP:c4ba87a265de9e09:3482d0efa64fc09a94e44faa83d2a936:01010000000000009A3DE84B6235DD01D36FD06DFF4D64BB000000000200080038004E004900490001001E00570049004E002D00310046005800340055004D005000530034005400420004003400570049004E002D00310046005800340055004D00500053003400540042002E0038004E00490049002E004C004F00430041004C000300140038004E00490049002E004C004F00430041004C000500140038004E00490049002E004C004F00430041004C0008003000300000000000000000000000000000000CAFEB574B56CB6139E261228FBFE3075B4FA9393A3B71031AF3280F4D5A27D00A0010000000000000000000000000000000000009001C0063006900660073002F003100320037002E0030002E0030002E00310000000000
^C
[*] Stopping the server...
| 파일 | 설명 |
|---|
server.c / server.h | 진입점, TCP 리스너 설정, 클라이언트 상태 머신, poll() 기반 메인 루프, RX/TX 버퍼링, 가로챈 해시 출력 |
smb1_parser.c / smb1_parser.h | SMB1 패킷(헤더, NEGOTIATE, SESSION_SETUP 명령, flags/flags2 등)의 파싱/구축 |
spnego_decoder.c / spnego_decoder.h | SMB 메시지에 포함된 SPNEGO 토큰(인증 메커니즘 협상, NTLMSSP 블롭 추출) 디코딩 |
asn1_parser.c / asn1_parser.h | SPNEGO 디코더가 ASN.1 구조 트리를 구축하는 데 사용하는 최소 ASN.1 DER 파서 |
ntlm_parser.c / ntlm_parser.h | NTLMSSP 메시지(NEGOTIATE, CHALLENGE, AUTHENTICATE) 파싱 및 사용자 이름, 도메인, 호스트 이름, NTLMv2 응답 추출 |
endianness.h | 엔디언 처리 유틸리티(런타임 시 리틀/빅 엔디언 변환) |
test.c, test2.c | 파서용 테스트/실험 파일 |
docs/ | 다이어그램 및 보조 자료(상태 머신 스키마, 메인 루프) |