Skip to content
Published on

[운영체제] 16. 보안: 위협과 방어

Authors

보안: 위협과 방어

운영체제 보안은 시스템의 자원을 무단 접근, 악의적 수정, 파괴로부터 보호하는 것을 목표로 합니다. 이 글에서는 보안 위협의 종류, 공격 기법, 암호화 기초, 인증 방법, 그리고 시스템 수준의 방어 메커니즘을 살펴봅니다.


1. 보안 문제 개요

보안의 3요소 (CIA Triad)

          기밀성
       (Confidentiality)
          ╱     ╲
         ╱   보안  ╲
        ╱    목표    ╲
       ╱               ╲
  가용성 ─────────── 무결성
(Availability)     (Integrity)
요소설명위협 예시
기밀성인가된 사용자만 정보 접근도청, 데이터 유출
무결성인가된 방법으로만 정보 수정데이터 변조, 위조
가용성인가된 사용자가 필요 시 접근 가능DoS 공격, 랜섬웨어

보안 위협 계층

┌──────────────────────────────────────┐
│            공격 표면                  │
│                                      │
│  물리적: 서버 직접 접근, USB 공격    │
│  │                                   │
│  네트워크: 원격 공격, 패킷 스니핑    │
│  │                                   │
│  운영체제: 권한 상승, 커널 익스플로잇│
│  │                                   │
│  애플리케이션: 코드 인젝션, XSS│  │                                   │
│  사회공학: 피싱, 스피어피싱           │
└──────────────────────────────────────┘

2. 프로그램 위협 (Program Threats)

맬웨어 (Malware) 분류

┌────────────────────────────────────────────────┐
│               맬웨어 분류                       │
│                                                │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐          │
│  │ 바이러스│ │  웜     │ │ 트로이  │          │
│  │         │ │         │ │ 목마    │          │
│  │숙주 필요│ │자가 전파│ │위장     │          │
│  └─────────┘ └─────────┘ └─────────┘          │
│                                                │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐          │
│  │ 랜섬    │ │ 스파이  │ │ 루트킷  │          │
│  │ 웨어    │ │ 웨어    │ │         │          │
│  │파일 암호│ │정보 수집│ │은닉     │          │
│  └─────────┘ └─────────┘ └─────────┘          │
└────────────────────────────────────────────────┘

코드 인젝션 (Code Injection)

외부 입력을 통해 악의적 코드를 실행하는 공격입니다.

// SQL 인젝션 예시 - 취약한 코드
void login(const char *username, const char *password) {
    char query[512];
    // 위험: 사용자 입력을 직접 쿼리에 삽입
    sprintf(query, "SELECT * FROM users WHERE name='%s' AND pass='%s'",
            username, password);
    execute_query(query);
}

// 공격 입력:
// username: admin' --
// password: (아무 값)
// 생성되는 쿼리:
// SELECT * FROM users WHERE name='admin' --' AND pass='...'
// -- 이후는 주석 처리되어 비밀번호 검증 우회
// 방어: 준비된 문장(Prepared Statement) 사용
void login_safe(const char *username, const char *password) {
    // 매개변수화된 쿼리 - 입력이 데이터로만 처리됨
    prepare_statement("SELECT * FROM users WHERE name=? AND pass=?");
    bind_parameter(1, username);
    bind_parameter(2, password);
    execute_prepared();
}

버퍼 오버플로 (Buffer Overflow)

가장 고전적이면서도 여전히 위험한 공격 기법입니다.

// 취약한 코드 예시
void vulnerable_function(const char *input) {
    char buffer[64];
    // 위험: 입력 길이를 확인하지 않음
    strcpy(buffer, input);  // 64바이트 이상 입력 시 오버플로
}
스택 구조 (오버플로 전):
┌──────────────────┐ 높은 주소
│ 반환 주소        │
├──────────────────┤
│ 이전 프레임 포인터│
├──────────────────┤
│ buffer[64] (64 바이트)├──────────────────┤ 낮은 주소

