
레드팀을 위한 Active Directory 시간 탐지 프로토콜. Kerberos, SMB, NTLM 및 CLDAP을 통한 은밀한 추출.

skewrun은 레드 팀을 위한 Active Directory 시간 발견 도구 키트입니다. 네트워크 프로토콜(CLDAP, SMB, NTP, Kerberos, NTLM)을 통해 동적으로 도메인 컨트롤러의 시간을 확인하고, libfaketime(LD_PRELOAD)을 통해 명령을 실행하여 실행된 바이너리가 정확한 DC 시간을 사용하도록 속입니다.
이를 통해 Kerberos KRB_AP_ERR_SKEW (Clock Skew Too Great) 오류를 해결하여, 시스템 시간을 변경하기 위해 루트 권한이 필요 없이 대상 Windows 도메인과 심하게 동기화되지 않은 Linux 공격 시스템에서 Impacket 또는 NetExec 같은 도구를 실행할 수 있습니다.
v0.9.0부터 Skewrun은 라이브러리 우선 아키텍처로 구축되었습니다:
ad-time: AD 프로토콜에서 은밀하게 시간을 추출하는 순수 Rust 라이브러리 크레이트입니다. 다른 Rust 임플란트나 도구에 기본적으로 포함될 수 있습니다.skewrun: ad-time 라이브러리를 조정하고 libfaketime으로 대상 프로세스를 래핑하는 CLI 바이너리입니다.# 사전 빌드된 정적 바이너리 (Rust 도구 체인 불필요)
wget https://github.com/JVBotelho/skewrun/releases/latest/download/skewrun-x86_64-linux-musl
chmod +x skewrun-x86_64-linux-musl
sudo mv skewrun-x86_64-linux-musl /usr/local/bin/skewrun
# crates.io에서
cargo install skewrun
# 소스에서
git clone https://github.com/JVBotelho/skewrun && cd skewrun && cargo build --release
참고: 시스템에 libfaketime이 설치되어 있어야 합니다 (예: apt-get install libfaketime).
# 기본 동작 (CLDAP -> SMB -> NTP 시도)
skewrun 10.10.10.100 -- impacket-getTGT -dc-ip 10.10.10.100 domain.local/user:pass
# 특정 방법 강제 사용
skewrun 10.10.10.100 -m cldap,ntlm,kerberos -- netexec smb 10.10.10.100
# 오프셋만 출력 (셸 스크립팅에 유용)
skewrun 10.10.10.100 --print-offset
# 오프라인 모드: 알려진 오프셋을 수동으로 제공
skewrun --offset "+3.450s" -- impacket-getTGT ...
# 방법 간 지터 조정 (기본값: sigma=0.4, base=8000ms; sigma=0은 지터 비활성화)
skewrun 10.10.10.100 --jitter-sigma 0.2 --jitter-base-ms 5000 -- impacket-getTGT ...
use ad_time::protocols::cldap::CldapSource;
use ad_time::time_src::TimeSource;
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let src = CldapSource;
let addr = "10.10.10.100:389".parse()?;
let offset_us = src.fetch(addr, Duration::from_secs(3))?;
println!("DC 오프셋: {} µs", offset_us);
Ok(())
}
각 프로토콜 모듈(kerberos, ntlm, cldap, smb, ntp)은 독립적이며 맞춤형 레드 팀 도구에 사용하기 위해 추출 가능합니다.
Skewrun은 DC를 쿼리하여 정확한 마이크로초 오프셋 (DC_Time - Local_Time)을 계산합니다. 그런 다음 FAKETIME 환경 변수를 설정하고 LD_PRELOAD를 사용하여 대상 명령에 libfaketime을 주입합니다.
LD_PRELOAD는 동적으로 링크된 libc 호출(예: clock_gettime)을 가로채는 데 의존합니다. 정적으로 컴파일된 바이너리(예: 많은 Go 또는 Rust 도구)에서 skewrun을 사용하려고 하면 libfaketime이 시간 함수를 후킹하는 데 조용히 실패합니다. Skewrun은 정적 바이너리를 실행하려고 시도하는 것을 감지하면 경고합니다.
목표는 표준 Windows 유선 트래픽과 조화를 이루고 DC의 포렌식 발자국을 최소화하는 것입니다.
사용된 방법과 관계없이: 모든 아웃바운드 소켓은 TCP 핸드셰이크 전에 TTL=128을 설정하고 Nagle을 활성화(TCP_NODELAY=0)하여 Linux 기본값(TTL=64, Nagle 꺼짐) 대신 Windows 클라이언트의 네트워크 스택 지문과 일치시킵니다. 이는 수동적 관찰자(p0f, Zeek conn.log)가 플래그를 지정할 수 있던 부분입니다. 방법 간 지연은 (고정된 무작위 범위가 아닌) CSPRNG 기반 로그-노멀 지터를 사용하며, 반복 실패 시 지수 백오프를 적용하여 고정된 지터 대역이 연결 로그에 남기는 균일한 타이밍 시그니처를 피합니다. 자세한 내용은 위의 --jitter-sigma 및 --jitter-base-ms를 참조하세요.
cargo test # 단위 + 속성 테스트
cargo +nightly fuzz run fuzz_parse_krb_error # Linux/macOS 전용
모든 네트워크 지향 파서(parse_krb_error, parse_cldap_search_response, parse_ntlm_type2, parse_negotiate_response, parse_ntp_timestamp)는 proptest를 사용한 패닉 안전 속성 테스트와 CI에서 퍼즈 테스트가 수행됩니다. BER 정수 인코딩은 전체 i32 범위에 걸쳐 DER 최소성 및 부호 정확성에 대해 검증되며, RFC 4120에 따라 음수 etype 값을 포함합니다. 퍼즈 대상과 코퍼스는 fuzz/에 있습니다.
MIT 또는 Apache 2.0 중에서 선택하여 듀얼 라이선스가 부여됩니다.
| 방법 | 프로토콜 | 포트 | OPSEC 참고사항 (EDR/NDR 가시성) |
|---|
| cldap (기본값) | CLDAP | UDP/389 | 매우 은밀. 보편적으로 허용됨. 표준 LDAP rootDSE 진단 쿼리(objectClass=* 기본 검색)를 전송하여 ldapsearch, PowerShell AD cmdlet 및 모니터링 도구의 기준과 일치합니다. 일반적인 관리 속성으로 속성 목록을 희석하고 요청마다 속성 순서를 무작위화하여 정적 NDR 시그니처를 깨뜨립니다. |
| smb (기본값) | SMB2 | TCP/445 | 은밀. SMB2 NEGOTIATE 응답에서 시간을 추출합니다. Windows 10/11 클라이언트 동작과 일치하도록 PREAUTH_INTEGRITY_CAPABILITIES(SHA-512)를 사용하여 SMB 3.1.1을 협상합니다. |
| ntp (기본값) | SNTP | UDP/123 | 표준. 기본 RFC 4330. 모든 클라이언트에서 매우 일반적인 트래픽입니다. |
| ntlm | SMB2 | TCP/445 | 은밀. SMB2 SESSION_SETUP을 악용하여 MsvAvTimestamp가 포함된 NTLM Type 2 챌린지를 얻습니다. Type 3 전에 TCP 연결을 끊어 이벤트 ID 4625(로그온 실패)가 생성되지 않도록 합니다. Windows 10/11 플래그를 에뮬레이트합니다. |
| kerberos | Kerberos | TCP/88 | 시끄러움. 존재하지 않는 사용자에 대한 AS-REQ를 전송합니다. 적절한 두 구성 요소 sname을 인코딩하고, cname을 회전시키며(예: admnistrator 오타), till을 Windows 하드코딩 상수 20370913024805Z로 설정하고(로컬 클록 산술이 아님 - ADR-0002 참조), nonce를 무작위화합니다. 항상 이벤트 4768/0x6(알 수 없는 보안 주체에 대한 사전 인증 실패)을 생성하며, 이는 감사 정책에 관계없이 SIEM으로 내보내집니다. cname이 구성된 트립와이어와 일치하는 경우 허니 계정 경고를 유발할 수 있습니다. |