Token관련 API 

Windows의 Token은 계정의 권한과 같은 개념이다. 

윈도우엔 권한이 있어야만 실행 가능한 것들이 있다.

(현재 로그인 세션의 권한을 저장하고 있는 변수라고 생각하면 된다.)


BOOL WINAPI OpenProcessToken(
  _In_   HANDLE ProcessHandle,
  _In_   DWORD DesiredAccess,
  _Out_  PHANDLE TokenHandle
);

ProcessHandle : Token을 얻어올 프로세스 핸들
DesiredAccess : 해당 프로세스에서 필요한 액세스 권한
TokenHandle : 얻어온 토큰이 저장될 핸들


BOOL WINAPI LookupPrivilegeValue(
  _In_opt_  LPCTSTR lpSystemName,
  _In_      LPCTSTR lpName,
  _Out_     PLUID lpLuid
);

*LUID = locally unique identifier의 약자로 Windows가 부팅되면서 부여되는 64비트크기의 고유한 값이다.


함수 이름 그대로 PrivilegeValue 값을 Lookup하는 함수. 
PrivilegeValue는 LUID로 구분되어 OS가 리부팅 되기전까지 가지고 있는 고유한 값이다.
(각 권한마다 매 부팅시 LUID가 부여되며 우리는 이 LUID로 권한을 disable || enable 시킬 수 있는 것이다.)


lpSystemName : Privilege값을 얻어올 시스템 이름. NULL입력시 로컬 시스템.
(MSDN에서 의미하는 System이 호스트단위인지는 잘 모르겠다. 공유가 가능한 LAN상에서 타 시스템의 Token도 가지고 올 수 있는건지 MSDN에선 Local system과 일반 system을 구분하고 있다.)

lpName : PrivilegeValue를 얻어올 PrivilegeName. 

lpLuid : PrivilegeValue를 받을 LUID자료형의 포인터. 



BOOL WINAPI AdjustTokenPrivileges(
  _In_       HANDLE TokenHandle,
  _In_       BOOL DisableAllPrivileges,
  _In_opt_   PTOKEN_PRIVILEGES NewState,
  _In_       DWORD BufferLength,
  _Out_opt_  PTOKEN_PRIVILEGES PreviousState,
  _Out_opt_  PDWORD ReturnLength
);

명시된 Access Token 의 권한을 Disable || Enable 시킬 수 있는 API함수


TokenHandle : 권한을 수정 할 Token의 핸들.

DisableAllPrivileges : 수정과는 관계없는 인자이므로 FALSE를 전달하면 된다. 이 값이 TRUE일 경우 NewState값은 무시되며 모든 권한이 Disable된다 

NewState : 수정할 토큰에대한 정보를 담은 TOKEN_PRIVILEGES 구조체의 포인터 (예제 참조)

BufferLength : 버퍼의 크기 입력. 수정되기전의 Privileges 값을 받을 때 사용되는 버퍼같은데 어떻게 사용하는지는 자세하게 알지 못하겠다. 0으로 설정하려면 PreviousState (변경되기 전의 값을 받을 포인터) 또한 NULL이어야 한다. 

PreviousState : 변경되기전 Privileges값을 받기위한 포인터 

ReturnLength : 변경되기전 Privileges 값을 리턴받기위해 필요한 바이트 크기. TOKEN_PRIVILEGES의 크기를 말하는 것 같다. 이 역시 PreviousState값이 NULL일 경우에만 NULL을 전달 할 수 있다. 




예제


int main(int argc, char *argv[])
{


if(!SetPrivilege(SE_DEBUG_NAME, TRUE))
return 1;

return 0;
}



BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;

if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{  
printf("OpenProcessToken error : %u\n", GetLastError());
return FALSE;
}

if(!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
{
printf("LookupPrivilegeValue error : %u\n", GetLastError());
return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if(bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;   
else
tp.Privileges[0].Attributes = 0;               // disable

if(!AdjustTokenPrivileges(hToken, 
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD)NULL))
{
printf("AdjustTokenPrivileges error : %u\n", GetLastError());
return FALSE;
}

if(GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}

return TRUE;
}




**  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY 에 대해 


TOKEN_ADJUST_PRIVILEGES : Token에 Access권한을 설정하는 AdjustTokenPrivileges를 호출할때 필요하다
MSDN : Required to enable or disable the privileges in an access token.


TOKEN_QUERY : 어떤 값인지 감을 못잡겠다 . 

MSDN의 내용대로라면 Lookup API를 쓰기위해 지정해주는 mask가 아닐까 한다. 

query : 질의, 문의 

MSDN : Required to query an access token.

Posted by $Zero
: