티스토리 뷰

LUID

  Process와 Thread 가질 수 있는 권한에 대한 64bit 크기의 식별자, Access Token의 정보에 포함되어 있다.


LUID(Locally Unique IDentifier) 목록(line 번호가 LUID 값)

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
#define SE_CREATE_TOKEN_NAME              TEXT("SeCreateTokenPrivilege")
#define SE_ASSIGNPRIMARYTOKEN_NAME        TEXT("SeAssignPrimaryTokenPrivilege")
#define SE_LOCK_MEMORY_NAME               TEXT("SeLockMemoryPrivilege")
#define SE_INCREASE_QUOTA_NAME            TEXT("SeIncreaseQuotaPrivilege")
#define SE_UNSOLICITED_INPUT_NAME         TEXT("SeUnsolicitedInputPrivilege")
#define SE_MACHINE_ACCOUNT_NAME           TEXT("SeMachineAccountPrivilege")
#define SE_TCB_NAME                       TEXT("SeTcbPrivilege")
#define SE_SECURITY_NAME                  TEXT("SeSecurityPrivilege")
#define SE_TAKE_OWNERSHIP_NAME            TEXT("SeTakeOwnershipPrivilege")
#define SE_LOAD_DRIVER_NAME               TEXT("SeLoadDriverPrivilege")
#define SE_SYSTEM_PROFILE_NAME            TEXT("SeSystemProfilePrivilege")
#define SE_SYSTEMTIME_NAME                TEXT("SeSystemtimePrivilege")
#define SE_PROF_SINGLE_PROCESS_NAME       TEXT("SeProfileSingleProcessPrivilege")
#define SE_INC_BASE_PRIORITY_NAME         TEXT("SeIncreaseBasePriorityPrivilege")
#define SE_CREATE_PAGEFILE_NAME           TEXT("SeCreatePagefilePrivilege")
#define SE_CREATE_PERMANENT_NAME          TEXT("SeCreatePermanentPrivilege")
#define SE_BACKUP_NAME                    TEXT("SeBackupPrivilege")
#define SE_RESTORE_NAME                   TEXT("SeRestorePrivilege")
#define SE_SHUTDOWN_NAME                  TEXT("SeShutdownPrivilege")
#define SE_DEBUG_NAME                     TEXT("SeDebugPrivilege")
#define SE_AUDIT_NAME                     TEXT("SeAuditPrivilege")
#define SE_SYSTEM_ENVIRONMENT_NAME        TEXT("SeSystemEnvironmentPrivilege")
#define SE_CHANGE_NOTIFY_NAME             TEXT("SeChangeNotifyPrivilege")
#define SE_REMOTE_SHUTDOWN_NAME           TEXT("SeRemoteShutdownPrivilege")
#define SE_UNDOCK_NAME                    TEXT("SeUndockPrivilege")
#define SE_SYNC_AGENT_NAME                TEXT("SeSyncAgentPrivilege")
#define SE_ENABLE_DELEGATION_NAME         TEXT("SeEnableDelegationPrivilege")
#define SE_MANAGE_VOLUME_NAME             TEXT("SeManageVolumePrivilege")
#define SE_IMPERSONATE_NAME               TEXT("SeImpersonatePrivilege")
#define SE_CREATE_GLOBAL_NAME             TEXT("SeCreateGlobalPrivilege")
#define SE_TRUSTED_CREDMAN_ACCESS_NAME    TEXT("SeTrustedCredManAccessPrivilege")
#define SE_RELABEL_NAME                   TEXT("SeRelabelPrivilege")
#define SE_INC_WORKING_SET_NAME           TEXT("SeIncreaseWorkingSetPrivilege")
#define SE_TIME_ZONE_NAME                 TEXT("SeTimeZonePrivilege")
#define SE_CREATE_SYMBOLIC_LINK_NAME      TEXT("SeCreateSymbolicLinkPrivilege")
cs

※ LUID 항목별 설명(MSDN) : https://msdn.microsoft.com/en-us/library/windows/desktop/bb530716(v=vs.85).aspx


현재 Process의 Privilege 확인 코드

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
70
71
72
73
74
75
76
#include <Windows.h>
#include <tchar.h>
#include <cstdio>
#include <sddl.h>
 
DWORD GetPrivilege(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,
        TokenPrivileges,
        NULL,
        0,
        &dwLen
    );
    if (!bRes)
    {
        CloseHandle(hToken);
        delete[] pBuffer;
        return FALSE;
    }
 
    BYTE* pBuffer = new BYTE[dwLen];
    if (pBuffer == NULL)
    {
        CloseHandle(hToken);
        return FALSE;
    }
 
    bRes = GetTokenInformation(
        hToken,
        TokenPrivileges,
        pBuffer,
        dwLen,
        &dwLen
    );
    if (!bRes)
    {
        CloseHandle(hToken);
        delete[] pBuffer;
        return FALSE;
    }
 
    TOKEN_PRIVILEGES* pPrivs = (TOKEN_PRIVILEGES*)pBuffer;
    for (DWORD i = 0; i < pPrivs->PrivilegeCount; i++)
    {
        printf("LUID : %u %u, Attriutes : %u\n"
            pPrivs->Privileges[i].Luid.HighPart, 
            pPrivs->Privileges[i].Luid.LowPart,
            pPrivs->Privileges[i].Attributes);
    }
 
    delete[] pBuffer;
    CloseHandle(hToken);
 
    if (!bRes) return FALSE;
    
    return TRUE;
}
 
