성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[tree soap] 아차! f는 기억이 나는데, m은 ㅜㅜ 감사합니다!!! ^...
[정성태] 'm'은 decimal 타입의 숫자에 붙는 접미사입니다. ...
[정성태] https://lxr.sourceforge.io/ http...
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>Local SYSTEM 권한으로 코드를 실행하는 방법</h1> <p> 이에 대해서 검색해 보면, 여러 가지 글들이 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Starting Process in the Logged Session under the Local System Account ; <a target='tab' href='http://www.codeproject.com/Articles/133375/Starting-Process-in-the-Logged-Session-under-the-L'>http://www.codeproject.com/Articles/133375/Starting-Process-in-the-Logged-Session-under-the-L</a> </pre> <br /> 종합해 보면, NT 서비스를 SYSTEM 권한으로 등록시키고 그것을 이용해 코드를 실행하라는 것입니다. 정말 이 방법 밖에는 없는 걸까요? 아쉽게도 그런 것 같습니다. ^^ "Mark Russinovich" 같은 뛰어난 개발자조차도 이 방법을 사용한 것에서 미뤄 짐작할 수 있습니다.<br /> <br /> 그가 만든 Sysinternals 도구 중의 하나인 psexec.exe를 이용하면 특정 프로세스를 Local SYSTEM 권한으로 실행할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > SYSTEM 권한으로 UI 프로그램 실행하는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/1/1153'>http://www.sysnet.pe.kr/2/1/1153</a> </pre> <br /> psexec.exe가 동작하는 방식은 다음과 같습니다.<br /> <br /> <ol> <li>c:\windows\psexesvc.exe 파일이 있는지 확인한다. 파일이 없다면 psexec.exe 파일 내부의 리소스로 포함된 "PSEXESVC" 바이너리를 c:\windows\psexesvc.exe로 쓴다.</li> <li>SCM(Service Control Manager) Win32 API를 이용해 psexesvc.exe를 "Local SYSTEM" 권한의 NT 서비스로 등록한다.</li> <li>인자로 입력된 프로그램 경로를 psexesvc.exe에 넘기고 실행한다.</li> <li>프로그램 실행이 완료되면, SCM Win32 API를 이용해 psexesvc.exe의 NT 서비스 등록을 해제한다.</li> </ol> <br /> 실제로, 3번 단계에서 프로그램이 실행되고 있을 때 "Process Explorer"를 이용해 해당 프로그램의 부모를 확인하면 psexesvc.exe인 것을 알 수 있고, NT 서비스에도 다음과 같이 등록된 것을 볼 수 있습니다.<br /> <br /> <img alt='local_system_execute_1.png' src='/SysWebRes/bbs/local_system_execute_1.png' /><br /> <br /> <hr style='width: 50%' /><br /> <br /> 제 경우에는 예전에 관리자 권한의 작업을 COM+에 대행했던 방법을 소개해 드린 적이 있는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 관리자 권한이 필요한 작업을 COM+에 대행 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1290'>http://www.sysnet.pe.kr/2/0/1290</a> </pre> <br /> gacutil 등을 이용한 등록 과정을 고려해 볼 때, 단발성으로 실행할 관리 권한의 코드라면 NT 서비스 등록/해제가 더 간단할 것도 같습니다.<br /> <br /> 이걸 C#으로 한번 구현해 볼까요? ^^ 다행히 SCM을 다루는 Win32 API를 다음의 글에서 C#으로 만들어 두었기 때문에 작업을 좀 더 쉽게 할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > How to install a windows service programmatically in C#? ; <a target='tab' href='http://stackoverflow.com/questions/358700/how-to-install-a-windows-service-programmatically-in-c'>http://stackoverflow.com/questions/358700/how-to-install-a-windows-service-programmatically-in-c</a> Re: Detecting a service that is running ; <a target='tab' href='http://www.tech-archive.net/Archive/VB/microsoft.public.vb.winapi/2006-08/msg00238.html'>http://www.tech-archive.net/Archive/VB/microsoft.public.vb.winapi/2006-08/msg00238.html</a> </pre> <br /> 이번 글에서는 모듈 수를 줄이기 위해 서비스 등록하는 프로그램과 서비스로 동작하는 프로그램을 하나로 만들어 볼 텐데요. 그래서, 아래와 같이 간단하게 코드가 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; using System.Diagnostics; using System.IO; using System.Threading; using Microsoft.Win32; namespace psexec2 { static class Program { static string _svcName = "psexec2"; static void Main(string[] args) { if (Environment.UserInteractive == true) { // 일반 프로그램으로 실행된 경우 DanceWithSCM(); } else { // Local System 권한의 NT 서비스로 실행된 경우 if (Environment.UserName == "SYSTEM") { DoSystemRights(); } } } // Local System 권한의 NT 서비스로 실행된 경우 // 스스로 NT 서비스로 등록된 상태에서 실행되었으므로, // 원하는 SYSTEM 권한의 동작을 수행한 후 곧바로 실행을 벗어난다. private static void DoSystemRights() { using (RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services", true)) { RegistryKey created = regKey.CreateSubKey(".DoTest"); created.SetValue("User", Environment.UserName); } } // 일반 프로그램으로 실행된 경우 // 1) 스스로를 NT 서비스로 등록하고 시작시킨 후, // 2) 서비스로 실행된 프로세스가 종료되는 때까지 대기한 다음, // 3) NT 서비스 등록을 해제한다. private static void DanceWithSCM() { Process process = Process.GetCurrentProcess(); string filePath = typeof(Program).Assembly.Location; if (ServiceInstaller.ServiceIsInstalled(_svcName) == false) { ServiceInstaller.InstallAndStart(_svcName, _svcName, filePath); } string exeName = Path.GetFileNameWithoutExtension(typeof(Program).Assembly.Location); Process[] serviceProcess = Process.GetProcessesByName(exeName); int maxSecond = 10; if (serviceProcess.Length == 2) { foreach (Process targetProcess in serviceProcess) { if (targetProcess.Id == process.Id) { continue; } System.Diagnostics.Trace.WriteLine("Exceuted"); targetProcess.WaitForExit(maxSecond * 1000); } } ServiceInstaller.StopService(_svcName); while (ServiceInstaller.GetServiceStatus(_svcName) == ServiceState.Stop) { if (maxSecond-- <= 0) { break; } Thread.Sleep(200); } ServiceInstaller.Uninstall(_svcName); } } } </pre> <br /> 위의 코드를 '관리자 권한'으로 실행하면 다음과 같이 레지스트리에 새로운 키가 생성됩니다.<br /> <br /> <img alt='local_system_execute_2.png' src='/SysWebRes/bbs/local_system_execute_2.png' /><br /> <br /> <a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=771&boardid=331301885'>첨부된 파일은 위의 예제 코드를 담고 있습니다.</a><br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1929
(왼쪽의 숫자를 입력해야 합니다.)