스택 구조 (오버플로 후):
┌──────────────────┐ 높은 주소
│ 악성 코드 주소   │ ← 반환 주소 덮어씀!
├──────────────────┤
AAAAAAAAAAAAAAAA │ ← 덮어씀
├──────────────────┤
AAAAAAAAAAAAAAAA │ ← 공격 데이터
 (64 바이트 이상)├──────────────────┤ 낮은 주소
// 방어: 안전한 문자열 함수 사용
void safe_function(const char *input) {
    char buffer[64];
    // 길이를 제한하는 안전한 복사
    strncpy(buffer, input, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0';
}

3. 시스템 및 네트워크 위협

웜 (Worm)

네트워크를 통해 자동으로 전파되는 자기 복제 프로그램입니다.

감염된 호스트 A
    ├── 네트워크 스캔 (취약 호스트 탐색)
    ├── 호스트 B 감염 (취약점 악용)
    │   ├── 호스트 D 감염
    │   └── 호스트 E 감염
    └── 호스트 C 감염 (취약점 악용)
        ├── 호스트 F 감염
        └── ...

지수적 전파 → 짧은 시간에 대규모 감염

포트 스캐닝

공격자                          대상 서버
  │                                │
  ├── SYN → 포트 22 ──────────────→│
  │←──────────── SYN-ACK ─────────│  포트 22: 열림 (SSH)
  │                                │
  ├── SYN → 포트 23 ──────────────→│
  │←──────────── RST ─────────────│  포트 23: 닫힘
  │                                │
  ├── SYN → 포트 80 ──────────────→│
  │←──────────── SYN-ACK ─────────│  포트 80: 열림 (HTTP)
  │                                │
  ├── SYN → 포트 443 ─────────────→│
  │←──────────── SYN-ACK ─────────│  포트 443: 열림 (HTTPS)
  ...

DoS (Denial of Service) 공격

일반 요청:
클라이언트 → [정상 요청] → 서버 → [정상 응답]

DoS 공격:
공격자 → [대량의 요청]서버 (과부하) → 정상 사용자 접근 불가

DDoS (분산 DoS):
봇넷 호스트 1 ─→ ┐
봇넷 호스트 2 ─→ ├→ 서버 (과부하)
봇넷 호스트 3 ─→ ┤
    ...        ─→ ┘

SYN Flood 공격:
공격자가 SYN 패킷만 대량 발송, SYN-ACK 응답 무시
→ 서버의 연결 대기 큐 고갈

4. 암호화 (Cryptography)

대칭 키 암호화

하나의 키로 암호화와 복호화를 모두 수행합니다.

송신자                              수신자
┌──────┐    ┌──────────┐    ┌──────┐
│평문  │─→ │암호화    │─→ │암호문│─→ ... ─→ ┌──────────┐─→ ┌──────┐
│Hello │    (비밀 키) │    │X7k9p│         │복호화    │   │Hello │
└──────┘    └──────────┘    └──────┘         (같은 키) │   └──────┘
                                             └──────────┘

알고리즘: AES (128/192/256비트), ChaCha20
문제: 키 교환 - 어떻게 안전하게 키를 공유할 것인가?

비대칭 키 암호화 (공개 키 암호화)

공개 키와 개인 키 쌍을 사용합니다.

수신자의 키 쌍:
┌──────────┐  ┌──────────┐
│ 공개 키  │  │ 개인 키  │
 (공개) (비밀)└──────────┘  └──────────┘

암호화:
송신자: 평문 + 수신자 공개 키 → 암호문

복호화:
수신자: 암호문 + 수신자 개인 키 → 평문

디지털 서명:
서명자: 해시 + 서명자 개인 키 → 서명
검증자: 서명 + 서명자 공개 키 → 해시 확인

알고리즘: RSA, ECC (Elliptic Curve Cryptography)

해시 함수

임의 길이 입력을 고정 길이 출력으로 변환합니다.

입력                    SHA-256 해시
"Hello"       →  185f8db32271fe25f561a6fc938b2e26
                 4306ec304eda518007d1764826381969

"Hello!"      →  334d016f755cd6dc58c53a86e183882f
                 8ec14f52fb05345887c8a5edd42c87b7

특성:
- 단방향: 해시로부터 원본 복원 불가
- 충돌 저항성: 같은 해시를 만드는 다른 입력 찾기 어려움
- 눈사태 효과: 입력 1비트 변경 시 해시가 크게 변함

용도: 비밀번호 저장, 무결성 검증, 디지털 서명
알고리즘: SHA-256, SHA-3, bcrypt (비밀번호용)
// 비밀번호 해싱 예시 (의사 코드)
#include <openssl/sha.h>
#include <string.h>
#include <stdio.h>

void hash_password(const char *password, const char *salt,
                   unsigned char *hash_out) {
    char salted[256];
    // 솔트(salt)를 추가하여 레인보우 테이블 공격 방지
    snprintf(salted, sizeof(salted), "%s%s", salt, password);

    SHA256((unsigned char *)salted, strlen(salted), hash_out);
}

int verify_password(const char *input, const char *salt,
                    const unsigned char *stored_hash) {
    unsigned char computed[SHA256_DIGEST_LENGTH];
    hash_password(input, salt, computed);
    return memcmp(computed, stored_hash, SHA256_DIGEST_LENGTH) == 0;
}

5. 사용자 인증 (User Authentication)

인증 방법 분류

┌─────────────────────────────────────────────┐
│             인증 요소 (Factor)│                                             │
│  ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│  │ 지식 기반 │ │ 소유 기반 │ │ 생체 기반 │ │
 (알고있는 │  (가지고   │  (자신의   │ │
│  │  것)      │ │  있는 것) │ │  특성)    │ │
│  │           │ │           │ │           │ │
│  │ 비밀번호  │ │ 보안 토큰 │ │ 지문      │ │
│  │ PIN      │ │ 스마트카드│ │ 홍채      │ │
│  │ 보안 질문 │ │ OTP      │ │ 얼굴 인식 │ │
│  └───────────┘ └───────────┘ └───────────┘ │
│                                             │
│  다중 요소 인증 (MFA):│  두 가지 이상의 요소를 결합하여 보안 강화     │
└─────────────────────────────────────────────┘

비밀번호 보안

취약한 비밀번호 저장:
┌──────────────────────────────────┐
│ users 테이블                     │
│ username │ password              │
│ admin    │ admin123     ← 평문!│ user1    │ password1    ← 위험!└──────────────────────────────────┘

안전한 비밀번호 저장:
┌──────────────────────────────────────────────┐
│ users 테이블                                 │
│ username │ salt     │ hashed_password        │
│ admin    │ x7k2m9   │ a3f2e8...  (해시값)│ user1    │ p4q8n1   │ b7d1c5...  (해시값)└──────────────────────────────────────────────┘
→ 솔트 + 느린 해시 (bcrypt, Argon2)

6. 보안 방어 (Security Defenses)

방화벽 (Firewall)

외부 네트워크 (인터넷)
  ┌────┴─────────────────┐
  │      방화벽          │
  │                      │
  │  규칙 예시:  │  허용: TCP 80 (HTTP)  │  허용: TCP 443 (HTTPS)  │  차단: TCP 23 (Telnet)  │  차단: 기타 모든 포트 │
  └────┬─────────────────┘
  내부 네트워크 (LAN)
  ┌────┴────┬────────┐
  │         │        │
 서버1    서버2    서버3

침입 탐지 시스템 (IDS)

네트워크 트래픽
┌─────────────────────┐
IDS 엔진         │
│                     │
│  시그니처 기반:│  알려진 공격 패턴    │
│  매칭               │
│                     │
│  이상 탐지 기반:│  정상 패턴 학습 후   │
│  비정상 행위 감지    │
│                     │
│  매칭 시 → 알림     │
└─────────────────────┘
  관리자에게 경고
  (또는 IPS가 자동 차단)

ASLR (Address Space Layout Randomization)

버퍼 오버플로 공격을 어렵게 만드는 기법입니다.

ASLR 없이 (고정 주소):          ASLR 적용 (랜덤 주소):
┌──────────────────┐            ┌──────────────────┐
0x08048000 코드  │            │ 0x55a3b000 코드  │ ← 매번 다른 주소
...              │            │ ...0x0804A000 데이터│            │ 0x55a3d000 데이터│
...              │            │ ...0xBFFF0000 스택  │            │ 0x7FFD2000 스택  │ ← 매번 다른 주소
...              │            │ ...0xB7E00000 라이브│            │ 0x7F4A1000 라이브│
│             러리 │            │             러리 │
└──────────────────┘            └──────────────────┘
공격자가 주소 예측 가능          공격자가 주소 예측 불가

추가 방어 기법

┌─────────────────────────────────────────┐
│           보안 방어 기법                 │
│                                         │
│  스택 카나리 (Stack Canary):│  ┌──────────┐                           │
│  │ 반환 주소│                           │
│  ├──────────┤                           │
│  │ 카나리값 │ ← 함수 반환 시 검증       │
│  ├──────────┤   값 변경 시 → 프로그램 종료│
│  │ buffer   │                           │
│  └──────────┘                           │
│                                         │
DEP (Data Execution Prevention):│  스택/힙 영역의 코드 실행 금지          │
W^X: 쓰기 가능 ⊕ 실행 가능            │
│                                         │
CFI (Control Flow Integrity):│  프로그램의 제어 흐름이 예상 경로만      │
│  따르도록 강제                           │
└─────────────────────────────────────────┘

7. 정리

  • 프로그램 위협: 맬웨어(바이러스, 웜, 랜섬웨어), 코드 인젝션, 버퍼 오버플로
  • 네트워크 위협: 포트 스캐닝, DoS/DDoS 공격, 중간자 공격
  • 암호화: 대칭 키(AES), 비대칭 키(RSA), 해시(SHA-256)
  • 인증: 지식/소유/생체 기반, 다중 요소 인증(MFA)
  • 방어: 방화벽, IDS/IPS, ASLR, DEP, 스택 카나리, CFI
퀴즈: 보안

Q1. 버퍼 오버플로 공격을 방어하는 기법 3가지를 설명하세요.

A1. (1) ASLR: 메모리 주소를 무작위로 배치하여 공격자가 목표 주소를 예측하기 어렵게 합니다. (2) 스택 카나리: 반환 주소 앞에 감시 값을 두어 오버플로 시 변조를 감지합니다. (3) DEP(Data Execution Prevention): 스택이나 힙 영역에서 코드 실행을 금지하여 주입된 코드가 실행되지 않게 합니다.

Q2. 대칭 키 암호화와 비대칭 키 암호화의 차이점은?

A2. 대칭 키는 하나의 키로 암호화와 복호화를 모두 수행하여 속도가 빠르지만, 키를 안전하게 교환하는 문제가 있습니다. 비대칭 키는 공개 키와 개인 키 쌍을 사용하여 키 교환 문제를 해결하지만, 연산이 느립니다. 실제로는 비대칭 키로 대칭 키를 교환한 후 대칭 키로 데이터를 암호화하는 하이브리드 방식을 사용합니다.

Q3. 비밀번호 저장 시 솔트(salt)를 사용하는 이유는?

A3. 같은 비밀번호라도 사용자마다 다른 솔트를 추가하면 해시값이 달라집니다. 이를 통해 레인보우 테이블(미리 계산된 해시 사전) 공격을 무력화하고, 같은 비밀번호를 사용하는 사용자를 해시값만으로 식별할 수 없게 합니다.