리눅스 시스템 기초 · 입문편 — 본문의 "N편"은 입문 과정 번호다. 번호별 글과 전체 250편 구성은 통합 로드맵에서 확인할 수 있다.

리눅스 시스템 기초 4 / 50 · Part 1. Linux 기본 구조
실습 환경: Rocky Linux 9 (10.0.0.200)
이전 글: 3. Shell과 Bash 이해

1. 들어가며

1편에서 "Linux는 User Space와 Kernel Space로 나뉜다"고 정리했고, 2편에서 root도 User Mode 프로그램이라는 점을 봤다. 이번 글은 이 두 공간이 메모리와 CPU 실행 모드 측면에서 실제로 어떻게 나뉘는지 를 다룬다.

이 내용이 관제와 연결되는 지점은 다음과 같다.

  • 프로세스 간 메모리 격리 가 있기 때문에 한 프로세스가 침해되어도 다른 프로세스로 바로 번지지 않는다. 공격자가 권한 상승을 노리는 이유다.
  • ps 결과에서 [kworker]처럼 대괄호로 표시되는 커널 스레드 를 구분할 줄 알아야, 이름을 위장한 악성 프로세스를 찾아낼 수 있다.

2. 핵심 개념

2-1. 두 공간의 차이

구분User SpaceKernel Space
실행 주체일반 프로그램 (bash, sshd, httpd — root 실행 포함)커널 본체, 커널 모듈, 커널 스레드
CPU 모드User Mode (x86 Ring 3)Kernel Mode (x86 Ring 0)
메모리 접근자기 프로세스의 가상 주소 공간만전체 물리 메모리
하드웨어 접근불가 → System Call로 요청직접 가능
오류 발생 시해당 프로세스만 종료 (Segmentation fault)시스템 전체 중단 가능 (Kernel panic)

2-2. 가상 메모리(Virtual Memory)

각 프로세스는 자기만의 가상 주소 공간 을 가진다. 프로세스 A의 주소 0x1000과 프로세스 B의 주소 0x1000은 서로 다른 물리 메모리를 가리킨다. 커널이 페이지 테이블로 이 연결을 관리하기 때문에 프로세스끼리 서로의 메모리를 직접 읽거나 쓸 수 없다. 이것이 메모리 격리다.

2-3. 모드 전환(Mode Switch)과 문맥 교환(Context Switch)

용어의미
모드 전환같은 프로세스가 User Mode ↔ Kernel Mode로 오가는 것 (System Call, 인터럽트)
문맥 교환CPU가 실행하는 프로세스 자체를 A → B로 바꾸는 것 (스케줄러)

3. 동작 원리

User Space와 Kernel Space — 메모리와 실행 모드

3-1. 프로세스 메모리 구조

영역내용특징
Text실행 코드읽기·실행 전용
Data / BSS전역·정적 변수
Heap실행 중 동적으로 할당한 메모리위쪽으로 커짐
공유 라이브러리libc.so 등 (mmap으로 매핑)여러 프로세스가 같은 물리 페이지 공유
Stack함수 호출, 지역 변수아래쪽으로 커짐
Kernel Space커널 영역사용자 모드에서 접근 불가

실제 배치는 /proc/<PID>/maps에서 볼 수 있다.

3-2. ASLR

ASLR(Address Space Layout Randomization)은 실행할 때마다 Stack, Heap, 라이브러리의 주소를 무작위로 바꿔 메모리 공격(버퍼 오버플로 등)의 성공률을 낮추는 커널 기능이다. kernel.randomize_va_space 값이 2면 전체 적용 상태다(2편 참고).

3-3. 커널 스레드

커널도 백그라운드 작업(디스크 쓰기, 작업 큐 처리 등)을 위해 스레드를 돌린다. 이것이 커널 스레드이며, ps에서 다음 특징으로 구분된다.

특징커널 스레드일반 프로세스
이름 표시[kthreadd], [kworker/0:1]처럼 대괄호/usr/sbin/sshd -D
부모kthreadd(PID 2)가 부모 (kthreadd 자신은 PPID 0)보통 systemd(PID 1) 또는 다른 프로세스
명령줄/proc/<PID>/cmdline 비어 있음실행 인자 존재
실행 파일/proc/<PID>/exe 링크 없음실행 파일 경로 존재
메모리사용자 공간 메모리 없음 (VSZ, RSS = 0)0보다 큼

4. 실습

# 1) 현재 쉘의 메모리 배치
cat /proc/$$/maps | head -20

# 2) 커널 스레드 확인
ps -o pid,ppid,user,vsz,rss,cmd -p 2
ps -ef | awk '$3==2' | head -10

# 3) 커널 스레드의 실행 파일 링크 (없어야 정상)
sudo readlink /proc/2/exe; echo "exit=$?"

