Step 13. 프로세스와 서비스 내부 — 실행의 계보를 추적하라

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 — 이 프로세스의 PID
  • ParentProcessId나를 실행시킨 프로세스의 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. 미션과 연습문제

미션 — 계보 추적 카드 만들기

  1. 파워쉘에서 그림판을 띄우세요: Start-Process mspaint
  2. 그림판 프로세스의 PID와 부모 PID를 확인하세요
  3. 부모를 따라 끝까지(시스템 계열까지) 올라가며 계보를 종이에 그리세요. 예: mspaint ← powershell ← explorer ← ...
  4. Get-Service에서 Automatic 서비스 중 이름을 모르는 것 3개를 골라 각각의 정체를 조사해 보세요 (이름으로 검색하면 정체가 나옵니다 — 이게 실제 조사 방법입니다)
  5. 마쳤으면 그림판을 닫으세요

연습문제

문제 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 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.