제품

공격자가 액세스 토큰 조작(ATT&CK T1134)을 악용하는 방법

이전 블로그 글에서는 보안 실무자를 대상으로 Windows 액세스 토큰을 다루며 다음 내용을 살펴보았습니다.

  • 로그인 세션과 액세스 토큰의 관계
  • Windows 환경에서 네트워크 인증이 작동하는 방식

Windows 보안의 몇 가지 핵심 개념을 다뤘으므로, 이제 이 지식을 바탕으로 공격자가 정상적인 Windows 기능을 악용해 측면 이동을 수행하고 Active Directory 도메인을 침해하는 방식을 살펴보겠습니다.

이 블로그 글에서는 가능한 경우 특정 Windows 네트워크 인증 프로토콜(예: NTLM 및 Kerberos)의 작동 방식을 의도적으로 추상화했습니다. 따라서 이러한 프로토콜에만 고유한 동작이 아래에 설명된 동작과 다른 경우가 있을 수 있습니다. 또한 Kerberos 인증 프로토콜을 어느 정도 이해하고 있다고 가정합니다1.

또한 이 블로그 시리즈에서 다루는 내용은 BlackHat 2020 발표인 “Detecting Access Token Manipulation”에 사용되었습니다. 발표 자료는 여기에서, 슬라이드는 여기에서 확인할 수 있습니다.

액세스 토큰 조작(ATT&CK 기법: T1134)

이전 블로그 게시물 에서는 로컬 환경과 분산 애플리케이션 모두에서 로그인 세션과 액세스 토큰이 작동하는 기본 원칙을 설명했습니다. 이 섹션에서는 공격자가 액세스 토큰을 악용하고 Windows 도메인의 근본적인 신뢰 관계를 표적으로 삼아 전체 네트워크를 침해하는 방식을 설명합니다. 이 섹션의 목적은 시뮬레이션된 침해의 맥락에서 공격자가 사용하는 액세스 토큰 조작 기법을 설명하는 것입니다.

액세스 토큰 조작에 관한 훌륭하고 광범위한 연구는 이미 많이 축적되어 있으며, 이 글 전반에서 관련 자료를 자유롭게 연결할 예정입니다. 이 블로그 글은 액세스 토큰, 로그인 세션 및 캐시된 자격 증명의 관계를 통해 액세스 토큰 조작을 살펴보는 다른 접근 방식을 취함으로써 기존 지식 체계를 확장하고자 합니다. 저자의 견해로는 이러한 관계를 고려하지 않는 토큰 조작 설명은 빙산의 일각에 불과합니다. 따라서 이 글에서 정의하는 액세스 토큰 조작의 범위는 일반적으로 이해되는 범위보다 훨씬 넓을 수 있습니다.

초기 보안 침해

공격자가 스피어 피싱을 통해 네트워크에서 거점을 확보하면, 일반적으로 침해된 사용자의 보안 컨텍스트에서 실행되는 셸을 얻게 됩니다. 이는 새 프로세스를 생성하거나 메모리에 직접 인젝션하여 달성할 수 있으며, 이는 페이로드에 따라 달라집니다. 하지만 결과는 같습니다. 공격자 코드는 침해된 사용자의 액세스 토큰을 가진 프로세스에서 실행됩니다.

즉, 모든 로컬 액세스 검사는 침해된 사용자의 액세스 토큰을 사용하고, 모든 원격 인증 시도는 침해된 사용자의 캐시된 자격 증명을 사용합니다2. 따라서 공격자는 로컬과 네트워크 전반에서 침해된 사용자가 수행할 수 있는 모든 작업을 수행할 수 있습니다. 예를 들어 내부 웹 애플리케이션이 Windows SSO를 사용하는 경우 공격자는 해당 사용자인 것처럼 애플리케이션에 액세스할 수 있습니다.

토큰 조작: '가능성의 기술'

일반적으로 공격자는 침해된 엔드포인트에서 다른 호스트로 가능한 한 빠르게 이동하려고 합니다3. 토큰 조작 관점에서 측면 이동을 고려할 때 공격자에게는 사실상 세 가지 선택지가 있으며4, 각 선택지는 아래 그림과 같이 액세스 토큰, 로그인 세션 및 캐시된 자격 증명 간의 근본적인 관계에 의해 제약됩니다.

1-access-tokens-logon-sessions-blog-access-token-manipulation.png

그림 1: 액세스 토큰, 로그인 세션 및 캐시된 자격 증명의 관계


공격자가 Windows SSO를 통해 측면 이동하려면 이 세 연결 고리가 모두 갖춰져야 합니다. 예를 들어 대상 자격 증명을 기반으로 하는 로그인 세션에 연결된 토큰의 핸들을 보유해야 합니다. 그렇지 않으면 공격자의 이동 가능성은 새 연결 고리, 예를 들어 새 로그인 세션을 생성하거나 기존 연결 고리, 예를 들어 캐시된 자격 증명이나 액세스 토큰이 가리키는 로그인 세션을 수정하는 데 달려 있습니다. 이러한 제약 사항은 아래 세 가지 선택지에서 더 자세히 설명합니다.

1. 이미 로그인한 권한 있는 사용자의 토큰 탈취(비네트워크 로그인)

다른 권한 있는 사용자가 이미 침해된 호스트에 로그인한 경우, 공격자는 권한을 상승시키고 해당 사용자를 나타내는 액세스 토큰의 핸들을 획득할 수 있습니다. 공격자가 탈취한 토큰을 가장하든 새 프로세스를 시작하든, 해당 토큰이 비네트워크 로그인 세션에 연결되어 있다면 캐시된 자격 증명을 갖게 됩니다. 따라서 공격자는 다른 호스트에 원격 인증을 수행할 수 있습니다5. 이 기법을 사용하면 공격자는 다른 사용자의 자격 증명을 이용해 Windows SSO를 통해 네트워크 전반의 원격 호스트에 액세스할 수 있으며, 자격 증명을 덤프하지 않고도 피벗할 수 있습니다6

토큰 조작 공격은 일반적으로 측면 이동, 즉 이 글에서 다루는 목적과 로컬 권한 상승이라는 두 가지 별개의 목표와 관련됩니다7. 토큰 탈취는 후자와 연관되는 경향이 있습니다. 예를 들어 원격 인증에 캐시된 자격 증명을 사용하기보다 로컬 액세스 검사를 우회할 목적으로 토큰을 탈취하거나 가장하는 경우입니다. 따라서 이 블로그 글에서는 이를 더 자세히 다루지 않지만, 다음 자료가 유용한 추가 참고 자료가 될 수 있습니다.

https://labs.f-secure.com/assets/BlogFiles/mwri-security-implications-of-windows-access-tokens-2008-04-14.pdf

2. 탈취한 자격 증명으로 새 로그인 세션을 생성하고, 반환된 토큰을 가장하거나 이를 사용해 새 프로세스 생성

이 경우에는 권한 있는 사용자가 이미 로그인되어 있지 않아, 이에 상응하는 유용한 액세스 토큰이나 로그인 세션도 없습니다. 하지만 공격자는 여전히 보안 컨텍스트를 변경할 방법을 찾아야 합니다.

따라서 공격자는 다른 위치에서 자격 증명을 찾아 탈취한 자격 증명을 사용해 침해된 사용자인 것처럼 로그인 세션을 생성해야 합니다.Windows는 특정 로그인 유형에 대해 자격 증명을 자동으로 캐시하므로, 공격자는 이제 탈취한 자격 증명을 기반으로 하는 새로 생성된 액세스 토큰을 획득할 수 있습니다. 공격자는 침해된 사용자를 나타내는 토큰의 핸들을 확보하면 표준 Windows SSO 프로세스를 활용하여 다른 호스트에서 인증할 수 있습니다. 

일반적으로 공격자는 Kerberoasting을 수행하거나 네트워크 공유, SharePoint, 내부 위키, 엔터프라이즈 GitHub, Zendesk 등 액세스 가능한 모든 리소스에서 보호되지 않은 평문 자격 증명을 검색하여 평문 자격 증명을 찾습니다8.

