Operating System/Windows 시스템 프로그래밍 - 기본

기본 이론

Tony Lim 2023. 7. 3. 14:20
728x90

대전제 (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 권한이 없는 사용자의 쓰기 시도 발생 시 로그 저장 (감사자료)
  • 이상한 놈이 계속 로그인 시도를 하는것을 로그로 남김

 

프로세스 수준 접근 통제

  1. 보안 객체 접근시 대상 객체와 접근 주체(Process)에 대한 권한 비교
  2. 객체에 대한 DACL 과 process(주체) 가 가진 Access token을 비교한 것
  3. 가진 권한과 허용된 접근 (RWX)에 따라 OS가 통제

 


Access token과 프로세스 권한 상속

  • 프로세스나 스레드가 갖는 보안 수준에 대한 정보와 의미를 포괄
  • 사용자 계정 특구너 (관리자, 일반 등)
  • 대표적으로 SID 정보

 

사용자 로그온 과정과 권한

  1. 지식기반 사용자 인증
  2. 로그온 사용자 권한으로 최초 프로세스인 쉘 프로세스(탐색기) 실행 -> 바탕화면이 보이게 됨
  3. OS는 로그온 사용자에 대한 Access token을 생성해 탐색기에 부여
  4. 탐색기를 통해 새프로세스가 실행될 때마다 권한 상속

바탕화면에서 뭔짓을 할때마다 상속된 권한을 기준으로 일이 진행이 된다.

상속받는 다는의미에서 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을 그대로 상속받기 때문에 문제가 안되긴 한다.

 

728x90

'Operating System > Windows 시스템 프로그래밍 - 기본' 카테고리의 다른 글

프로세스 관리  (0) 2023.07.18
메모리 시스템  (0) 2023.07.15
Win32 파일 입/출력  (0) 2023.07.10
스레드 동기화  (0) 2023.07.07
스레드 생성 및 제어  (0) 2023.07.05