Step 13. 프로세스와 서비스 내부 — 실행의 계보를 추적하라
Level 0 — 컴퓨터 조작과 구조의 이해 | 난이도 ★★★☆☆ | 예상 소요 시간 2~3시간
전제: Step 12 완료. 윈도우 파워쉘에서 진행합니다. 관리자 권한은 필요 없고, 인터넷 연결은 미션의 검색 단계에서만 필요합니다.
- 준비물: 윈도우 PC, 파워쉘.
- 주의: 오늘 실습은 전부 조회와 짧은 실행입니다. 프로그램을 종료하는 명령(Stop-Process)이 한 번 나오는데, 우리가 방금 연 실험용 프로그램만 닫습니다. 다른 프로그램을 함부로 종료하면 작업 중인 문서가 날아갈 수 있으니, 챕터의 지시 대상 외에는 쓰지 마세요.
작업 관리자를 열었는데 모르는 프로그램이 돌고 있다고 합시다. 보안 분석가의 첫 질문은 정해져 있습니다: "얘를 누가 실행했지?" 아무것도 아닌 프로그램도, 실행시킨 주체가 수상하면 수상한 겁니다. 프로세스의 세계에는 가족관계가 있습니다 — 모든 프로세스에는 자신을 실행시킨 부모가 있고, 그 부모에게도 부모가 있습니다. 이 계보를 번호로 추적하는 법이 오늘의 주제입니다.
1. 학습 목표
이 챕터를 끝내면 다음을 할 수 있습니다:
- PID가 무엇이며, 왜 이름 대신 번호로 프로세스를 지목하는지 설명한다
Get-CimInstance Win32_Process로 부모 PID를 조회하고, 계보를 끝까지 추적한다- "내가 실행한 프로그램의 부모는 나"라는 규칙을 직접 실험으로 확인한다
- 서비스의 시작 유형(자동/수동/사용 안 함)을 구분하고, 그 보안 의미를 안다
- 추적 중 만나는 "끊긴 고리"(부모 종료)를 오류가 아닌 정상 상황으로 해석한다
2. 배경 지식 — 오늘의 도구와 개념
오늘의 도구 한눈에 보기
| 구분 | 내용 |
|---|---|
| 언어·환경 | 파워쉘 5.1 (일반 권한으로 충분), CIM/WMI 조회 사용 |
| 오늘의 명령어 | Get-Process(목록+PID), Get-CimInstance Win32_Process(부모 PID), $PID(이 창의 번호), Get-Service | Group-Object StartType(시작 유형 분포) |
| 필요한 개념 | PID, 부모 프로세스와 프로세스 트리, 서비스 시작 유형, 고아(orphan) 프로세스 |
2-1. PID — 프로세스의 주민번호
컴퓨터에는 같은 이름의 프로그램이 여러 개 돌 수 있습니다. 크롬 창을 열면 chrome.exe가 수십 개죠. 이들을 어떻게 구별할까요? 각 프로세스에는 실행될 때마다 고유 번호가 부여됩니다. 이게 PID(Process ID)입니다.
이름은 겹칠 수 있지만 PID는 겹치지 않습니다. 그래서 시스템을 다루는 모든 도구는 프로세스를 이름이 아니라 PID로 정확히 지목하고, 분석 보고서도 "PID 34732"처럼 번호로 기록합니다. 그리고 이 번호는 프로그램이 아니라 실행 회차에 붙습니다 — 같은 메모장도 닫았다 다시 열면 새 번호를 받습니다.
2-2. 프로세스 트리 — 모두에게는 부모가 있다
프로세스는 무(無)에서 생기지 않습니다. 반드시 다른 프로세스가 실행시킵니다:
System (시조)
└─ explorer.exe (바탕 화면 관리자)
└─ powershell.exe (내가 연 파워쉘)
└─ mspaint.exe (파워쉘에서 연 그림판)
이런 나무 구조를 프로세스 트리라 합니다. 여러분이 아이콘을 더블클릭해 프로그램을 열 때, 실제로는 explorer.exe(바탕 화면을 관리하는 프로세스)가 실행시켜 줍니다. 그래서 정상 프로그램의 부모는 대부분 explorer.exe입니다.
이것이 왜 중요한가: 정상 계보를 알면 비정상이 보입니다. "워드(winword.exe)의 자식으로 파워쉘이 떴다" — 문서 파일을 열었더니 문서가 몰래 명령을 실행했다는 뜻으로, 실제 악성 문서 공격의 전형적 모습입니다. 오늘 배우는 추적이 그걸 발견하는 기술입니다.
2-3. 시조는 누구인가
가계도를 거슬러 올라가면 맨 위에는 누가 있을까요? 윈도우에서는 System(PID 4)과 그 주변의 시스템 프로세스들이 시조 역할을 합니다. 부팅과 함께 가장 먼저 태어나 다른 프로세스들을 줄줄이 실행시킵니다. 실습에서 PID 0, 4 같은 아주 낮은 번호를 보게 되는데, 낮은 번호는 일찍 태어난 시스템의 뼈대라고 읽으면 대체로 맞습니다.
2-4. 서비스 복습 + 시작 유형
Step 5에서 서비스를 "사용자가 안 보는 곳에서 상주하는 직원"이라고 배웠습니다. 오늘은 언제 출근하는가, 즉 시작 유형을 추가합니다:
| 시작 유형 | 뜻 |
|---|---|
| Automatic(자동) | 부팅 때 자동 출근 |
| Manual(수동) | 필요할 때 불려 옴 |
| Disabled(사용 안 함) | 출근 금지 |
보안 연결: 악성코드가 "자동" 서비스로 자신을 등록하면 재부팅해도 자동으로 살아납니다. 그래서 Step 11의 Run 키와 함께, "자동 시작 서비스 목록"도 지속성 조사의 양대 축입니다.
3. 따라 하기
3-1. PID 확인하기
Get-Process | Select-Object Name, Id -First 12
Name Id
---- --
acad 37372
AdskAccessCore 3076
AdskAccessServiceHost 5764
AdskAccessUIHost 13772
AdskAccessUIHost 21672
AdskAccessUIHost 21708
AdskAccessUIHost 21832
AdskIdentityManager 21440
AdskLicensingAgent 1724
...
(2026-09-09 실측. 여러분 컴퓨터의 목록과 번호는 다릅니다.)
출력 읽는 법: 왼쪽이 프로세스 이름, 오른쪽(Id)이 PID입니다. 실측 화면에서도 AdskAccessUIHost가 같은 이름으로 네 개 — 이걸 구별하는 게 오른쪽 번호입니다. 그리고 이 번호는 실행할 때마다 바뀝니다.
3-2. 부모 PID까지 보기 — 오늘의 새 명령
Get-Process는 부모 정보를 안 보여 줍니다. 그래서 더 깊은 창구를 씁니다:
Get-CimInstance Win32_Process | Select-Object Name, ProcessId, ParentProcessId -First 12
Name ProcessId ParentProcessId
---- --------- ---------------
System Idle Process 0 0
System 4 0
Secure System 236 4
Registry 276 4
smss.exe 936 4
csrss.exe 1324 1116
wininit.exe 1448 1116
csrss.exe 1456 1440
winlogon.exe 1544 1440
services.exe 1564 1448
lsass.exe 1620 1448
...
(2026-09-09 실측.)
출력 읽는 법:
ProcessId— 이 프로세스의 PIDParentProcessId— 나를 실행시킨 프로세스의 PID
실측 표로 계보를 읽어 봅시다. System Idle Process(0번)와 System(4번)이 최상단 시조입니다. services.exe(1564)의 부모는 1448, 즉 바로 위의 wininit.exe — "서비스 관리자는 wininit이 실행시켰다"가 숫자로 증명됩니다.
실측에서 발견한 진짜 ‘끊긴 고리’: csrss.exe(1324)의 부모는 1116번인데, 목록에 1116번이 없습니다. winlogon.exe의 부모 1440번도 마찬가지입니다. 부모가 자식을 실행해 두고 먼저 종료된 것입니다 — 오류가 아니라 윈도우 부팅 과정에서 매번 일어나는 정상 상황입니다. 부팅 직후 "임시로 떴다가 사라지는" 조부모 프로세스들이 있기 때문입니다.
3-3. 추적 실습 — 내 파워쉘의 가계도
직접 추적해 봅시다. 현재 열여 있는 이 파워쉘의 PID는 한 단어로 나옵니다:
$PID
30916
(번호는 실행할 때마다 다릅니다.)
이제 그 번호의 정보와 부모를 봅니다:
Get-CimInstance Win32_Process -Filter "ProcessId = $PID" | Select-Object Name, ProcessId, ParentProcessId
Name ProcessId ParentProcessId
---- --------- ---------------
powershell.exe 30916 7600
(2026-09-09 실측.)
나온 ParentProcessId로 같은 질문을 반복하세요 — 부모의 부모, 그 위의 부모… 몇 단계 올라가다 보면 explorer.exe를 지나 3-2절의 시스템 계열에 닿습니다. "누가 누구를 실행했나"가 추측이 아니라 번호로 추적된다 — 이 감각이 오늘의 핵심 수확입니다.
3-4. 실험 — 내가 부모가 되어 보기
이번엔 직접 부모가 되어 봅니다. 이 파워쉘 창에서 그림판을 실행합니다:
Start-Process mspaint
그림판이 열립니다(Start-Process는 실행하고 바로 프롬프트로 돌아옵니다). 이제 확인:
Get-CimInstance Win32_Process -Filter "Name = 'mspaint.exe'" | Select-Object Name, ProcessId, ParentProcessId
Name ProcessId ParentProcessId
---- --------- ---------------
mspaint.exe 21052 26644
(2026-09-09 실측. 이 실행에서 파워쉘의 PID는 26644였습니다.)
ParentProcessId 26644 = 이 파워쉘의 PID. "실행시킨 주체가 부모가 된다"는 규칙이 번호로 확인됐습니다.
⚠️ 윈도우 11 주의 — 메모장과 계산기는 예외입니다: 같은 방법으로
Start-Process notepad를 하고 부모를 보면, 부모가 여러분의 파워쉘 번호가 아닙니다 (2026-09-09 실측: Notepad.exe의 부모는 37968번이라는 별도 프로세스였고, 계산기(CalculatorApp.exe)도 마찬가지였습니다). 최신 윈도우의 메모장·계산기는 스토어 앱 형태라, 윈도우의 앱 실행 관리자가 대신 실행시켜 주기 때문입니다. 실험은 그림판(mspaint)으로 하세요 — 클래식 프로그램이라 규칙이 그대로 보입니다. "부모가 내가 아니다 = 이상하다"가 아니라 설명 가능한 현대 윈도우의 모습 — Step 11에서 배운 "낯선 것 = 확인 대상"의 좋은 예입니다.
확인했으면 그림판을 닫으세요. 창에서 닫아도 되고, 파워쉘에서 닫아도 됩니다:
Stop-Process -Name mspaint
3-5. 서비스의 시작 유형 분포 보기
Get-Service | Group-Object StartType | Select-Object Name, Count
Name Count
---- -----
Manual 195
Automatic 105
Disabled 10
(2026-09-09 실측. 숫자는 컴퓨터마다 다릅니다.)
새 명령 — Group-Object: "같은 값끼리 묶어 줘"입니다. 시작 유형별로 묶어서 개수를 센 겁니다.
읽는 법: Automatic이 105개 — 부팅 때마다 105개의 서비스가 자동 출근한다는 뜻입니다. 악성코드가 서비스로 숨으려면 이 목록에 섞여야 합니다. "평소 이 숫자가 얼마인지" 대강이라도 아는 것이 베이스라인 감각입니다.
오늘의 총정리 — 왜 이게 보안과 관련되는가: 악성코드 분석 보고서의 고정 문장이 있습니다. "해당 프로세스의 부모는 X이며, Y 서비스에 의해 자동 시작되도록 등록되어 있었다." 오늘 여러분은 그 문장의 두 재료 — 부모 추적과 자동 시작 확인 — 를 전부 직접 해 본 겁니다.
4. 미션과 연습문제
미션 — 계보 추적 카드 만들기
- 파워쉘에서 그림판을 띄우세요:
Start-Process mspaint - 그림판 프로세스의 PID와 부모 PID를 확인하세요
- 부모를 따라 끝까지(시스템 계열까지) 올라가며 계보를 종이에 그리세요. 예:
mspaint ← powershell ← explorer ← ... Get-Service에서 Automatic 서비스 중 이름을 모르는 것 3개를 골라 각각의 정체를 조사해 보세요 (이름으로 검색하면 정체가 나옵니다 — 이게 실제 조사 방법입니다)- 마쳤으면 그림판을 닫으세요
연습문제
문제 1. 같은 이름의 프로세스가 여러 개일 때 무엇으로 구별하며, 그 번호는 프로그램에 붙는가 실행 회차에 붙는가?
문제 2. 어떤 프로세스의 ParentProcessId를 조회했더니 해당 번호의 프로세스가 목록에 없었습니다. 무슨 상황이며, 보고서에는 어떻게 기록하면 될까요?
문제 3. 윈도우 11에서 Start-Process notepad로 연 메모장의 부모가 내 파워쉘이 아니었습니다. "뭔가 오염된 것"일까요? 왜 이런 일이 생길까요?
문제 4. 악성코드는 왜 정상 프로세스 이름(svchost.exe 등)을 흉내 낼까요? 이름에 의존한 조사의 약점과, 그 약점을 메우는 두 가지 확인 항목을 말해 보세요.
5. 모범 답안과 완료 기준
미션 모범 답안
Start-Process mspaint
$PID # 이 창의 번호를 메모
Get-CimInstance Win32_Process -Filter "Name = 'mspaint.exe'" |
Select-Object Name, ProcessId, ParentProcessId
계보 추적의 예 (2026-09-09 실측):
mspaint.exe (21052) ← powershell.exe (26644) ← explorer.exe (6700) ← (부모 5848은 종료됨)
검증하는 법: ① mspaint의 ParentProcessId가 아까 $PID로 본 번호와 일치하는가 — 일치하면 "내가 부모" 확인 완료. ② 계보를 올라가다가 중간에 "없는 PID"가 나와도 정상입니다 — 3-2절 실측에서 csrss.exe의 부모(1116번)도 목록에 없었듯이, 부모가 먼저 종료된 "끊긴 고리"입니다. 종이에 "(부모 종료됨)"이라고 적고 추적을 마치면 됩니다.
서비스 조사의 예: 실측 컴퓨터의 Automatic 서비스 중 낯선 이름을 고르면 — 예: AdskLicensingService(오토데스크 제품의 라이선스 확인 서비스), RtkAudUService(리얼텍 오디오 드라이버 — Step 11의 시작프로그램에서도 봤죠)처럼 이름 검색으로 정체가 확인됩니다. 3개 전부의 정체가 확인되면 완료입니다.
연습문제 해답
문제 1 해답. PID(Process ID)로 구별합니다. 이름은 겹칠 수 있지만 PID는 고유합니다. 번호는 프로그램이 아니라 실행 회차에 붙습니다 — 같은 프로그램도 닫았다 다시 열면 새 번호를 받습니다.
문제 2 해답. 부모가 자식을 실행해 두고 먼저 종료된 상황(고아 프로세스, "끊긴 고리")입니다. 오류가 아니라 부팅 과정에서도 매번 일어나는 정상 상황입니다. 보고서에는 "부모 종료됨 (ParentProcessId N)"으로 기록하고 그 단계에서 추적을 마치면 됩니다.
문제 3 해답. 오염이 아닙니다. 최신 윈도우의 메모장·계산기는 스토어(패키지) 앱이라, 파워쉘이 직접 실행하는 게 아니라 윈도우의 앱 실행 관리자가 대신 실행시켜 주기 때문입니다 (2026-09-09 실측 확인). "부모가 예상과 다르다"는 신호이지만, 원인을 알면 설명 가능한 정상 동작입니다. 설명 가능한지 확인하는 것 — 그것이 조사입니다.
문제 4 해답. 조사가 "이름"에 의존한다는 약점을 노리는 것입니다. svchost.exe는 정상 컴퓨터에도 수십~백 개가 떠 있어서(실측 컴퓨터에는 102개) 섞이면 눈에 잘 띄지 않습니다. 약점을 메우는 확인 항목은 ① 경로(진짜 svchost는 System32 아래)와 ② 부모(진짜 svchost의 부모는 services.exe)입니다 — 이름은 속일 수 있어도 계보와 경로는 속이기 어렵습니다.
완료 기준 체크리스트
- [ ] PID가 무엇인지, 왜 이름 대신 쓰는지 설명할 수 있다
- [ ] ParentProcessId의 의미를 설명할 수 있다
- [ ] 임의의 프로세스에서 부모를 따라 계보를 추적할 수 있다
- [ ] 내가 실행한 프로그램(그림판)의 부모가 내 파워쉘이 됨을 실험으로 확인했다
- [ ] 윈도우 11 패키지 앱(메모장·계산기)의 부모가 다른 이유를 설명할 수 있다
- [ ] 서비스의 시작 유형 세 가지를 구분할 수 있다
- [ ] 미션: 계보 추적 카드와 서비스 3개 조사를 완성했다
6. 흔한 실수와 해결
벽 1. Get-CimInstance가 너무 느리다
증상: 명령이 수 초 이상 걸립니다.
원인: Win32_Process는 전체 프로세스의 상세 정보를 긁어오는 무거운 조회입니다. 정상입니다.
해결: -First 15처럼 자르거나, 3-3절처럼 -Filter로 대상을 좁히면 빨라집니다. 조사의 철칙: 전체를 긁기 전에 "내가 찾는 게 뭔지" 먼저 정하기.
벽 2. Filter 문법에서 오류가 난다
증상: 빨간 오류 "쿼리가 올바르지 않다" 류.
원인: -Filter "Name = 'mspaint.exe'"에서 따옴표 조합이 틀린 경우가 대부분입니다. 규칙: 바깥은 큰따옴표, 안쪽 값은 작은따옴표.
해결: 형태를 그대로 베끼고 이름만 바꾸세요. 그래도 안 되면 Filter 없이 전체를 뽑고 Where-Object로 거르는 방법도 통합니다.
벽 3. ParentProcessId의 주인을 못 찾겠다
증상: 부모 PID로 조회해도 해당 프로세스가 없습니다.
원인: 부모가 이미 종료됐습니다 — 3-2절 실측에서도 csrss.exe의 부모(1116번)는 목록에 없었습니다.
해결: 오류가 아닙니다. 거기서 추적 종료 — 보고서에는 "부모 종료됨 (PID N)"으로 기록하면 됩니다. 실무에서도 매우 흔한 상황입니다.
벽 4. Stop-Process에서 "프로세스를 찾을 수 없다"는 오류
증상: 빨간 오류가 뜹니다 (2026-09-09 실측):
Get-Process : 이름이 "notepad"인 프로세스를 찾을 수 없습니다. 프로세스 이름을 검증하고 다시 cmdlet을 호출하십시오.
원인: 해당 이름의 프로세스가 실행 중이 아닙니다 — 이미 닫았거나, 이름을 틀리게 쳤거나. 참고로 Stop-Process에 쓰는 이름은 확장자(.exe)를 뺀 이름입니다 (mspaint, not mspaint.exe).
해결: Get-Process | Where-Object Name -match 'paint'처럼 이름의 일부로 찾아 실제 이름을 확인하세요.
벽 5. Group-Object 결과가 기대와 다르다
증상: StartType이 아니라 이상한 기준으로 묶입니다.
원인: Group-Object 뒤의 속성 이름 오타입니다. 대소문자는 무관하지만 철자는 정확해야 합니다.
해결: Get-Service | Select-Object -First 1로 속성 이름들을 먼저 확인하세요. "속성 이름은 물어보면 안다"는 습관이 모든 파워쉘 작업에서 시간을 아껴 줍니다.
7. 정리
오늘의 개념
| 개념 | 한 줄 설명 |
|---|---|
| PID | 프로세스의 고유 번호 — 실행 회차마다 새로 부여 |
| ParentProcessId | 나를 실행시킨 프로세스의 번호 |
| 프로세스 트리 | 부모-자식으로 이어진 실행의 가계도 |
| 고아 프로세스 | 부모가 먼저 종료된 프로세스 — 정상 상황 |
| 시작 유형 | 서비스의 출근 방식 (자동/수동/사용 안 함) |
오늘의 명령어
| 명령 | 하는 일 |
|---|---|
Get-Process |
프로세스 목록 + PID |
Get-CimInstance Win32_Process |
부모 PID까지 보는 깊은 조회 |
$PID |
지금 이 창의 PID |
Start-Process mspaint |
프로그램 실행 (기다리지 않고 돌아옴) |
Stop-Process -Name mspaint |
프로세스 종료 (⚠️ 대상 확인 필수) |
Get-Service | Group-Object StartType |
시작 유형별 분포 |
명령어보다 중요한 감각
"누가 얘를 실행했나" — 악성코드 분석의 첫 질문이자, 오늘 여러분이 번호로 추적하는 법을 배운 것입니다. 정상 계보(explorer → 정상 프로그램)를 알면, 문서가 몰래 명령을 실행하는 비정상 계보가 눈에 들어옵니다. 그리고 이름은 속일 수 있지만 계보와 경로는 속이기 어렵다 — 이것이 이름 흉내 악성코드를 잡는 관점입니다.
두 가지를 더 기억해 두세요. 첫째, 프로세스 목록에 svchost.exe가 아주 많다는 걸 눈치챘을 겁니다 — 실측 컴퓨터에는 102개가 떠 있었습니다. 윈도우 서비스들을 대신 실행해 주는 "숙주" 프로세스라서 그렇고, 악성코드가 이 이름을 흉내 내는 이유도 이 숫자 때문입니다. 둘째, 마이크로소프트의 무료 도구 Process Explorer를 쓰면 오늘 숫자로 추적한 트리를 실제 나무 그림으로 보여 줍니다. 지금은 명령으로 원리를 배우는 중이고, 도구는 원리를 알고 난 뒤에 쓰면 그 진가를 압니다.
오늘부터 작업 관리자를 열 때마다 한 번씩 "얘 누가 실행했지?"를 물어보세요. 의심하는 눈은 하루아침에 생기지 않고, 평범한 것을 계속 본 사람에게만 비범한 것이 보입니다.
전부 체크되면 Step 13 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.