int main(void) {
    if (!GetPrivilege()) return -1;
 
    return 0;
}
cs
  • 11번째 줄 : 현재 Process의 Access Token을 가져옴
  • 20번째 줄 : 2번째 인자인 TokenPrivilege를 질의로 하여 dwLen에 Privilege 배열의 전체 크기를 받아옴
  • 34번째 줄 : Privilege 배열의 전체 크기를 받아올 수 있도록 메모리 할당
  • 41번째 줄 : 다시 한 번 질의를 하여 할당해둔 메모리에 질의에 대한 결과 저장
  • 55번째 줄 : LUID와 Attributes 출력


현재 Process의 Privilege 확인 코드 결과



Attributes 값

1
2
3
4
5
6
7
8
9
10
11
12
// Privilege attributes
//
 
#define SE_PRIVILEGE_ENABLED_BY_DEFAULT (0x00000001L)
#define SE_PRIVILEGE_ENABLED            (0x00000002L)
#define SE_PRIVILEGE_REMOVED            (0X00000004L)
#define SE_PRIVILEGE_USED_FOR_ACCESS    (0x80000000L)
 
#define SE_PRIVILEGE_VALID_ATTRIBUTES   (SE_PRIVILEGE_ENABLED_BY_DEFAULT | \
                                         SE_PRIVILEGE_ENABLED            | \
                                         SE_PRIVILEGE_REMOVED            | \
                                         SE_PRIVILEGE_USED_FOR_ACCESS)
cs



Privilege 세팅 코드

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <Windows.h>
#include <tchar.h>
#include <cstdio>
#include <sddl.h>
 
static BOOL g_flag;
DWORD GetPrivilege(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,
        TokenPrivileges,
        NULL,
        0,
        &dwLen
    );
 
    BYTE* pBuffer = new BYTE[dwLen];
    if (pBuffer == NULL)
    {
        CloseHandle(hToken);
        return FALSE;
    }
 
    bRes = GetTokenInformation(
        hToken,
        TokenPrivileges,
        pBuffer,
        dwLen,
        &dwLen
    );
 
    if (!bRes)
    {
        CloseHandle(hToken);
        delete[] pBuffer;
        return FALSE;
    }
 
    TOKEN_PRIVILEGES* pPrivs = (TOKEN_PRIVILEGES*)pBuffer;
    if(g_flag) puts("================== Before ================");
    else puts("================== After ================");
    for (DWORD i = 0; i < pPrivs->PrivilegeCount; i++)
    {
        printf("LUID : %u %u, Attriutes : %u\n"
            pPrivs->Privileges[i].Luid.HighPart, 
            pPrivs->Privileges[i].Luid.LowPart,
            pPrivs->Privileges[i].Attributes);
    }
 
    delete[] pBuffer;
    CloseHandle(hToken);
 
    if (!bRes) return FALSE;
    
    return TRUE;
}
 
BOOL SetPrivilege(void) { 
    HANDLE hToken;
    LUID luid;
 
    if (!OpenProcessToken(
        GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES| TOKEN_QUERY,
        &hToken))
    {
        fprintf(stderr, "[-] OpenProcessToken error : %u\n", GetLastError());
        return FALSE;
    }
 
    if (!LookupPrivilegeValue(
        NULL,
        SE_DEBUG_NAME,
        &luid))
    {
        fprintf(stderr, "[-] LookupPrivilegeValue error : %u\n", GetLastError());
        return FALSE;
    }
 
    TOKEN_PRIVILEGES tp;
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
    if (!AdjustTokenPrivileges(
        hToken,
        FALSE,
        &tp,
        sizeof(TOKEN_PRIVILEGES),
        (PTOKEN_PRIVILEGES)NULL,
        (PDWORD)NULL))
    {
        fprintf(stderr, "[-] AdjustTokenPrivileges error : %u\n", GetLastError());
        return FALSE;
    }
 
    CloseHandle(hToken);
 
    return TRUE;
}
 
int main(void) {
    g_flag = TRUE;
    if (!GetPrivilege()) return 0;
    if (!SetPrivilege()) return 0;
    g_flag = FALSE;
    if (!GetPrivilege()) return 0;
 
    return 0;
}
cs
  • 7번째 줄 : 위에서 본 것과 동일한 Privilege를 확인하는 함수이다.
  • 74번째 줄 : 2번째 인자로 Privilege를 적용시키기 위한 TOKEN_ADJUST_PRIVILEGES를 추가하였다.
  • 83번째 줄 : SE_DEBUG_NAME에 해당하는 LUID 값(20)을 가져온다. 저 값을 확인해보면 20인 것을 확인할 수 있다.
  • 92번째 줄 : 세팅하기 위한 TOKEN_PRIVILEGE를 추가한다.
  • 97번째 줄 : TokenPrivileges를 세팅한다.
  • 119번째 줄 : 다시 확인해보면 20이 2(SE_PRIVILEGE_ENABLED)로 변경된 것을 확인할 수 있다.


Privilege 세팅 코드 결과(관리자로 실행, Before에 출력되었던 LUID만 결과를 볼 수 있음)


LUID가 20(SE_DEBUG_NAME)인 Attributes가 2로 변경된 것을 확인할 수 있다.



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

Windows 인증 과정3 (원격)  (0) 2018.04.12
Windows 인증 과정1 (개요)  (2) 2018.04.12
Windows Access Token  (0) 2018.03.27
JavaScript using frida  (0) 2017.12.14
Windows Structure  (0) 2017.11.30
댓글
최근에 올라온 글
최근에 달린 댓글
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