# 4) ASLR 확인 — 같은 명령을 두 번 실행해 주소 비교
grep -m1 stack /proc/self/maps
grep -m1 stack /proc/self/maps

# 5) 모드 전환 통계 (사용자/시스템 CPU 시간)
grep -E '^cpu ' /proc/stat

5. 결과 분석

아래 출력은 형식 설명용 예시다.

① /proc/$$/maps

55d4xxxx-55d4xxxx r-xp ... /usr/bin/bash       ← Text (실행 권한 x)
55d4xxxx-55d4xxxx rw-p ... [heap]
7f1cxxxx-7f1cxxxx r-xp ... /usr/lib64/libc.so.6
7ffcxxxx-7ffcxxxx rw-p ... [stack]
권한 표기의미보안 의미
r-xp읽기·실행코드 영역
rw-p읽기·쓰기 (실행 불가)데이터 영역 — 여기서 코드 실행이 막히는 것이 정상 (NX)
rwxp읽기·쓰기·실행일반 프로그램에서 드묾 → 메모리 인젝션 의심 지표 중 하나

② 4)번 결과: 두 번 실행한 [stack] 주소가 서로 다르면 ASLR이 동작하는 것이다.

③ readlink /proc/2/exe: 커널 스레드는 실행 파일이 없으므로 오류와 함께 종료 코드가 0이 아니다.


6. 보안 관점

공격User/Kernel 경계와의 관계대응
권한 상승일반 사용자 권한에서 root 또는 커널 권한으로 경계를 넘으려는 시도패치, 최소 권한
메모리 공격격리된 프로세스 메모리 안에서 흐름을 조작ASLR, NX, 스택 보호
프로세스 위장악성 프로그램이 argv[0]을 [kworker/0:2]처럼 바꿔 커널 스레드인 척PPID·exe·메모리 확인
파일리스 실행디스크에 파일을 남기지 않고 메모리에서만 실행/proc/<PID>/exe의 (deleted), memfd: 경로

프로세스 이름(명령줄)은 실행한 쪽이 마음대로 정할 수 있는 값 이다. 그래서 이름만 보고 정상이라고 판단하면 안 되고, 커널이 관리하는 정보(PPID, 실행 파일 링크, 메모리 사용량)와 대조해야 한다.


7. SOC / 보안관제 활용

7-1. 커널 스레드 위장 프로세스 점검

# 이름이 대괄호로 시작하는데 실행 파일(exe)이 있는 프로세스 = 위장 의심
for p in /proc/[0-9]*; do
  pid=${p#/proc/}
  cmd=$(tr '\0' ' ' < $p/cmdline 2>/dev/null)
  comm=$(cat $p/comm 2>/dev/null)
  exe=$(readlink $p/exe 2>/dev/null)
  if [[ -n "$exe" && ( "$cmd" == \[* || "$comm" == \[* ) ]]; then
    echo "[의심] PID=$pid CMD=$cmd EXE=$exe"
  fi
done
# 실행 파일이 삭제되었거나 메모리 기반(memfd)인 프로세스
sudo ls -l /proc/*/exe 2>/dev/null | grep -E '\(deleted\)|memfd:'

7-2. 분석 흐름

[Event]   CPU 사용률 경보 — 프로세스 이름 [kworker/0:2]
   ↓
[검증]    PPID=1(2가 아님), exe=/tmp/.x/kw, RSS>0  → 커널 스레드 아님
   ↓
[IOC]     실행 파일 해시(sha256sum), 경로, 실행 계정, 외부 연결(ss -tanp)
   ↓
[Root Cause] 누가 언제 /tmp/.x/kw 를 실행했는가 → secure·audit 로그
   ↓
[Response]  프로세스 메모리·파일 증적 확보 → 종료 → 지속성 경로 점검

8. 핵심 정리

  • User Space는 Ring 3, Kernel Space는 Ring 0에서 동작한다. root 프로세스도 User Space다.
  • 프로세스마다 독립된 가상 주소 공간 이 있어 서로의 메모리를 직접 접근할 수 없다.
  • /proc/<PID>/maps로 메모리 배치를, rwxp 같은 이상 권한을 확인할 수 있다.
  • ASLR(randomize_va_space=2)은 메모리 공격을 어렵게 만든다.
  • 커널 스레드는 대괄호 이름, PPID 2, exe 없음, 메모리 0 이 특징이다.
  • 이름은 위장할 수 있다. PPID·exe·메모리 로 교차 확인한다.

9. 다음 글

다음 글 「5. Linux 시스템 호출(System Call)」 에서는 User Mode에서 Kernel Mode로 넘어가는 유일한 공식 통로인 System Call을 strace로 직접 관찰하고, auditd로 System Call을 기록해 누가 무엇을 실행했는지 추적하는 방법을 다룬다.


참고 자료

profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글