Without a Break

프로그래밍 관점에서의 소프트웨어 보안 본문

Software/소프트웨어보안

프로그래밍 관점에서의 소프트웨어 보안

와븨 2022. 12. 6. 21:58

프로그래머의 잘못된 가정

1. 잘못된 신뢰 가정

운영체제는 안전하고, 방화벽은 트래픽을 필터링 함

=> 따라서, 네트워크에서 오는 입력은 안전할 것이다.

 

2. 컴파일된 프로그램(Binary program)은 읽을 수 없다.

- 단지 읽기 어려운 것일 뿐, 읽을 수 있음

- 모호하지만, 감추지 않음(난독화의 경우라도)

- 리버싱도구의 진화 (코드에 담겨진 비밀 내용이 나타남, 클라이언트/서버의 통신 악용 가능성 있음)

 

3. 웹페이지는 입력을 점검할 것이다.

가정: 따라서, 프로그램에 데이터가 도착할 때 적정한 포멧을 가질 것이다.

 

- 점검하지 않음.

- 직접 http 요청을 제작 (UI 통하지 않고 CGI로 바로)

- 요청을 보내기 직전에 변경하므로, 모든 입력은 서버 측에서 재검증할 필요 있음

- 특별한 인코딩이 포함되어 있을 수 있음

 

프로그래머의 실수

Memory corruption

Mistaking size of memory

for(int i=0;i<=sizeof(dest);i++)
	dest[i] = src[i];

dest 사이즈가 4라고 가정하면, i는 0,1,2,3,4로 5번 반복된다.

=> 즉, 마지막꺼에는 복사가 안됨

 

Memory corruption 대응

증상에 대처 : 실행 및 컴파일 시 특별한 기술 적용,  공격으로 인한 피해의 제한

*공격으로 인한 피해의 제한

- containment(방지): 빠져나오지를 못하게 함

- curtailment(제한): 빠져나오는걸 지워버림

 

원인의 제거 : 코드가 취약점을 가지지 않도록 함, 코드 검토 및 분석 도구를 통한 안전한 프로그래밍

 

 

Forgetting string terminator

if(strlen(user) > sizeof(buf))
	die("user string too long\n");
strcpy(buf,user);

C string은 문자열 끝에 \n(null)이 있음. => 문자열 크기 + 1

이 점을 유의.

 

unchecked buffer boundares

Intger overflow

외부 입력을 받을 때, 입력 받은 값이 믿을만한지.

입력 값이 너무 크면 integer overflow가 발생할 수도 있음

 

type confusion errors

Type safety

- 명확하게 데이터 타입에 대한 원칙을 명시

- 데이터의 값이 프로그램이 실행되고 있는 동안에 원칙에 따라 유지되고 있어야 함

 

데이터 형 관점에서의 문제 (C)

- 암묵적 형변환

int i;
i = 7.5;

 

 

- 명시적 형변환

int i;
i = (int)7.5;

 

 

 

방어적 프로그래밍 - 경계 점검

- 쓰기 전 데이터 길이 검사

- 배열의 첨자가 범위 안에 있는 지 검사

- 경계 조건들을 점검하여 Off-by-One 에러를 피함

- 입력의 길이를 제한

- 위험한 코드를 실행할 수 있는 위험한 API 호출을 경계

 

경계 점검의 책임

책임의 분산 : 프로그래머, 프로그래밍 언어 및 컴파일러, 운영체제

 

코드 주입 공격의 이해

명령어의 주입 - 쉘 활용

프로그래머는 시스템 명령 호출을 응용프로그램 코드에 삽입 => 명령어 쉘은 이러한 입력을 번역이라고 함

 

사용 이유

- 프로그래밍 언어가 명령에 해당하는 라이브러리를 갖고 있지 않음

- 편리성, 시간 절약

 

명령어의 주입 - 웹 환경

1. 항진 명제

: 항상 참으로 검증되는 코드 삽입

- 항진 명제의 차단은 어려움

- 1>0, 'x' LIKE 'x' 등등

 

2. Piggy-backed queires

: 쿼리에 또 다른 쿼리 업기

 

3. Inference pairs

: 두가지의 상반된 문제를 준 후 반응을 보고, 어떤 기능을 가지고 있는지 확인함

- 두 쿼리의 결과 차이를 통해 정보 추출

- 로긴 파라미터 취약점 검사

 

4. Stored procedures and other DBMS features

SQL 프로시져

- 스크립터 언어 형태

- 추가 취약점

 

프로그래머

매번 점검 - 성능에 영향 줌

 

프로그래밍 언어의 안전성

프로그램 언어의 특성 자동 제공

- Memory safety: 임의의 메모리 주소에 데이터를 읽고 쓰는 것을 불허. Corrupted된 메모리로부터의 overflow 공격을 막게 됨.

- Type safety: 데이터 전달 시 명확한 데이터 형을 명시하도록 하여 임의의 데이터가 전달되는 것을 차단함. 공격자들이 데이터 영역에 이진 코드를 주입하여 실행하는 것을 어렵게 함.

 

컴파일러와 도구를 활용

- safe compiler : 자동으로 점검 코드를 생성하여 실행 도중 경계와 데이터 타입을 점검

- a verifying compiler : 정적으로 컴파일 시에 코드가 안전한지를 점검

- security testing tools: security bugs를 찾기 위해 입력을 생성하여 입력해보는 도구

- program analysis tools: 소스 코드가 특정 취약점이 있는지를 확인

 

라이브러리 관점의 안전성

안전하지 않는 함수와 이의 설명을 검토

- Microsoft's recommendations

- CERT Secure C Coding

 

Code security scanning tool 사용

- 위험한 API 호출 탐지기능 보유

- 코드를 찾는 것은 쉽지만, 특정 취약점을 식별하기 위해 깊은 분석 필요

 

안전한 라이브러리 선택 사용

- The Safe C Library - Visual Studio 2005부터

- 경계 점검은 최근 발표된 C11 standard의 일부