콘텐츠로 이동

2022 04 14

2022-04-14

컴퓨터 보안 개념 정리

  • CIA
    • Confidentiality / Integrity / Availablity
  • Security Mechanism
    • Isolation: API로만 접근 가능하도록
    • Least Privilege: 정말 기능을 쓸 정도의 권한만 부여하기
    • Fault Compartments: Isolation과 Least Privilege의 조합
      • ex. Docker
  • SDLC
    • Software Development Life Cycle
      • Requirement Analysis
      • Design
      • Implementation
      • Testing
      • Release
      • Maintenance
  • Security Policies
    • Core Security Policy
      • Isolation: API
      • Least Privilege: 최소 권한
      • Fault Compartments: 망해도 해당 부분만 망하고, 나머지는 동작할 것
      • Type Safety: 형 변환 조심하기
      • Memory Safety: 엄한데 가르키지 않기, 오버플로우 조심, NPE, 이중 해제
  • C/C++의 Memory Safety 보장법
    1. C/C++ 위험 기능 제거한 방언 생성
      • Limit Ptr, Null check, GC, Spatial/Temporal Memory Safety 등 지원
    2. C/C++ 위험 기능 사용 보호
      • Object Based: Object별 메타데이터 저장
      • Pointer Based: 포인터별 메타데이터 저장
      • Soft Bound: Compiler 기반 C/C++ 메모리 안정성 확인
  • Reverse Engineering
    • Machine Code => Assembly
    • 기계어와 Assembly 코드는 1:1 대응이 됨
  • ELF(Executable and Linkable Format) format
    • 참고: https://namu.wiki/w/ELF
    • Recap
      • 참고: https://papimon.tistory.com/37
      • 소스코드 --(컴파일)--> 오브젝트 파일 --(링킹)--> 이진 실행 파일 --(로더)--> CPU 코어에서 실행
      • 셸에서 프로그램이 실행되는 과정
        1. fork() syscall로 프로그램 실행할 새 프로세스 생성
        2. exec() syscall로 로더 호출하며, 파라미터로 실행파일 이름 전달
        3. 로더가 프로세스 주소 공간을 사용해 지정된 프로그램을 메모리에 적재
      • UNIX/Linux의 오브젝트 파일이 ELF 형식
    • 개요
      • 유닉스 계열 OS의 실행/오브젝트 파일/공유 라이브러리/코어 덤프를 지원하는 바이너리 파일
      • 즉 실행 파일
    • 구조
      • ELF Header
        • 실행 파일에 대한 정보
        • 오브젝트 파일인지, 실행 파일인지, 공유 라이브러리 인지, 어떤 OS와 비트를 위해 컴파일 된건지 등등
      • Program Header Table
        • 프로그램 헤더 테이블
      • .text
        • 여기에 코드가 들어감
        • push, rax, mov, [esp-4] 이런게 바이너리로 들어감
      • .rodata
        • read only data segment
        • static이나 const의 값들
      • .data
        • 데이터가 있음
        • 읽고 쓸 수 있는 데이터
  • Syscall Convention
    • rax/eax 등은 syscall에 번호가 부여된다
    • 파라미터로 register값이 넘어가고 이는 x86, x64 등에 따라 달라짐
  • Exploitation
    • DoS(Denial of Service) : 서비스 강제 종료시켜 정상 요청을 받지 못하도록 함
    • Leak Information : 정보 유출 시키기
    • Code Execution : 코드 실행 시키기
      • Code injection
      • Code reuse
      • 하이잭킹
    • Privilege Escalation : Sudo 권한등을 탈취
  • Mitigation
    • DEP (Data Execution Prevention)
      • 메모리 중에 실행 가능이라 마킹되지 않은 페이지에서 코드 실행 방지하도록 하는 HW + SW solution
    • ROP (Return Oriented Programming)
      • 실행 불가능한 메모리와 코드 사이닝 같은 보안 방어가 존재하는 경우, 공격자가 코드를 실행할 수 있게하는 보안 취약점 공격
      • 프로그램 제어 흐름을 하이재킹하기 위해 콜 스택 제어 얻음
        • 이후 선택된 기계어를 실행시킴

Authentication vs Authorization

  • Authorization(인가)
    • 유저에게 특정 권한을 허락하는 것
    • 사용자가 request를 실행할 수 있는 권한이 있는가?
    • Check users' permission to access data

SW Bug/Danger의 종류 (C/C++)

  1. Arbitrary Write
    • pointer의 위치 idx를 파라미터로 받을 수 있도록 open해 두는 것
  2. Improper Initialize
    • 배열 중에 일부분 값 넣어서 초기화 시키는 등
    • 뜬금없는 값 할당
  3. 변수 Scope
    • int a 여기서 할당, int a 또 괄호안에서 할당?!
  4. &, *, -> 의 Scope를 지정해주자
    • ex. curr->next 라고 했을때 애매해! => (curr)->next 이런식으로 바꿔보자!
  5. Partial init
    • 부분적으로 할당
  6. Double Goto
  7. 해제 후 접근
  8. Casting 지 맘대로 했을 때

C Header File(.h), C Source File(.c)

  • Java의 interface와 비슷한 기능인건가?
    • 같은 것은 아니야!
      • 헤더 파일은 컴파일러에게 헤더파일에 있는 클래스/함수는 있는 것이니, 굳이 해당 클래스/함수를 찾으려고 전체 프로젝트를 뒤지지 말고 뚝딱 컴파일하라고 알려주는 용도
      • 헤더 파일은 자바 클래스의 public 멤버 명세정도라고 생각해도 될듯해

C & * ->

  • &
    • 참고: https://wikidocs.net/2154
    • &변수: 변수의 주소를 알려줌
      #include <stdio.h>
      
      int main(void) {
        int num; 
        scanf("%d", &num);
        printf("%d", num);
      
        return 0;
      }
      
  • ->
    • 구조체 포인터에서의 포인터 연산

      #include<stdio.h>
      
      struct Data {
        int num1;
        int num2;
      }
      
      int main() {
        struct Data d[3] = { {10, 20}, {30, 40}, {50, 60} };
        struct Data *ptr;
        prt = d; // 구조체 배열 첫 요소의 메모리 주소를 포인터에 저장
      
        print("%d %d\n", (ptr + 1) -> num1, (ptr + 1) -> num2); //30 40 출력
        print("%d %d\n", (ptr + 2) -> num1, (ptr + 2) -> num2); //50 60 출력
      
        return 0;
      }
      

      • int가 4byte이니, 구조체의 크기는 총 8byte
      • ptr+1 하면 8byte씩 추가된대 (음... 뭐지? 연산자에서 뚝딱 처리해주는건가 같은 자료형에 +1 연산을?)
        #include<stdio.h>
        #include<stdlib.h>
        #include<string.h>
        
        struct Data {
          int num1;
          int num2;
        }
        
        int main() {
          void *ptr = malloc(sizeof(struct Data) * 3); // 포인터가 가르킬 공간을 먼저 확보 (총 24 byte)
          struct Data d[3];
        
          ((struct Data *) ptr)->num1 = 10; // 포인터의 공간 4byte씩 할당
          ((struct Data *) ptr)->num2 = 20;
        
          ((struct Data *) ptr + 1)->num1 = 30;
          ((struct Data *) ptr + 1)->num2 = 40;
        
          ((struct Data *) ptr + 2)->num1 = 50;
          ((struct Data *) ptr + 2)->num2 = 60;
        
          memcpy(d, ptr, sizeof(struct Data) * 3);
        
          printf("%d %d\n", d[1].num1, d[1].num2);
        
          free(ptr);
        
          return 0;
        }