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
- Software Development Life Cycle
- Security Policies
- Core Security Policy
- Isolation: API
- Least Privilege: 최소 권한
- Fault Compartments: 망해도 해당 부분만 망하고, 나머지는 동작할 것
- Type Safety: 형 변환 조심하기
- Memory Safety: 엄한데 가르키지 않기, 오버플로우 조심, NPE, 이중 해제
- Core Security Policy
- C/C++의 Memory Safety 보장법
- C/C++ 위험 기능 제거한 방언 생성
- Limit Ptr, Null check, GC, Spatial/Temporal Memory Safety 등 지원
- C/C++ 위험 기능 사용 보호
- Object Based: Object별 메타데이터 저장
- Pointer Based: 포인터별 메타데이터 저장
- Soft Bound: Compiler 기반 C/C++ 메모리 안정성 확인
- 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 코어에서 실행
- 셸에서 프로그램이 실행되는 과정
- fork() syscall로 프로그램 실행할 새 프로세스 생성
- exec() syscall로 로더 호출하며, 파라미터로 실행파일 이름 전달
- 로더가 프로세스 주소 공간을 사용해 지정된 프로그램을 메모리에 적재
- 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)
- 실행 불가능한 메모리와 코드 사이닝 같은 보안 방어가 존재하는 경우, 공격자가 코드를 실행할 수 있게하는 보안 취약점 공격
- 프로그램 제어 흐름을 하이재킹하기 위해 콜 스택 제어 얻음
- 이후 선택된 기계어를 실행시킴
- DEP (Data Execution Prevention)
Authentication vs Authorization¶
- 참고 1: https://velog.io/@aaronddy/%EC%9D%B8%EC%A6%9DAuthentication%EA%B3%BC-%EC%9D%B8%EA%B0%80Authorization
- 참고 2: https://gintrie.tistory.com/36
- 참고 3: https://dev-coco.tistory.com/104
- Authentication(인증)
- 유저가 누구인지 확인하는 절차
- 회원가입/로그인
- Who are you?
- Validate a system that accessed by right person
- 유저가 누구인지 확인하는 절차
- Authorization(인가)
- 유저에게 특정 권한을 허락하는 것
- 사용자가 request를 실행할 수 있는 권한이 있는가?
- Check users' permission to access data
SW Bug/Danger의 종류 (C/C++)¶
- Arbitrary Write
- pointer의 위치 idx를 파라미터로 받을 수 있도록 open해 두는 것
- Improper Initialize
- 배열 중에 일부분 값 넣어서 초기화 시키는 등
- 뜬금없는 값 할당
- 변수 Scope
- int a 여기서 할당, int a 또 괄호안에서 할당?!
- &, *, -> 의 Scope를 지정해주자
- ex. curr->next 라고 했을때 애매해! => (curr)->next 이런식으로 바꿔보자!
- Partial init
- 부분적으로 할당
- Double Goto
- 해제 후 접근
- Casting 지 맘대로 했을 때
C Header File(.h), C Source File(.c)¶
- 참고: https://www.youtube.com/watch?v=QAxjN0KUaLo
- 정의

- C Header File에 선언부를, C Source File에 구현부를 넣어주는 것이 일반적!
- Java의 interface와 비슷한 기능인건가?
- 같은 것은 아니야!
- 헤더 파일은 컴파일러에게 헤더파일에 있는 클래스/함수는 있는 것이니, 굳이 해당 클래스/함수를 찾으려고 전체 프로젝트를 뒤지지 말고 뚝딱 컴파일하라고 알려주는 용도
- 헤더 파일은 자바 클래스의 public 멤버 명세정도라고 생각해도 될듯해
- 같은 것은 아니야!
C & * ->¶
- &
- 참고: https://wikidocs.net/2154
- &변수: 변수의 주소를 알려줌
-
*
- 참고: https://dojang.io/mod/page/view.php?id=275
- "*"는 포인터 변수
- 변수의 주소를 저장할 수 있는 변수!
- ->
-
구조체 포인터에서의 포인터 연산
#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; }
-