성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<span> <br /> <div class='mainCenterTitle'>필수 무결성 제어(<strike>신뢰도 등급</strike>)을 조절하는 방법(2) - 직접 코딩</div><br /> <br /> Manifest를 통한 필수 무결성 제어(<strike>신뢰도 등급</strike>) 조정과 코딩을 통한 필수 무결성 제어(<strike>신뢰도 등급</strike>) 조정은 어느 것이 낫다고 볼 수 없는, 그들만의 장단점을 가지고 있습니다. 대략 다음과 같은 특징들이 있다고 볼 수 있겠군요.<br /> <br /> <pre class='code'> 1. Manifest를 이용 장점: 구현의 용이, 코드 수정 없이 변경 가능(외부 manifest) 단점: requireAdministrator, highestAvailable, asInvoker만이 가능 2. 코딩을 이용한 방법 장점: 다양한 제어 가능(Low 권한의 프로세스 생성 가능) 단점: 코딩의 부담 </pre> <br /> 음... 써놓고 보니 좀 상투적이라고 느낌이 드는군요. ^^; 암튼, 이와 관련돼 대표적인 코드 2가지를 한번 살펴 보도록 하겠습니다.<br /> <br /> * 참고로, 여기 있는 소스 코드를 직접 컴파일하고 실행시켜 보기 위해서는 개발 환경을 그에 맞게 구성해 주셔야 합니다. 이에 대해서는 다음의 토픽을 참고하십시오.<br /> <br /> <pre class='code'> 비스타 응용 프로그램 개발을 위한 VS.NET 2005 환경 설정 ; <a target='_tab' href='/2/0/444'>http://www.sysnet.pe.kr/2/0/444</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> <span class='subLastTitle'>1. medium 신뢰도에서 "low" 신뢰도의 프로그램을 실행시키는 코드 </span> <br /> 이미, 예전에 "<a target='_tab' href='/2/0/433'>보호 모드와 필수 무결성 제어(<strike>신뢰도 등급</strike>)(MIC: Mandatory Integrity Control)</a>"에서 소개해 드렸던 "<a target='_tab' href='https://kb.digital-detective.net/display/BF/Understanding+and+Working+in+Protected+Mode+Internet+Explorer'>Understanding and Working in Protected Mode Internet Explorer</a>"에 포함된 코드를 그대로 옮길 수밖에는 없을 것 같습니다. ^^<br /> <br /> <pre class='code'> void CreateLowProcess() { BOOL bRet; HANDLE hToken; HANDLE hNewToken; WCHAR wszProcessName[MAX_PATH] = L"Notepad.exe"; WCHAR wszIntegritySid[20] = L"<b>S-1-16-4096</b>"; PSID pIntegritySid = NULL; TOKEN_MANDATORY_LABEL TIL = {0}; PROCESS_INFORMATION ProcInfo = {0}; STARTUPINFO StartupInfo = {0}; ULONG ExitCode = 0; if (OpenProcessToken(GetCurrentProcess(),MAXIMUM_ALLOWED, &hToken)) { if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hNewToken)) { if (ConvertStringSidToSid(wszIntegritySid, &pIntegritySid)) { TIL.Label.Attributes = SE_GROUP_INTEGRITY; TIL.Label.Sid = pIntegritySid; if (<b>SetTokenInformation</b>(hNewToken, TokenIntegrityLevel, &TIL, sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid))) { bRet = <b>CreateProcessAsUser</b>(hNewToken, NULL, wszProcessName, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcInfo); } LocalFree(pIntegritySid); } CloseHandle(hNewToken); } CloseHandle(hToken); } } </pre> <br /> 뭐, 별로 그다지 살펴 볼만한 내용이 없을 것 같습니다. 그냥 그대로 ^^; 써야만 하기 때문에.<br /> <br /> 참고로, IntegritySid 값으로는 다음과 같은 값들을 가지고 있습니다.<br /> <br /> <pre class='code'> Low == S-1-16-<b>4096</b> Medium == S-1-16-<b>8192</b> High == S-1-16-<b>12288</b> System == S-1-16-<b>16384</b> </pre> <br /> "<a target='_tab' href='/2/0/433'>보호 모드와 필수 무결성 제어(<strike>신뢰도 등급</strike>)(MIC: Mandatory Integrity Control)</a>"에서도 잠시 언급을 했었지만, "low, medium, high, system에 대해 각각 hex 값으로 1000/2000/3000/4000"이라고 말씀드렸었는데... 실제로 위의 Integrity SID 값의 "S-1-16-" 뒤의 숫자 값들을 16진수로 표현하면 각각 4096 == 0x1000, 8192 == 0x2000, 12288 == 0x3000, 16384 == 0x4000 임을 알 수 있습니다.<br /> <br /> <span class='subLastTitle'>2. medium 신뢰도에서 "high" 신뢰도의 프로그램을 실행시키는 코드 </span> <br /> 처음에 저는, medium에서 high 신뢰도의 응용 프로그램을 실행시킬 때에도 위와 같은 코드를 그대로 활용할 수 있을 거라고 생각했습니다. 즉, 위에서 살펴본 CreateLowProcess 함수의 wszIntegritySid 변수값에 high에 해당하는 "S-1-16-12288" 값을 넣으면, "CreateProcessAsUser" API가 실행되면서 "UAC 확인창"이 뜨고 자연스럽게 high 권한의 프로세스가 생성될 거라고 여겼었는데요.<br /> <br /> 실제 해보면 SetTokenInformation API에서 "0x522" 값의 오류 코드가 반환됩니다. <br /> <br /> <pre class='code'> * 참고: 관련 오류 코드 의미 #define ERROR_PRIVILEGE_NOT_HELD 1314L // 0x522 : "A required privilege is not held by the client." #define ERROR_ELEVATION_REQUIRED 740L // 0x2e4 : "The requested operation requires elevation." </pre> <br /> 일단, medium 신뢰도의 프로세스에서 high 신뢰도의 프로세스를 생성하는 방법에 대해서 문서상으로는 명시적인 방법이 제공되고 있진 않지만, 다행히도 다음의 토픽에서 "트릭"으로 언급하면서 설명해 주고 있습니다.<br /> <br /> <pre class='code'> Vista Compatibility Team Blog - Elevate through ShellExecute ; http://blogs.msdn.com/vistacompatteam/archive/2006/09/25/771232.aspx </pre> <br /> 아래의 코드가 그 방법인데, 간단하게 기존에 제공되던 "verb" 중에서 "runas"를 이용해서 high 신뢰도의 프로세스를 실행시키는 것을 가능하게 해주고 있습니다.<br /> <br /> <pre class='code'> void CreateHighProcess(HWND hWnd) { SHELLEXECUTEINFO sei; ZeroMemory (&sei, sizeof(sei) ); sei.cbSize = sizeof(SHELLEXECUTEINFOW); sei.hwnd = hWnd; sei.lpVerb = L"<b>runas</b>"; sei.lpFile = L"Notepad.exe"; sei.nShow = SW_SHOWNORMAL; <b>ShellExecuteEx</b> ( &sei ); } </pre> <br /> * 첨부된 압축 파일에는 위의 2가지 코드를 담은 Visual C++ 8 MFC 대화창 기반 프로젝트가 들어있습니다.<br /> <br /><br /><hr /><span style='color: Maroon'>[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </span>
첨부파일
스팸 방지용 인증 번호
7833
(왼쪽의 숫자를 입력해야 합니다.)