알프스의 카레 파스타. 카레 파스타는 처음이라 걱정했는데 생각보다 괜찮았다. 당근이랑 고기도 맛있음
- 버퍼 오버플로우 공격
- 버퍼 오버프로우 공격 개요
- 프로세스 메모리 구조와 스택 프레임 구조
- 프로세스 메모리 구조
- 텍스트 — 프로그램 코드와 상수 정의, 읽기만 가능
- 데이터 — 전역 변수와 정적 변수 저장
- 힙: 동적 메모리 호출에 의해 할당
- 스택: 함수 인자 값, 함수 내 지역 변수, 함수의 반환 주소 등 저장. 상위에서 하위로 저장
- 버퍼 오버플로우 공격 기본 개념
- 버퍼에 할당된 용량보다 더 많은 입력이 위치하면 다른 정보 변경 → 코드 삽입
- 공격 원리
- 스택 버퍼 오버플로우
- 개요
- SetUID가 설정된 루트 권한의 프로그램을 공격 대상으로 함
- 1988년 모리스 인터넷 웜에서 처음 발견 — fingerd 데몬에서 사용한 gets() 함수의 검사되지 않은 버퍼 오버플로우 이용
- 셸코드
- 오버플로우가 발생하는 버퍼에 저장되는 공격자의 코드로 실행 제어를 이동시키는 것
- 셸로 제어를 넘기고 공격당한 프로그램의 권한으로 다른 프로그램에 접근
- 스택 버퍼 오버플로우 공격 절차
- 공격 셸코드를 버퍼에 저장
- 루트 권한으로 실행되는 프로그램의 특정 함수의 스택 반환 주소 버퍼를 오버플로우시켜서 공격 셸코드가 저장되어 있는 버퍼의 주소로 덮어씌움
- 특정 함수가 호출되면 조작된 반환 주소로 셸 코드의 주소가 반환되어 셸 코드가 실행되고, 루트 권한 획득
- 힙 오버플로우
- 개요
- 힙에 요청되는 메모리는 레코드의 연결 리스트와 같은 동적 데이터 구조를 위해 사용
- 레코드가 오버플로우에 취약한 버퍼를 가진다면 연속된 메모리가 손상될 수 있음
- 실행 제어를 쉽게 이동시킬 수 있는 반환 주소 없음
- 할당된 공간이 함수에 대한 포인터를 포함하고 있다면 공격자는 이 주소를 변경하여 겹쳐 쓴 버퍼에 있는 셸코드를 가리키도록 할 수 있음
- 버퍼 오버플로우 공격 대응책
- 개요
- 컴파일 시간 방어
- 기본 개념
- 프로그램을 컴파일할 때 검사하여 버퍼 오버플로우를 방지하거나 발견하는 것을 목표로 함
- 버퍼 오버플로우를 허용하지 않는 Java, ADA, Python과 같은 언어 사용
- 메모리 접근에 자유도를 가진 언어를 사용하는 경우, 데이터 크기가 할당된 버퍼의 크기를 초과하지 않도록 반드시 확인하는 로직을 포함해야 함
- 프로그래밍 언어의 선택
- 현대 언어 — 컴파일러가 범위 검사를 강제로 수행하는 코드를 자동으로 추가
- 안전한 코딩 기법들
- 사용 자제 함수 — strcat(), strncat(), strcpy(), gets(), scanf(), sscanf(), vscanf(), vsscanf(), sprinf(), vsprinf(), gethostbyname(), realpath()
- 사용 권장 함수
- strcat() → stract_s() — 2개의 문자열을 연결시키는 함수
- strncat() → strncat_s() — 2개의 문자열을 지정한 개수만큼 연결시키는 함수
- strcpy() → strcpy_s() — 문자열을 복사해주는 함수
- strncpy() → strncpy_s()
- sprintf() → sprintf_s() — 서식에 따른 문자열을 문자 배열(버퍼)에 출력하는 함수
- gets() → gets_s() 또는 fgets() — 표준 입력에서 문자열을 입력받는 함수
- 언어 확장과 안전한 라이브러리 사용
- Libsaft — 표준 의미를 구현하면서 복사 연산이 스택 프레임 내부의 지역 변수 공간을 넘지 않도록 검사하는 기능 구현
- 스택 보호 메커니즘(Stack Guard)
- 함수의 진입(entry)과 종료(exit) 코드를 조사하고 함수의 스택 프레임에 대해 손상이 있는지 검사 → 변경 발견 시 프로그램 종료
- Stack Guard
- GCC 컴파일러 확장 버전. 추가적인 함수 진입과 종료 코드 삽입
- 컴파일러가 프로그램 함수 호출(프롤로그) 시에 ret 앞에 canary(밀고자) 값을 주입하고, 종료(return, 에필로그) 시에 canary 값이 변조되었는지 여부 확인
- 스택 쉴드 — 함수 시작 시 복귀 주소를 Global RET이라는 특수 스택에 저장해두었다가 함수 종료 시 저장된 값과 스택의 RET 값을 비교
- 실행 시간 방어
- 기본 개념
- 컴파일 시간 기법 — 기존의 프로그램을 다시 컴파일해야 함
- → 취약한 프로그램에 보호를 제공하기 위해 운영체제의 업데이트로 배포할 수 있는 실행 시간 방어법
- 실행 시점 대응책 — 실행 가능 주소 공간 보호(Executable Address Space Protection) 기법과 주소 공간 임의화(Address Space Randomization) 기법 포함
- 실행 가능 주소 공간 보호 기법 — 실행 코드가 프로세스 메모리상의 특정 위치에서만 실행될 수 있도록 함
- 주소 공간 임의화 기법 — 스택 버퍼가 위치하는 주소 공간을 메모리 내에 임의적으로 배치
- ASLR과 NOP
- 주소 공간의 임의 추출(ASLR, Address Space Layout Randomization)
- /proc/sys/kernel/randomize_va_space 설정
- 0 — ASLR 해제
- 1 — 랜덤 스택, 라이브러리 활성화
- 2 — 랜덤 스택, 라이브러리, 힙 활성화
- NOP sled(NOP 썰매) — 공격 기법인데 왜 방어에 박아둔 거임?
- 버퍼의 맨 끝 부분에 셸코드를 위치시키고 버퍼의 앞 부분에 의도적으로 채워진 NOP 기계어의 연속 → 셸코드 시작 주소 지정의 정확성을 높임
- NOP(No Operation)
- 아무 기능도 수행하지 않는 명령어. 인텔 x86의 0x90
- 빈 공간을 채우기 위한 명령어. 해당 명령어를 만나면 다음 명령어로 넘어감
- 실행 가능 주소 공간의 보호
- 스택과 힙을 실행 불가능하게 하여 방어 → 최신 운영체제
- DEP(Data Execution Prevention) — MS 윈도우 운영체제에 포함된 보안 기능. 실행 방지 메모리 영역의 실행 코드에서 응용 프로그램이나 서비스가 실행되지 못하도록
- NX-bit(No eXecute BIt) — 프로세스 명령어나 코드 또는 데이터 저장을 위한 메모리 영역을 따로 분리하는 CPU 기술. 프로세스 명령어가 지정된 구역을 상주하지 않아 실행되지 않도록 함
- DEP/NX 설정 — /proc/sys/kernerl/exec-shield
- Solaris 2.7 이상의 버전 — /etc/system 파일에 다음을 추가
- set noexec_user_stack = 1
- set noexec_user_stack_log =1
- rtl(return to libc) 공격
- ret 주소를 실행 가능한 임의의 주소(libc 영역의 주소)로 돌려 원하는 함수 수행
- 메모리에 적재된 공유 라이브러리는 스택에 존재하지 않아 Non-Executable Stack 우회 가능
- 포맷 스트링 공격(Format String Attack)
- 개요
- printf(), fprintf(), sprintf()와 같이 포맷 스트링을 사용하는 함수를 사용하는 경우, 외부로부터 입력된 값을 검증하지 않고 입출력 함수의 포맷 문자열로 그대로 사용할 때 발생 가능한 취약점
- 메모리 내용을 읽거나 쓸 수 있음 → 취약한 프로세스의 권한을 취득하여 임의의 코드 실행
- 공격 원리
- 데이터 형태에 대한 불명확한 정의
- %s, 등으로 명시해야 함
- 함수 사용 시 포맷 스트링을 지정하지 않아 사용자에 의해 결정된다면, 이를 조작하여 메모리 내용을 참조하고 특정 영역의 값을 변경할 수 있음
- %x를 통해 메모리 내용 참조 및 원하는 위치(RET 영역)로 이동 후%n을 통해 Return Address를 악성코드가 위치한 주소로 변조
- 포맷 스트링 취약점의 위협 요소
- 프로그램 파괴
- core를 덤프하는 데몬 kill
- DNS 스푸핑 시 특정 서비스가 반응하지 않도록
- 프로세스 메모리 보기
- 포맷 함수의 응답(출력 스트링)을 볼 수 있다면 정보 수집 가능
- 포맷 스트링이 무엇을 하며, 프로세스 배치가 어떤지에 대한 개략적인 내용 획득
- 임의의 메모리 덮어쓰기
- 보안 대책
- 포맷 문자열 사용 하수 사용 시 사용자 입력값을 직접적으로 포맷 문자열로 사용하지 않고, 포맷 문자열 생성에 포함하지 시키지 않도록 함
- 사용자가 포맷 스트링을 변경할 수 있는 구조로 작성하지 않도록 함
- %n, %hn — 공격자가 특정 메모리 위치에 특정 값을 변경할 수 있음 → 사용 x
- 사용자 입력값을 포맷 문자열을 사용하는 함수 사용 시 %s 권장
- 점검 툴 — gdb, ltrace, strace, Objdump
- gdb — 텍스트 기반 디버그. 소스 차원과 머신 코드 디버깅에 적절
- ltrace, strace — 프로그램 호출 시, 인자와 리턴값을 로깅하면서 라이브러리와 시스템 호출을 hook. 프로그램을 블랙 박스로 간주하여 어떻게 프로그램이 시스템과 상호작용하는지 확인 가능
- Objdump — 실행 가능한 바이너리나 오브젝트 파일에 대한 정보를 알아내는 데 사용
- 레이스 컨디션 공격
- 기본 개념
- 레이스 컨디션 — 둘 이상의 프로세스나 스레드가 공유 자원에 동시에 접근 할 때 접근 순서에 따라 비정상적인 결과가 발생하는 조건/상황
- 실행되는 프로세스가 임시 파일을 만드는 경우, 악의적인 프로그램을 통해 그 프로세스 실행에 끼어들어 임시 파일을 목적 파일로 연결(심볼릭 링크)하여 악의적인 행위를 하는 것
- 프로세스가 setuid 설정이 되어 root 권한으로 실행된다면 권한 상승 가능
- 파일 링크
- 하드 링크
- 똑같이 복사된 파일을 만드는 것
- 하드 링크된 파일 수정 시 원본 파일 또한 수정됨 → 서로 동기화
- 링크하고자 하는 파일이 다른 파티션에 존재하면 안 됨
- 심볼릭 링크
- 원본 파일 데이터를 가리키는 링크 정보만을 가짐
- 원본 파일이 삭제되더라도 원본 파일의 이름과 위치 기억
- 삭제 후 같은 경로에 같은 파일 생성 시, 해당 파일에 대해 링크 정보 보유
- 심볼릭 링크와 레이스 컨디션 공격
- 공격 대상 — 소유자가 root고, SetUID 비트를 가지며, 임시 파일을 생성하는 파일, 생성되는 임시 파일의 이름을 알아야 함
- lsof — 특정 파일에 접근하는 프로세스 목록 확인. 특정 프로세스가 사용하는 파일 목록 확인
- 생성된 임시 파일 확인 → 임시 파일로 프로그램이 실행되기 전 심볼릭 링크 파일 생성 → 심볼링 링크 파일이 관리자 권한으로 접근 가능한 파일을 가리켜 접근하도록
- 레이스 컨디션 공격에 대한 대응책
- 임시 파일에 접근하기 전 임시 파일에 대한 심볼릭 링크 설정 여부와 권한에 대한 검사 과정 추가
- 가능하면 임시 파일을 생성하지 않도록
- umask를 최하 022 정도로 유지하여 임시로 생성한 파일이 공격자에 의해 악의적으로 삭제되지 않도록 함
- 백도어
- 개요
- 설계자가 고의적으로 만든 통로
- 백 오피리스 — 악의적 목적. PC에 내장되어 사용자 정보를 저장 및 유출하기 위한 프로그램
- 리눅스/유닉스 백도어
- root 권한으로 운영되는 경우 — http 데몬이 시작 프로그램으로 자동 실행, 또는 관리자가 보안에 관심없는 경우
- 백도어 탐지와 대응책
- 현재 동작 중인 프로세스 확인
- Csrss, Svchost — 웜/바이러스 백도어가 애용하는 프로세스
- Csrss.exe — 윈도우 콘솔을 관장하고, 스레드를 생성/삭제하며, 32비트 가상 MS-DOS 모드를 지원하는 프로세스
- Explorer.exe — 작업 표시줄, 바탕 화면같은 사용자 셸을 지원하는 프로세스
- Lsass.exe
- 윈도우 서비스에 필요한 인증 프로세스 담당
- 인증 성공 시 초기 셸 실행
- 사용자별 액세스 토큰을 생성하여 다른 프로세스들이 해당 토큰을 상속받도록 함
- Mstask.exe — 시스템에 대한 백업이나 업데이트 등에 관련된 작업의 스케줄러 프로세스
- Smss.exe
- 사용자 세션 시작 기능을 담당하는 프로세스
- Winlogon, Win32(Csrss.exe)를 구동하고 시스템 변수 설정
- Winlogon이나 Csrss가 끝나기를 기다려 정상적인 Winlogon, Csrss 종료 시 시스템 종료
- Spoolsv.exe — 프린터와 팩스의 스풀링 기능 담당
- Svchost.exe
- DLL에 의해 실행되는 프로세스의 기본 프로세스
- 한 시스템에서 svhost 프로세스를 여러 개 볼 수 있음
- Services.exe — 시스템 서비스를 시작/정지하여 그들 간의 상호작용하는 기능 수행
- Taskmgr.exe — 윈도우 작업 관리자 자신
- Winlogon — 사용자 로그인/로그오프를 담당
- H-IDS 사용
- 의심스러운 실행 파일에 대해 변경 발생 여부를 확인하기 위해 checksum 수행
- 안티바이러스, IDS 소프트웨어를 통해 자동 수행
- 시스템 자원 고갈 공격(시스템 서비스 거부 공격(DoS) 공격 중 하나?)
- 개요
- 시스템 자원 고갈 공격의 종류
- 가용 디스크 자원 고갈 공격 — 파일을 생성하고 1000바이트씩 계속 작성하는 프로그램
- 가용 메모리 자원 고갈 공격 — malloc() 함수를 통해 메모리 할당만 계속 수행하는 프로그램. 디스크 고갈 공격보다 시스템 자원을 더 많이 차지
- 가용 프로세스 자원 고갈 공격 — 프로세스 할당 함수 fork()를 계속해서 사용
- 프로레스 죽이기 공격 — 루트 권한을 획득한 상태에서 사용 중인 프로세스 kill
- 리버스 엔지니어링
- 기본 개념 — 장치나 시스템의 구조를 분석하여 원리를 발견하는 과정
- 도구
- OllyDbg
- 바이너리 코드 분석을 위한 x86 디버거
- 소스코드가 없을 때 유용
- 프로그램의 리버스 엔지니어링 사용
- Procexp(Process Explorer)
- MS 윈도우용 프리웨어 작업 관리자, 시스템 모니터
- 실행 중인 프로세스에 관한 정보를 수집하기 위한 기능, 작업 관리자 기능 제공
- FileMonitor — 파일 생성, 삭제, 파일명 변경 등 실시간 확인
- 리버스 엔지니어링 공격
- 리버스 엔지니어링에 대한 대응책
- 프로그램 코드를 읽기 어렵게
- 소스코드 난독화
- 바이너리 난독화 — 컴파일 후 생성된 바이너리 변조
- 기타 시스템 보안 위협 및 대응책
- 루트킷
- 개요 — 시스템에 설치되어 그 존재의 흔적을 숨기면서 공격자가 관리자 권한으로 접근할 수 있도록 유지하는 프로그램 집합
- 루트킷의 확인
- 공격자는 행동을 숨기기 위해 정상적인 프로그램을 대신하도록 바이너리 파일을 변조시킴
- ls, ps, netstat, login, top, dir, du, ifconfig, find, tcpd 등을 변조하여 공격자 파일 은닉
- 시스템 프로그램의 파일 크기, 생성 시간, 변경 시간 등을 확인해야 함
- /bin 또는 /usr/bin에서 #ls -alct|more로 확인
- ls, ps, netstat 등의 파일은 똑같은 OS 버전의 다른 시스템 파일 사이즈를 비교하여 변조 여부 확인
- 윈도우용 — FU-Rootkit, Hxdef100, NTRootkit
- 리눅스용 — Suckit, lrk4, lrk5, adore
- 논리 폭탄(logic bomb)
- 특정한 사건 발생 시 프로그램이나 코드 실행
- 포렌식 활동 실행 시 논리 폭탄이 시작되어 디지털 증거를 삭제하도록