대전제 (feat. 핸들)
- 결국 내가 작성하는 코드는 실행 주체이며 Process 이다.
- 주체가 아닌 나머지는 모두 객체 (대상체) 이다.
- 모든 객체는 주체가 생성/개방 할 수 있으며 사용 후 삭제하거나 닫는다.
자료형을 재정의 한게 굉장히 많다. F12 를 눌러서 windows.h, winnt.h 로 가서 어떤 자료형을 warpping 한것인지 확인하자
모든 객체 (프로세스 포함) 를 식별하는 것은 핸들(Handle) 이며 핸들의 실체는 결국 포인터이다.
핸들에 대한 토큰은 핸들이 식별하는 대상에 관한 정보를 담은 구조체로 이해한다.
보안 객체와 (보안) 기술자
- 보안 객체에 대한 정보 (객체의 소유자, 그룹, 보호 속성, 감사 정보) 를 의미
- 객체 소유자 및 그룹
- 보호속성 (Protection attributes)
- 감사 정보 (Audit information)
- 파일이나 폴더(보안객체) 생성 시 접근권한에 관한 정보가 함께 생성
Administrator가 System process를 통제할 수 있긴한데 SYSTEM 이 제일 강력하다.
SYSTEM > admin > User >
대표적인 보안 객체(Securable Object)
파일,폴더
프로세스 , 스레드 = 컴퓨터라는 놀이공원에서 나 라는 개념 (주체임)
파일 매핑 객체
파이프
토큰
윈도우 스테이션 및 테스크톱
레지스트리, 서비스, 프린터, 네트워크 공유자원
이벤트, 뮤텍스, 세마포어
DACL
- DACL (Discretionary Access Control List)은 보안객체에 대한 접근 허용/차단 정보를 가진 데이터구조
- ACL (Access Control List) 은 ACE (Access Control Entity) 의 리스트
ACE
- 윈도우 시스템에서 접근제어를 위한 기본정보
- 권한에 따라 접근을 제한다는 것은 ACE를 수정편집한다는 의미
- ACE의 핵심 정보는SID(Security Identifier) 이며 사용자나 그룹을 식별
SID
- 각 사용자 그룹 (관리자, 일반)의 SID
- 각 사용자 계정의 SID
- 특정 파일 (보안객체) 에 대한 DACL에는 결과적으로 어떤 SID에 대해 어떤 권한(RWX)이 있는지 기술되어 있음
SACL (System Access Control List)
- 파일 같은 보안 객체에 대한접근 로그를 남기는 근거 정보
- Write 권한이 없는 사용자의 쓰기 시도 발생 시 로그 저장 (감사자료)
- 이상한 놈이 계속 로그인 시도를 하는것을 로그로 남김
프로세스 수준 접근 통제
- 보안 객체 접근시 대상 객체와 접근 주체(Process)에 대한 권한 비교
- 객체에 대한 DACL 과 process(주체) 가 가진 Access token을 비교한 것
- 가진 권한과 허용된 접근 (RWX)에 따라 OS가 통제
Access token과 프로세스 권한 상속
- 프로세스나 스레드가 갖는 보안 수준에 대한 정보와 의미를 포괄
- 사용자 계정 특구너 (관리자, 일반 등)
- 대표적으로 SID 정보
사용자 로그온 과정과 권한
- 지식기반 사용자 인증
- 로그온 사용자 권한으로 최초 프로세스인 쉘 프로세스(탐색기) 실행 -> 바탕화면이 보이게 됨
- OS는 로그온 사용자에 대한 Access token을 생성해 탐색기에 부여
- 탐색기를 통해 새프로세스가 실행될 때마다 권한 상속
바탕화면에서 뭔짓을 할때마다 상속된 권한을 기준으로 일이 진행이 된다.
상속받는 다는의미에서 CreateProcess 호출할때 security인자에 NULL을 넣어주게 된다.
shell 을 해킹해서 원격코드를 실행시켜서 프로세스B를 실행시키면 권한을 그대로 상속받기 때문에
자기가 새로 계정을 만들어버리면 된다.
SECURITY_ATTRIBUTES 구조체
void CreateSample01()
{
STARTUPINFO si;
::ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION pi;
::ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
TCHAR szBuffer[_MAX_FNAME] = TEXT("notepad.exe");
if (::CreateProcess(NULL, // No module name (use command line).
szBuffer,
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi) // Pointer to PROCESS_INFORMATION structure.
)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
szBuffer에 실행시킬 파일의 경로가 담겨 있다.
process , thread handle not inheritable 이라고 적혀있는 필드는 현재 이 create process를 호출하는 process의 보안권한을 상속 받겠다는 의미이다.
일반 user로 접속했을때 특정 프로그램만 관리자 권한으로 띄우고 싶을 때는 CreateProcessAsUser()를 띄위게 된다.
void CreateSample02()
{
PROCESS_INFORMATION pi;
::ZeroMemory(&pi, sizeof(pi));
STARTUPINFO si;
::ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = (LPTSTR)TEXT("winsta0\\default");
HANDLE hToken = NULL;
HANDLE hProcess = NULL;
//현재 프로세스에 대한 토큰을 얻는다.
hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION,
TRUE, ::GetCurrentProcessId());
::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
//얻은 토큰으로 프로세스를 생성한다.
TCHAR szBuffer[_MAX_FNAME] = TEXT("notepad.exe");
if (CreateProcessAsUser(
hToken,
NULL, // No module name (use command line).
szBuffer,
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
TRUE, // Set handle inheritance to FALSE.
CREATE_NEW_CONSOLE,
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi) // Pointer to PROCESS_INFORMATION structure.
)
{
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
}
::CloseHandle(hToken);
::CloseHandle(hProcess);
}
hToken에는 security 정보가 들어잇다. (권한같은)
사실 이렇게 할거면 그냥 CreateProcess를 호출해도 hToken을 그대로 상속받기 때문에 문제가 안되긴 한다.
'Operating System > Windows 시스템 프로그래밍 - 기본' 카테고리의 다른 글
프로세스 관리 (0) | 2023.07.18 |
---|---|
메모리 시스템 (0) | 2023.07.15 |
Win32 파일 입/출력 (0) | 2023.07.10 |
스레드 동기화 (0) | 2023.07.07 |
스레드 생성 및 제어 (0) | 2023.07.05 |