3. 현재 액세스 토큰에 연결된 캐시된 자격 증명을 탈취한 자격 증명으로 변경(예: API를 통한 정상적 변경 또는 lsass 메모리직접 수정하는 ‘비정상적’ 방식 사용

이 시나리오에서 공격자는 새 로그인 세션을 만드는 대신 현재 액세스 토큰, 즉 로그인 세션에 연결된 캐시된 자격 증명을 수정합니다. 이후 살펴보겠지만, 많은 Windows 보안 지원 공급자(SSP)는 이를 수행하는 기본 제공 방식을 제공하며, 이러한 방식에는 상승된 권한이 필요하지 않습니다.

또는 공격자는 ‘직접적인’ 방식을 택해 lsass에 저장된 캐시된 자격 증명을 수동으로 수정할 수 있습니다. 이를 위해서는 OpenProcess를 통해 lsass에 대한 쓰기 핸들(예: PROCESS_VM_WRITE)을 획득할 상승된 권한이 필요합니다. 이는 이후 다룰 패스 더 해시 유형 공격에서 일반적으로 사용됩니다.

액세스 토큰 조작 공격

이 블로그 글에서는 공격자가 사용하는 네 가지 일반적인 기법을 살펴봅니다. 모두 위의 세 번째 선택지를 변형한 기법으로 분류할 수 있습니다.

  • NETONLY 플래그
  • 패스 더 티켓
  • 패스 더 해시
  • 오버패스 더 해시

1. NETONLY 플래그

Windows API는 지정한 사용자 또는 보안 주체의 새 로그인 세션을 만들기 위한 LogonUser 함수를 제공합니다9.

BOOL LogonUserW(
LPCWSTR lpszUsername,
LPCWSTR lpszDomain,
LPCWSTR lpszPassword,
DWORD dwLogonType,
DWORD dwLogonProvider,
PHANDLE phToken
);

여기서 주목해야 할 핵심 매개변는 수행할 로그인 유형을 지정하는 dwLogonType입니다. 예를 들어 사용자가 물리적으로 자신의 워크스테이션에 로그인하는 경우 이 값은 LOGON32_LOGON_INTERACTIVE로 설정됩니다. 지정된 로그인 유형은 반환되는 토큰의 유형권한을 결정합니다.

예를 들어 대화형 로그인의 경우 LogonUserW는 기본 액세스 토큰을 반환하며, UAC가 활성화된 경우 이 토큰은 필터링된 토큰이 됩니다. 즉, 중간 무결성 수준이며 상승되지 않은 토큰입니다. 다만 사용자가 로컬 관리자 계정, 예를 들어 *-500 SID인 경우에는 예외입니다. 이 경우 Windows는 자동으로 상승된 토큰을 반환합니다10.

네트워크 로그인(LOGON32_LOGON_NETWORK)의 경우 가장 토큰이 반환됩니다. 일반적으로 서버가 원격 클라이언트를 대신해 작업을 수행할 때 사용되기 때문입니다. 또한 사용자가 로컬 관리자 그룹에 속한 경우 토큰은 상승되며 모든 권한이 활성화됩니다11

LogonUser의 이러한 경우의 수는 아래 표에 정리되어 있습니다.

dwLogonType

반환되는 토큰

자격 증명 캐시 여부

반환된 토큰이 상승되었는지 여부(관리자인 경우)

대화형(LOGON32_LOGON_INTERACTIVE)

기본

아니요(UAC 적용)

대화형(로컬 관리자 계정, 예: rid-500)

기본

네트워크(LOGON32_LOGON_NETWORK)

가장

아니요12

예(+ 모든 권한 활성화)

네트워크(로컬 관리자 계정, 예: rid-500)

가장

아니요

원격 UAC 설정에 따라 다름13

표 1: 해당 dwLogonType에 따른 LogonUser의 경우의 수


핵심은 LogonUser가 새로 생성된 토큰의 핸들을 반환하며, 이 토큰은 이제 가장에 사용할 수 있다는 점입니다. 

반환된 토큰이 기본 토큰이면, 먼저 TokenType으로 TokenImpersonate를 전달하여 DuplicateTokenEx를 통해 가장 토큰으로 변환해야 합니다14.

BOOL DuplicateTokenEx(
HANDLE hExistingToken,
DWORD dwDesiredAccess,
LPSECURITY_ATTRIBUTES lpTokenAttributes,
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
TOKEN_TYPE TokenType,
PHANDLE phNewToken
);


이후 SetThreadToken 함수를 사용하여 반환된 가장 토큰을 현재 스레드에 할당할 수 있습니다.

BOOL SetThreadToken(
PHANDLE Thread,
HANDLE Token
);

또는 Windows API는 호출 스레드가 전달된 토큰으로 표시되는 사용자의 보안 컨텍스트를 가장할 수 있도록 하는 ImpersonateLoggedOnUser 함수를 제공합니다.

BOOL ImpersonateLoggedOnUser(
HANDLE hToken
);

ImpersonateLoggedOnUser에는 전달된 토큰의 유형을 자동으로 확인하고, 기본 토큰이 전달된 경우 이를 가장 토큰으로 변환한다는 추가 이점이 있습니다. 이 토큰 유형은 스레드가 가장에 사용할 수 없으므로, 이 작업은 NtDuplicateToken을 통해 수행됩니다15.

방어 회피 관점에서 보면, 이 두 가장 API는 문서화되지 않은 시스템 호출 NtSetInformationThread의 경량 래퍼라는 점에 유의해야 합니다. 예를 들어 ThreadInformationClassThreadImpersonationToken을 전달하여 호출할 수 있습니다. 따라서 공격자가 https://github.com/jthuraisamy/SysWhispers와 같은 기법을 통해 직접 시스템 호출을 사용하고 사용자 모드 후크를 우회하기에 좋은 대상입니다.

또한 Windows에는 가장과 관련된 엄격한 규칙이 있다는 점을 강조할 필요가 있습니다. 아래는 ImpersonateLoggedOnUser의 MSDN 페이지에 나열된 규칙입니다.

ImpersonateLoggedOnUser를 포함한 모든 가장 함수는 다음 중 하나가 참인 경우 요청된 가장을 허용합니다.
- 토큰의 요청된 가장 수준이 SecurityImpersonation보다 낮은 경우. 예를 들어 SecurityIdentification 또는 SecurityAnonymous인 경우
- 호출자에게 SeImpersonatePrivilege 권한이 있는 경우
- 프로세스 또는 호출자의 로그인 세션에 있는 다른 프로세스가 LogonUser 또는 LsaLogonUser 함수를 통해 명시적 자격 증명을 사용하여 토큰을 생성한 경우
인증된 ID가 호출자의 ID와 같은 경우

또한 가장된 토큰의 무결성 수준은 호출 프로세스의 무결성 수준보다 낮거나 같아야 합니다. 그렇지 않으면 가장 호출도 실패합니다16. 따라서 상승되지 않은 공격자가 탈취한 자격 증명을 사용하여 관리자 사용자를 대화형으로 로그인시키고 UAC가 활성화되어 있다고 가정하면, 상승되지 않은 토큰, 즉 필터링된 토큰을 반환받습니다. 그러므로 반환된 사용자를 가장하고 측면 이동하는 등의 작업에 문제가 없습니다.

“흥미로운 /NETONLY 플래그”17

하지만 공격자는 탈취한 자격 증명을 사용하여 사용자를 로그인하려 해도 실패할 수 있습니다. 자격 증명은 유효하지만 해당 계정에 특정 워크스테이션에 로그인할 권한이 없거나, 자격 증명이 다른 도메인에서만 유효한 경우 등 여러 이유가 있을 수 있습니다. 또한 공격자는 특정 상황에서 매우 비정상적으로 보일 수 있으므로, 권한이 매우 높은 계정으로 로그인하는 것 자체를 피하고 싶을 수 있습니다. 예를 들어 도메인 관리자가 권한이 낮은 업무 사용자 호스트에 로그인하는 것은 매우 의심스러워야 합니다18

이 시나리오에서는 LOGON32_LOGON_NEW_CREDENTIALS 플래그가 공격자에게 도움이 됩니다. 공격자가 이 플래그와 유효한 자격 증명 집합, 예를 들어 파일 공유를 살피다 찾아낸 자격 증명을 전달하여 LogonUserW 함수를 호출하면, Windows는 호출자가 현재 토큰을 복제하되 탈취한 자격 증명을 캐시하는 New Credentials 로그인 세션이라는 로그인 세션을 가리키도록 합니다. 그 결과 사용자는 로컬에서 동일한 보안 컨텍스트를 계속 유지합니다. 예를 들어 동일한 액세스 토큰의 복사본을 계속 보유하지만, 이 토큰은 로그인 세션을 가리킵니다. 반면 원격 인증을 시도하면 LogonUserW 호출에 전달된 새 자격 증명이 제공됩니다19. 이는 아래 다이어그램에 설명되어 있습니다.

2-logon-new-credentials-blog-access-token-manipulation.gif

그림 2: LOGON32_LOGON_NEW_CREDENTIALS 플래그의 내부 작동 방식


따라서 LOGON32_LOGON_NEW_CREDENTIALS 플래그는 현재 액세스 토큰이 다른 로그인 세션, 즉 다른 자격 증명을 가리키도록 하는 기본 제공 메커니즘을 제공합니다20.

LOGON32_LOGON_NEW_CREDENTIALS 플래그를 사용해 LogonUserW를 호출할 때는 자격 증명을 검증하지 않는다는 점에 유의해야 합니다. 자격 증명은 완전히 잘못된 값일 수도 있습니다. 자격 증명은 원격 인증 요청이 발생할 때만 도메인 컨트롤러에서 검증됩니다. 

추가 예로, 오픈 소스 .NET C2 프레임워크 Covenant의 MakeToken 작업 코드를 빠르게 검토하면 정확히 동일한 방식을 사용한다는 것을 알 수 있습니다. 이 작업은 사용자 이름과 비밀번호 조합을 가져와 LOGON32_LOGON_NEW_CREDENTIALS 플래그를 전달함으로써 새 로그인 세션과 토큰을 생성한 후 반환된 토큰을 가장합니다. 

또한 LOGON_NETCREDENTIALS_ONLY를 dwLogonFlags로 전달하면 CreateProcessWithLogonW를 통해 정확히 같은 동작을 재현할 수 있습니다21.

BOOL CreateProcessWithLogonW( 
LPCWSTR lpUsername,
LPCWSTR lpDomain,
LPCWSTR lpPassword,
DWORD dwLogonFlags,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);

핵심 차이점은 앞서 설명한 프로세스 내 가장과 달리, 이 방식은 반환된 토큰으로 새 프로세스를 생성한다는 점입니다. 실제로 Windows 기본 제공 유틸리티인 runas는 CreateProcessWithLogonW를 단순히 래핑한 것이며, /NETONLY 플래그는 아래와 같이 네트워크 전용 자격 증명이 다른 새 프로세스를 생성하는 기본 제공 방법을 제공합니다.

3-using-the-runas-blog-access-token-manipulation.png

그림 3: astro\cosmo 사용자로 새 프로세스를 생성하되, 다른 캐시된 자격 증명을 사용하는 runas /NETONLY 플래그의 예시


앞서 설명한 방식과 정확히 동일하게, 새 명령 프롬프트는 로컬에서 동일한 사용자로 실행되는 것처럼 보입니다. 즉, 로컬 액세스 검사에 사용되는 토큰에 캐시된 특성은 동일하므로 whoami는 astro\cosmo를 반환합니다. 하지만 모든 원격 인증 시도는 ASTRO\Administrator 사용자를 위해 탈취한 자격 증명을 사용하여 수행됩니다. 

이러한 로그인 세션은 SysInternals의 LogonSessions 도구를 사용하여 볼 수 있습니다. NewCredentials 플래그로 생성된 로그인 세션은 아래와 같이 Logon type 필드로 식별할 수 있습니다.

4-logon-session-blog-access-token-manipulation.png

그림 4: 일반적으로 NETONLY 플래그로 생성되는 NewCredentials 로그인 세션의 예시


또한 NETONLY 가젯을 통해 생성된 경우처럼 비정상적인 NewCredentials 로그인 세션은 Windows 이벤트 로그에 아티팩트를 남깁니다. 이러한 아티팩트는 이벤트 ID 4642 및 9인 LogonType으로 식별할 수 있습니다. 아래 이미지에 예시가 나와 있습니다.

5-windows-event-log-blog-access-token-manipulation.png

그림 5: 일반적으로 NETONLY 플래그로 생성되는 이벤트 ID 4624의 Windows 이벤트 로그 예시


원래 사용자는 SubjectUserName 필드에 표시되고, 지정된 네트워크 전용 자격 증명, 즉 전달된 자격 증명은 TargetOutboundUser/DomainName 필드에 표시된다는 점에 유의해야 합니다22.

자동 상승

로컬 권한 상승 관점에서 또 하나의 특이점은 rid-500 계정의 경우 CreateProcessWithLogonW가 대화형 로그인에 대해 반환된 토큰을 자동으로 상승시킨다는 점입니다. 즉, UAC를 무시합니다. 따라서 CreateProcessWithLogonW에 로컬 또는 도메인 관리자 계정을 전달하면 중간 무결성 또는 상승되지 않은 컨텍스트에서 상승된 프로세스를 실행할 수 있습니다.

이 동작은 runas를 사용하여 확인할 수 있습니다. 예를 들어 로컬 관리자 계정으로 프로세스를 생성하기 위해 runas /user:"Administrator" cmd.exe를 사용하면 결과 프로세스는 상승됩니다. 예를 들어 높은 무결성 수준이 됩니다. 반면 여전히 로컬 관리자 그룹에 속하지만 rid-500 계정이 아닌 계정을 사용하면 결과 프로세스는 상승되지 않습니다. 즉, 필터링된 토큰 또는 중간 무결성 수준이 됩니다.

이 동작은 표 1에서 LogonUserW에 대해 나열한 경우의 수와 일치합니다. 따라서 상승되지 않은 공격자는 네트워크 로그인을 통해 rid-500 계정이 아닌 관리자 사용자를 로그인시키고, 모든 권한이 활성화된 상승된 토큰을 받을 수도 있습니다.

하지만 앞서 설명한 가장 규칙에 따르면, 상승된 토큰은 호출자보다 더 높은 무결성 수준을 가지므로, 해당 토큰을 가장하려는 모든 시도는 실패해야 합니다. 따라서 공격자는 실제로 이 토큰으로 아무것도 할 수 없어야 합니다. 그럼에도 상승된 토큰을 복제하고, 복사된 토큰의 무결성 수준을 중간으로 낮춘 다음, isElevated가 여전히 true인 상태에서23 상승되지 않은 중간 무결성 컨텍스트에서 상승된 토큰을 가장하는 것이 실제로 가능합니다24. 따라서 가장 토큰 관점에서는 계정이 rid-500 계정인지와 관계없이 특정 계정만 상승시키는 기본 Windows 동작을 우회하고 상승된 토큰을 가장할 수 있습니다.

프로세스 생성

기본적으로 자식 프로세스를 생성하면, 현재 다른 보안 컨텍스트를 가장하고 있더라도 자식 프로세스는 기본 토큰을 상속한다는 점에 유의해야 합니다25. 예를 들어 SYSTEM 토큰을 가장한 상태에서CreateProcess()를 호출하면, 해당 프로세스는 스레드의 SYSTEM 보안 컨텍스트를 상속하는 대신 기본 프로세스 토큰의 복사본을 여전히 상속합니다26.

따라서 공격자가 다른 보안 컨텍스트에서 새 프로세스를 생성하려면 다음 중 하나를 수행해야 합니다.

  • 앞서 설명한 것처럼 명시적 자격 증명과 함께 CreateProcessWithLogonW를 사용합니다. 
  • CreateProcessWithTokenW 또는 CreateProcessAsUserW를 호출하고 토큰의 핸들을 전달합니다. 예를 들어 LogonUser가 반환한 토큰이나 더 일반적으로는 탈취한 토큰을 전달할 수 있습니다.

이 두 함수에는 새 프로세스의 보안 컨텍스트를 나타내는 토큰의 핸들을 전달할 수 있습니다.27

BOOL CreateProcessWithTokenW(
HANDLE hToken,
DWORD dwLogonFlags,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
BOOL CreateProcessAsUserW(
HANDLE hToken,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);

예를 들어 CreateProcessAsUserW는 성공적으로 로그인한 후 운영 체제 자체가 사용자의 셸을 생성하는 데 일반적으로 사용됩니다. 사용자가 CreateProcessWithLogonW를 호출할 때 Secondary Logon 서비스도 이 함수를 사용합니다. 이러한 의미에서 사용자가 ‘선택한 로그인 세션에 프로세스를 인젝션’할 수 있도록 합니다28. 또한 이 두 API는 모두 KernelBase.dll에 있는 CreateProcessInternalW의 래퍼라는 점에 유의해야 합니다.

여기서 핵심 차이점은 호출자가 이 두 API를 호출하려면 특정 권한을 가져야 한다는 것입니다29. 하지만 공격자 관점에서 목표는 같습니다. 측면 이동을 위해 대상 사용자의 보안 컨텍스트에서 코드를 실행하는 것입니다.

흥미로운 특이점 중 하나는 PowerShell이 가장과 멀티스레딩을 처리하는 방식의 제약 때문에 PowerShell Empire 프레임워크가 이 프로세스 생성 방식을 사용해야 했다는 점입니다. 탐지 관점에서는 이 방식이 훨씬 더 눈에 띌 수 있습니다. 여기의 참고 사항에서 이를 더 자세히 설명합니다.

어떤 경우든 프로세스 생성 토큰 조작 기법을 사용하는 워크플로는 동일합니다. 공격자는 OpenProcess/OpenProcessToken을 사용해 기본 토큰의 핸들을 얻거나, 스레드가 가장 중인 경우 OpenThread/OpenThreadToken을 사용해 토큰 핸들을 획득한 후, DuplicateTokenEx를 호출하여 대상 토큰의 로컬 기본 복사본을 만들어야 합니다. 그런 다음 이 복사본을 CreateProcessWithTokenW 또는 CreateProcessAsUserW 함수에 전달합니다.

여기에서도 공격자는 네트워크 로그인이 아닌 권한 있는 로그인 세션에만 관심이 있다는 점에 유의해야 합니다. 네트워크 로그인은 자격 증명을 캐시하지 않으므로 다른 호스트에 인증할 수 없기 때문입니다.

2. 패스 더 티켓


Windows는 Kerberos를 사용하여 NETONLY 플래그와 매우 유사한 기법을 수행하는 기본 제공 방법을 제공합니다30. 이 기법은 공격자가 새 로그인 세션을 생성할 필요 없이, 자신의 로그인 세션 및 현재 액세스 토큰과 연결된 캐시된 Kerberos 자격 증명(예: TGT)을 임의로 변경할 수 있다는 점에서 더욱 강력합니다. 아래에 그 방식이 나와 있습니다.

6-pass-the-ticket-blog-access-token-manipulation.gif

그림 6: 패스 더 티켓 공격의 내부 작동 방식. 이 예에서 사용자 ASTRO\cosmo는 ASTRO\Administrator 사용자의 탈취한 TGT를 현재 로그인 세션에 적용합니다.


Kerberos SSP와 상호 작용하고 Kerberos 티켓 캐시를 관리하려면 프로세스는 LsaCallAuthenticationPackage를 호출할 수 있습니다. 이 함수는 Sspicl.dll에 있습니다.

NTSTATUS LsaCallAuthenticationPackage( 
HANDLE LsaHandle,
ULONG AuthenticationPackage,
PVOID ProtocolSubmitBuffer,
ULONG SubmitBufferLength,
PVOID *ProtocolReturnBuffer,
PULONG ReturnBufferLength,
PNTSTATUS ProtocolStatus
);

사용자는 먼저 LSA 서버에 대한 연결 핸들을 획득하기 위해 LsaConnectUntrusted를 호출하고, Kerberos 패키지(MICROSOFT_KERBEROS_NAME_A)의 ID를 찾기 위해 LsaLookupAuthenticationPackage를 호출해야 합니다. 또한 IDA에서 이러한 함수를 검사하면, 이들 함수도 Sspicl.dll에 있으며 RPC를 통해 LSA에 연결한다는 것을 알 수 있습니다31.

LsaCallAuthenticationPackage를 통해 사용자는 여러 민감한 요청을 수행할 수 있습니다. 다만 정확히 어떤 요청을 수행할 수 있는지는 권한 상승 여부에 따라 달라집니다. 예를 들어 상승되지 않은 사용자는 현재 활성화된 티켓 열거, 티켓 캐시 제거 및 현재 로그인 세션에 임의의 티켓 적용과 같은 기본 티켓 관리 작업32을 수행할 수 있습니다33. 따라서 사용자는 현재 로그인 세션에 캐시된 자격 증명을 효과적으로 변경하고, 임의의 네트워크 전용 자격 증명을 지정할 수 있습니다.

또한 상승된 컨텍스트에서는34 공격자가 다른 사용자에게 속한 티켓, 즉 자격 증명을 열거하고 덤프할 수 있습니다. 따라서 lsass에 대한 핸들을 열지 않고도 35.

Kerberos 인증 패키지에 전송할 수 있는 메시지 유형의 전체 목록은 여기에서 확인할 수 있습니다. 지정한 로그인 세션과 연결된 현재 TGT를 변경하려면 다음 메시지 구조를 사용하는 KerbSubmitTicketMessage를 전달할 수 있습니다.

Typedef struct _KERB_SUBMIT_TKT_REQUEST {
KERB_PROTOCOL_MESSAGE_TYPE MessageType;
LUID LogonId;
ULONG Flags;
KERB_CRYPTO_KEY32 Key;
ULONG KerbCredSize;
ULONG KerbCredOffset;
} KERB_SUBMIT_TKT_REQUEST, *PKERB_SUBMIT_TKT_REQUEST

따라서 KerbSubmitTicketMessage의 경우 ProtocolSubmitBuffer 매개변수는 KERB_SUBMIT_TKT_REQUEST 구조체와 그 바로 뒤에 이어지는 ASN으로 인코딩된 Kerberos 티켓, 즉 지정된 로그인 세션에 적용할 티켓으로 구성된 메모리 블록을 가리킵니다. KerbSubmitTicketMessage 요청을 전송하는 mimikatz 관련 코드는 여기에서, Rubeus 관련 코드는 여기에서 확인할 수 있습니다. 

LsaCallAuthenticationPackage를 호출한 후에는 사용자의 TGT가 탈취한 티켓으로 업데이트됩니다. 이후 사용자 액세스 토큰 또는 대화형 로그인 세션에 연결된 프로세스나 스레드가 네트워크 리소스에 액세스하려고 하면, 탈취한 TGT를 사용해 Kerberos 인증을 자동으로 수행합니다. 예를 들어 도메인 전반의 리소스에 대해 서로 다른 서비스 티켓(TGS)을 요청할 수 있습니다. 

사용자는 현재 로그인 세션과 연결된 TGT를 하나만 보유할 수 있다는 점에 유의해야 합니다. 따라서 새 티켓을 적용하면 사용자의 기존 티켓은 제거됩니다. 그렇다면 공격자가 현재 TGT를 보존하려면 어떻게 해야 할까요? 이 경우에도 NETONLY 플래그를 사용할 수 있습니다. 공격자는 임의의 또는 무의미한 자격 증명과 함께 CreateProcessWithLogonW를 사용해 ‘희생용’ NETONLY 프로세스를 생성할 수 있습니다. 그러면 새 더미 프로세스와, 더 중요하게는 탈취한 TGT를 적용할 수 있는 새 로그인 세션 및 액세스 토큰이 생성됩니다. 따라서 사용자의 현재 티켓을 보존할 수 있습니다36

방어 실무자가 이 기법에서 도출해야 할 중요한 결론은, 모든 활동이 LsaCallAuthenticationPackage를 통해, 즉 RPC를 통해 수행되므로 lsass와 직접 상호 작용할 필요가 없다는 점입니다. 여기서 직접 상호 작용이란 OpenProcess를 통해 lsass에 대한 핸들을 여는 것을 의미합니다. 또한 이 특정 사용 사례인 패스 더 티켓에서는 공격자가 원격 호스트에 인증하려고 시도하기 전까지 모든 활동이 로컬 RPC를 통해 수행됩니다. 원격 호스트에 인증하면 새 로그인이 생성됩니다. 

추가 예로 Rubeus의 README에는 다음과 같은 설명이 포함되어 있습니다. 

“Rubeus에는 LSASS를 건드리는 코드가 없으며, 그렇게 할 의도도 없습니다. 따라서 Rubeus의 기능은 LsaCallAuthenticationPackage() API를 사용해 Kerberos 티켓을 추출하는 것으로 제한됩니다.” 

따라서 lsass에 대한 핸들 액세스를 전제로 하는 탐지 로직, 예를 들어 특정 프로세스 또는 스레드 핸들 작업에 대한 ObjectPreCallback 커널 루틴이나 OpenProcess/NtOpenProcess의 사용자 모드 후크는 이러한 활동을 놓칠 수 있습니다.그러므로 Sysmon 프로세스 액세스 이벤트를 사용하여 의심스러운 프로세스 핸들 액세스를 경고하는 방어자에게는 잠재적인 사각지대가 될 수 있습니다.

3. 패스 더 해시(PtH)

이 블로그 글에서 다루는 마지막 두 기법은 공격자가 lsass 메모리를 직접 수정하여 현재 액세스 토큰 또는 로그인 세션에 연결된 캐시된 자격 증명을 ‘비정상적으로’ 변경하는 사례입니다. PtH 시나리오에서 공격자의 액세스 토큰은 변경되지 않으며 동일한 로그인 세션을 가리킵니다. 하지만 연결된 캐시된 자격 증명은 탈취한 해시로 직접 덮어써집니다. 이후 모든 원격 인증 시도는 아래와 같이 탈취한 해시를 사용합니다.

7-under-the-hood-blog-access-token-manipulation.gif

그림 7: PtH 공격의 내부 작동 방식. 이 예에서 ASTRO\cosmo 사용자의 정상 해시가 메모리에서 ASTRO\Administrator 사용자에게 속한 NTLM 해시로 덮어써집니다.


이러한 의미에서 PtH와 OPtH는 앞서 설명한 NETONLY 기법과 기능적으로 동일한 것으로 볼 수 있습니다.

일반적인 PtH 공격 워크플로는 다음과 같습니다.

  • PROCESS_VM_WRITE의 요청 액세스를 사용해 OpenProcess/NtOpenProcess 등을 통해 lsass에 대한 쓰기 핸들을 엽니다.
  • 로그인 세션의 연결 리스트를 열거합니다.
  • 관심 있는 로그인 세션을 찾고 필요한 인증 패키지를 식별합니다. PtH/NTLM의 경우 이는 MSV1_0 인증 패키지입니다.
  • 연결된 캐시된 자격 증명을 업데이트합니다.

이러한 기법은 문서화되지 않은 Windows 구조를 파싱하고 수정하는 데 의존하는 경우가 많습니다. 이 작업은 이 블로그 글에서 다루지 않지만, 수행 방식에 관한 자세한 내용은 여기여기에서 확인할 수 있습니다. 

캐시된 자격 증명이 메모리에서 업데이트되면, 해당 토큰으로 실행되는 프로세스나 스레드가 원격 리소스에 액세스하려 할 때 일반적인 Windows SSO 설계에 따라 자동으로 원격 인증에 사용됩니다.  

이 단순한 경우에는 추가 로그인 세션이나 액세스 토큰이 생성되지 않았다는 점에 유의해야 합니다. 하지만 패스 더 티켓 공격과 유사하게, 이러한 도구도 기존 자격 증명을 보존하거나 탈취한 자격 증명을 적용하기 위해 새롭고 무의미한 NETONLY 프로세스 또는 로그인 세션을 생성해야 하는 경우가 많습니다. 

lsass에 대한 쓰기 핸들을 획득하기 위해 멀웨어는 일반적으로 다음 두 가지 방식을 사용합니다.

  • SeDebugPrivilege를 획득합니다37.
  • SYSTEM 토큰을 탈취하고 가장합니다.

첫 번째 방식은 이 블로그 시리즈의 첫 번째 글에서 설명했습니다. 하지만 후자의 방식은 로컬 액세스 검사를 우회할 목적으로 토큰을 탈취하거나 가장하는 일반적인 사례입니다. 예를 들어 SeTcbPrivilege와 같은 특정 권한이 활성화된 SYSTEM 토큰을 탈취하는 경우입니다. SYSTEM 토큰은 일반적으로 winlogon의 기본 토큰을 탈취하여 획득합니다.

4. 오버패스 더 해시(OPtH)

오버패스 더 해시 기법은 한 가지 핵심적인 차이점을 제외하면 패스 더 해시와 동일한 개념을 적용합니다. 해시를 완전한 TGT 티켓으로 변환한다는 점입니다. 

사용자가 Windows 워크스테이션에 처음 로그인할 때 Kerberos 인증 프로세스의 일부로 사용자 비밀번호 해시를 사용해 타임스탬프를 암호화합니다. 이를 통해 도메인 컨트롤러 또는 키 배포 센터(KDC)에 사용자의 ID를 검증하고 TGT를 받습니다. 오버패스 더 해시는 메모리에서 이러한 캐시된 해시를 수정한 후38 일반 Kerberos 인증 프로토콜(AS-REQ/AS_REP 등)을 시작하여 탈취한 해시에 대한 완전한 TGT를 획득합니다39.

이 기법은 mimikatz의 pth 명령을 통해 수행할 수 있습니다. 이 명령은 실제로 내부적으로 오버패스 더 해시를 수행하지만, 오해의 소지가 있게도 pth로 표시됩니다.

mimikatz # sekurlsa::pth /user:Administrator /domain:ASTRO.testlab /ntlm: c0f969f35beb20e8f09ce86ef42ccd51

이는 Kerberos SSP와 kerberos.dll을 대상으로 한다는 점을 제외하면, 본질적으로 PtH와 동일한 단계를 수행합니다.40

8-opth-attack-blog-access-token-manipulation.gif

그림 8: OPtH 공격의 내부 작동 방식. 이 예에서는 ASTRO\cosmo 사용자의 정상 해시가 메모리에서 ASTRO\Administrator 사용자에게 속한 해시로 덮어써지고, 일반 Kerberos 인증 프로세스가 시작됩니다.


이 기법도 사용자 로그인 세션과 연결된 현재 TGT를 제거하므로, 공격자는 더미 로그인 세션과 연결된 NETONLY 프로세스를 사용하여 현재 TGT를 보존할 수 있습니다. 실제로 이것이 mimikatz가 기본적으로 오버패스 더 해시를 수행하는 방식입니다. 

먼저 mimikatz는 LOGON_NETCREDENTIALS_ONLY 플래그와 함께 CreateProcessWithLogonW를 사용하여 일시 중단 상태의 새 프로세스를 생성합니다. 그런 다음 이 일시 중단된 프로세스의 기본 토큰에 대한 핸들을 획득하고, GetTokenInformation을 통해 더미 로그인 세션의 인증 ID를 가져옵니다. 이 함수는 TOKEN_INFORMATION_CLASS 열거형을 통해 토큰에 캐시된 정보를 쿼리하는 데 사용되며, 이 경우에는 TokenStatistics를 사용합니다. 

인증 ID를 획득하면 mimikatz는 이제 lsass 내 로그인 세션의 연결 리스트를 열거하며 새로 생성된 로그인 세션을 찾을 수 있습니다. 인증 ID를 통해 대상 로그인 세션을 찾으면 해당 세션과 연결된 Kerberos 자격 증명을 업데이트할 수 있습니다. 자격 증명이 업데이트되면, 해당 로그인 세션이 탈취한 해시와 연결된 토큰은 이전에 살펴본 것처럼 DuplicateTokenEx를 통해 가장 토큰으로 변환되고 SetThreadToken을 통해 가장할 수 있습니다. 

이 단계에서도 공격자가 네트워크 전반의 리소스에 액세스하려는 모든 시도는 mimikatz에 인수로 제공된 domain\user 및 비밀번호 해시 조합을 인증에 사용합니다. 따라서 모든 원격 상호 작용은 탈취한 자격 증명이 가진 액세스 권한과 권한으로 수행됩니다.

결론

이 두 부분으로 구성된 블로그 시리즈의 목적은 Windows 보안의 근본적인 개념이 내부적으로 작동하는 방식을 설명하고, 공격자가 이러한 기능을 악용하여 Windows 도메인을 침해하는 방식을 보여 주는 것이었습니다. 이 블로그 글에서는 어떤 도구 또는 인증 공급자가 악용되었는지와 관계없이, 공격자가 액세스 토큰 조작에서 동일한 비정상 신호(예: 비정상적인 네트워크 전용 로그인)을 초래하는 일련의 제약 아래에서 활동한다는 점을 보여 주었습니다. 이러한 제약은 액세스 토큰, 로그인 세션 및 캐시된 자격 증명 간의 근본적인 관계에 의해 결정됩니다.

Elastic Security를 통한 통합 데이터 보호를 시작할 준비가 되셨나요? 지금 무료로 사용해 보거나 Elastic Cloud의 Elasticsearch Service에서 최신 버전을 경험해 보세요. 성공적인 시작을 위해 Quick Start 교육도 활용해 보세요.


참고 자료

1.   Kerberos 인증이 작동하는 방식을 다시 살펴보려면 Keith Brown의 Programming Windows Security 또는 https://posts.specterops.io/kerberosity-killed-the...를 참조하세요. 또한 Kerberos와 상호 작용하기 위한 툴킷인 Rubeus에는 매우 유익한 README가 있으므로 추가 참고 자료로 권장합니다.

2. Windows SSO 메커니즘에 따라 사용자가 네트워크 리소스에 액세스하려 할 때마다 Windows는 로그인 세션에 캐시된 자격 증명을 자동으로 사용하여 인증한다는 점을 기억하세요. 여기서 캐시된 자격 증명은 모든 인증 공급자의 자격 증명, 예를 들어 NTLM 해시 또는 Kerberos 티켓을 가리킬 수 있습니다. 이 설명은 사용자가 대화형으로, 즉 비네트워크 방식으로 로그인했다고 가정합니다.

3.  일반적으로 이는 인시던트 대응 또는 호스트 격리로 인해 거점을 잃지 않기 위한 것입니다.

4.  이는 물론 공격자가 impacket 등을 통해 원격으로 코드를 실행하는 경우가 아니라, 침해된 호스트에서 수행하는 공격자 활동에만 적용됩니다.

5.  https://clymb3r.wordpress.com/2013/11/03/powershel...

6.  이 기법의 예로 Cobalt Strike의 steal_token 명령을 참조하세요. https://www.cobaltstrike.com/help-beacon

7.  보관된 PowerSploit 프레임워크의 코멘트도 로컬 권한 상승을 위한 토큰 탈취와 측면 이동을 위한 토큰 탈취의 차이를 더 명확히 이해하는 데 도움이 됩니다.

8.  또는 공격자는 패스워드 스프레이 방식을 사용하거나 responder와 같은 도구를 통해 NTLM 스니핑 또는 재전송 공격을 시도할 수도 있습니다.

9.   LogonUserExExW는 모두 SspiCli.dll의 LogonUserExExW를 단순히 래핑한 것임에 유의하세요.

10.  정확히 같은 방식으로 CreateProcessWithLogonW에 로컬 관리자 계정(rid-500)을 전달하면 중간 무결성 또는 상승되지 않은 컨텍스트에서 상승된 프로세스를 실행할 수 있습니다.

11.  이 동작을 변경할 수 있는 원격 UAC 레지스트리 옵션이 있습니다.

12.  추가 로그인 유형인 LOGON32_LOGON_NETWORK_CLEARTEXT가 있습니다. 이는 본질적으로 캐시된 자격 증명을 가진 네트워크 로그인입니다. 자세한 내용은 Keith Brown의 Programming Windows Security를 참조하세요.

13.  자세한 내용은 다음을 참조하세요.


https://blueteamer.blogspot.com/2018/12/disabling-...
https://support.microsoft.com/en-gb/help/951016/de...
https://labs.f-secure.com/blog/enumerating-remote-...

14.   DuplicateToken 함수도 있지만, 이 함수는 가장 토큰만 반환한다는 점에 유의하세요.

15.  IDA에서 해당 함수를 검사하여 이를 확인할 수 있습니다. 또는 ReactOS의 여기에서 확인하세요.

16.  이 요약은 가장 보안을 다소 단순화한 것입니다. 더 철저한 개요는 James Forshaw의 “Introduction to Logical Privilege Escalation on Windows” 슬라이드 26페이지를 참조하세요. https://conference.hitb.org/hitbsecconf2017ams/mat...

17.  이 제목은 Raphael Mudge의 훌륭한 블로그 글인 Windows Access Tokens and Alternate Credentials에서 가져왔습니다.

18.  일반적으로 이것이 공격자가 두 번째 선택지를 흔히 사용하지 않는 주된 이유입니다.

19.  따라서 복제된 토큰이 다른 네트워크 자격 증명을 갖더라도 토큰 자체는 동일하므로 whoami를 실행하면 여전히 같은 사용자가 표시됩니다. 이는 내부적으로 동일한 기법을 수행하는 Cobalt Strike의 make_token 명령을 사용할 때 흔히 발생하는 혼동의 원인입니다.

20.  Windows RPC/COM API를 사용해도 사용자가 네트워크 전용 자격 증명을 지정할 수 있습니다. 예를 들어 RPC의 경우 RpcBindingSetAuthInfoExW를 호출하고 AuthIdentity 매개변수를 통해 SEC_WINNT_AUTH_IDENTITY 구조를 전달하여 이를 수행할 수 있습니다. 자세한 내용은 Keith Brown의 Programming Windows Security 및 다음 자료를 참조하세요. https://docs.microsoft.com/en-us/windows/win32/wmisdk/setting-authentication-using-c-.

21.  두 플래그의 이름은 다르지만 의미는 같습니다. 이 자격 증명은 네트워크에서만 사용됩니다.

22.  비정상 로그인 세션에서 의심스러운 이벤트 로그가 생성되는 것을 우회하는 방법도 여전히 존재한다는 점에 유의하세요.

23.  이는 James Forshaw의 기법입니다. 자세한 내용은 다음 블로그 글을 참조하세요. https://www.tiraniddo.dev/2017/05/reading-your-way.... 또한 TokenViewer는 이러한 유형의 기법을 실험하는 데 매우 유용한 도구입니다.

24.  이렇게 생성된 가장 토큰을 사용하면 System32 등에 파일을 기록할 수 있습니다.

25.  다만 API 호출 전에 가장하는 것이 타당한 이유도 있을 수 있습니다. 예를 들어 특정 API를 호출하기 전에 현재 보유하지 않은 권한을 획득해야 하는 경우가 이에 해당합니다. 일부 API는 자동으로 권한을 활성화한다는 점에 유의하세요.

26.  이를 우회하는 몇 가지 방법이 있습니다. 예를 들어 PROCESS_CREATE_PROCESS 액세스 권한으로 OpenProcess를 사용해 SYSTEM 프로세스에 대한 핸들을 획득하면, 해당 SYSTEM 프로세스의 자식 프로세스로 새 프로세스를 생성할 수 있습니다. 그런 다음 이 HANDLE을 ParentProcess 매개변수로 NtCreateProcess에 전달할 수 있습니다. PROC_THREAD_ATTRIBUTE_PARENT_PROCESS 매개변수 및 CreateProcess를 통해서도 이를 수행할 수 있습니다. https://gist.github.com/xpn/a057a26ec81e736518ee50...

27.  이상하게도 CreateProcessWithTokenW는 기존 토큰의 핸들도 요구하면서 dwLogonFlags 인수를 받습니다. 정의상 기존 토큰에는 이미 그에 상응하는 로그인 세션이 있어야 합니다. 이는 사용자 프로필을 로드하는 방식과 관련된 것으로 보입니다.

28.  Programming Windows Security, Keith Brown

29.  구체적으로 CreateProcessWithTokenW에는 SE_IMPERSONATE_NAME이 필요하며, CreateProcessAsUserW에는 SE_INCREASE_QUOTA_NAME 및 토큰을 할당할 수 없는 경우 SE_ASSIGNPRIMARYTOKEN_NAME이 필요합니다.

30.  Kerberos 인증의 개요는 여기에서 확인할 수 있으며, Kerberos 관련 공격에 관한 자세한 정보는 다음 자료를 참조하세요. https://www.blackhat.com/docs/us-14/materials/us-1..., , https://github.com/GhostPack/Rubeus#readme

31.  https://googleprojectzero.blogspot.com/2019/12/cal...

32.  예를 들어 Windows 기본 제공 도구인 klist는 유사한 기능을 제공하며, LsaCallAuthenticationPackage를 명확히 래핑한 것으로 보입니다.

33.  상승되지 않은 사용자는 자신의 로그인 세션에만 티켓을 적용할 수 있습니다. 다른 로그인 세션에 TGT를 적용하려면 상승된 권한이 필요합니다.

34.  이 설명에는 Rubeus README에서 더 적절히 다루는 몇 가지 주의 사항과 미묘한 차이가 있습니다. 간단히 말하면 호출자는 LsaRegisterLsaProcess를 통해 LSA 연결을 등록해야 하며, 이를 위해서는 SeTcbPrivilege 권한이 필요합니다. 즉, 호출자가 신뢰할 수 있는 컴퓨팅 기반의 일부여야 합니다.

35.  참고로 LsaCallAuthenticationPackage를 통해 msv1_0 인증 패키지와도 상호 작용하고 다음 메시지 유형을 전송할 수 있습니다. https://docs.microsoft.com/en-us/windows/win32/api... 다만 이 인터페이스를 통해 NTLM 자격 증명도 검색할 수 있는지는 조사하지 않았습니다.

36.  자세한 내용은 Kerberos 관련 기능 및 OPSEC 고려 사항을 훌륭하게 설명한 Rubeus GitHub 리포지토리의 README를 참조하세요.

37.  권한을 활성화하는 예는 여기에서 확인할 수 있습니다.

38.  IDA에서 PsOpenProcess/Thread를 살펴보고 SePrivilegeCheck 호출을 찾으면 이를 확인할 수 있습니다.

39.  SeDebugPrivilege를 획득하면 탐지 로직 관점에서 매우 눈에 띄는 경향이 있다는 점에 유의하세요.

40.  해시 또는 키는 rc4_hmac(예: NTLM), aes128_hmac, aes256_hmac 등일 수 있습니다. 자세한 내용은 여기에서 확인하세요.

41.  자세한 내용은 다음을 참조하세요. https://www.blackhat.com/docs/us-14/materials/us-1...

42.  참고로 Rubeus의 asktgt 기능은 상승되지 않은 컨텍스트에서 lsass를 건드리지 않고 지정된 해시에 대한 원시 AS-REQ 트래픽을 생성하여 오버패스 더 해시의 변형을 수행합니다.