티스토리 뷰

System/Windows

Windows Access Token

Tribal 2018. 3. 27. 21:30

Access Token이란?


  Access Token은 Windows에서 주체가 객체에 접근하기 위해 사용되는 일종의 접근 권한에 대한 정보이다. Linux의 owner, group, others에 대한 권한을 생각하면 조금 이해가 편해진다. Windows는 가장 높은 권한인 System 권한(Linux의 root 권한)과 사용자의 계정을 구별하기 위해 생성되는 계정 별로 SID(Security IDentifier)를 두고 관리된다. 


Access Token에 저장되는 정보(MSDN) :

  • 사용자 계정 SID(Security IDentifier)
  • 사용자가 멤버인 그룹의 SID
  • 현재 로그인한 세션을 식별하기 위한 SID
  • 사용자 또는 사용자 그룹이 가지는 권한 목록
  • 소유자 SID
  • 주요 그룹의 SID
  • 사용자가 Security Descriptor를 지정하지 않고 보안 객체를 만들 경우에 사용하는 기본 DACL
  • Access Token의 출처
  • 토큰의 종류(기본 토큰, 위장 토큰)
  • 제한된 SID 목록
  • 현재 위장 수준
  • 기타


  Windows에 로컬이나 네트워크(원격)를 통해 Logon을 하게 되면, 사용자에 대한 password를 물어본다. 입력된 password가 SAM(Security Account Manager)에 저장된 해당 계정의 password와 일치한 경우, System이 Logon을 허용하고 해당 사용자에 대한 Access Token을 발급해준다. 로그인한 사용자가 가지는 모든 접근에 대한 정보는 해당 계정의 Access Token에 전부 저장되어 관리되고, 사용자의 모든 접근에 Access Token이 사용된다. Logon에 대한 정보는 간략하게 설명되었지만, 자세히 알고 싶다면 LSA 인증 프로토콜을 보면 된다.


  이후, 로그인한 사용자가 실행하는 프로그램은 사용자의 Access Token을 복사하여 해당 사용자의 권한으로 실행된다. 따라서 사용자가 실행시킨 프로그램은 사용자와 동일한 Access Token을 가지게 된다. 아래는 이 점을 이용해 Process의 SID 값을 확인해 본 결과이다.


ProcessSID 확인용 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <Windows.h>
#include <tchar.h>
#include <cstdio>
#include <sddl.h>
 
BOOL GetProcessUserSID(void) {
    DWORD dwLen;
    BOOL bRes;
    HANDLE hToken;
 
    if (!OpenProcessToken(
        GetCurrentProcess(),
        TOKEN_QUERY,
        &hToken))
    {
        fprintf(stderr, "[-] OpenProcessToken error : %u\n", GetLastError());
        return FALSE;
    }
 
    bRes = GetTokenInformation(
        hToken,
        TokenUser,
        NULL,
        0,
        &dwLen
    );
 
    BYTE* pBuffer = new BYTE[dwLen];
    if (pBuffer == NULL)
    {
        CloseHandle(hToken);
        return FALSE;
    }
 
    bRes = GetTokenInformation(
        hToken,
        TokenUser,
        pBuffer,
        dwLen,
        &dwLen
    );
 
    if (!bRes)
    {
        CloseHandle(hToken);
        delete[] pBuffer;
        return FALSE;
    }
 
    TOKEN_USER* pUser = (TOKEN_USER*)pBuffer;
    LPTSTR StringSid = NULL;
    ConvertSidToStringSid(pUser->User.Sid, &StringSid);
    printf("SID : %ls, Attriutes : %u\n",
            StringSid,
            pUser->User.Attributes);
    LocalFree((HLOCAL)StringSid);
    delete[] pBuffer;
    CloseHandle(hToken);
 
    if (!bRes) return FALSE;
 
    return TRUE;
}
 
int main(void) {
    GetProcessUserSID();
 
    return 0;
}
cs


ProcessSID 확인(위 사진 : 내 계정의 SID 값, 아래 사진(왼) : 관리자 권한으로 실행된 프로세스 SID, 아래 사진(오) : 프로세스의 SID)



  현재 실행된 계정의 SID와 현재 실행된 프로세스의 SID, 현재 관리자 권한으로 실행된 프로세스의 SID는 동일한 SID 값을 가지는 것을 확인할 수 있다.


  여기서 위에서 관리자 권한으로 실행된 프로세스의 SID는 내 계정과 동일한데 어떤 차이가 생기는지 한 가지 궁금증이 생긴다. Windows는 Windows OS에 중요한 작업을 할 때는 관리자 권한이 있어야만 접근을 허용하고 있는데, 정작 실행된 Process SID 값은 관리자 권한 여부와 상관없이 동일한 것을 확인할 수 있다. 이 이유는 SID는 식별을 위해서만 사용하고 접근 권한에 대해서는 Access Token의 Privilege가 관리하는 것으로 알 수 있다.


사용 코드 : http://tribal1012.tistory.com/216 의 현재 Process의 Privilege 확인 코드

출력 결과


  왼쪽은 관리자 권한으로 실행된 프로세스의 Privilege이고, 오른쪽은 그냥 실행된 프로세스의 Privilege이다. SID 값은 동일한데, 권한은 명백하게 차이가 나는 것을 확인할 수 있다. 관리자 권한으로 실행된 프로세스는 그냥 실행된 프로세스와 달리 시스템으로부터 권한을 추가적으로 더 받았기 때문에 SID가 동일하더라도 행사할 수 있는 능력이 차이가 나는 것을 알 수 있다. 여기서 LUID 값 9는 take ownership인데, 프로세스에 소유권을 가진 것을 알 수 있다. 직접 설정하여 확인해 보지는 않았지만, 이 권한은 Linux의 setuid와 비슷한 권한이라고 생각된다.


참고 : 



'System > Windows' 카테고리의 다른 글

Windows 인증 과정1 (개요)  (2) 2018.04.12
Windows LUID 값과 Token을 이용한 Privilege 변경  (0) 2018.03.28
JavaScript using frida  (0) 2017.12.14
Windows Structure  (0) 2017.11.30
Microsoft Spy++ 백업  (0) 2017.11.23
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31