0. 개요
네트워크 보안에 이어 S/W가 가지는 보안 취약점에 대해 알아보자.
1. Bad Software란?
SW Complexity가 높아질 수록 bug 발생 확률 높아지므로 보안성이 낮아진다.
- 일반적으로 1000LOC당 5개 bug가 있다고 가정 (conservative extimate)
결론은 S/W에 존재하는 bug는 보안 취약점으로 이어질 수 있다.
1) Software Security Topic
SW의 보안 이슈는 크게 두가지 이슈에 의해 발생될 수 있다.
- 프로그램 자체의 결함 : 이는 프로그램을 개발하는 과정에서 비의도적으로 생긴 결함에 의해 보안 취약점이 발생할 수 있음을 의미
- 악성 SW : 애초에 공격의 목적으로 생산된 프로그램으로 인해 SW 보안이 위협받을 수 있음
① Program Flaw (unintentional)
- Buffer Overflow
- Incomplete mediation
- Race conditions
② Malicious software (intentional)
- viruses
- worms
- other breeds of malware
2) Program Flaws
: 프로그램의 결함(unintentional)은 크게 아래와 같은 원인에 의해 발생
① Buffer Overflow
② Incomplete mediation
③ Race Conditions
※ Concept of flaws
아래를 모두 아우르는 개념으로 'Flaws'를 인식하도록 한다.
- error : programming mistake
- fault : error는 program의 incorrect internal state로 이끌 수 있음
- failure : fault로 인해 발생하는 프로그램 장애
2. Buffer Overflow
1) Typical Scenario
- buffer overflow란?
임시 저장 공간(buffer)가 사용자가 설정한 영역을 벗어나서 사용되게 되었을 때 보안상 취약점이 발생할 수 있음
![](https://velog.velcdn.com/images/hjee02018/post/4508c9c7-f20a-4e5a-a120-7c34a577ba74/image.JPG)
text : 프로그램 코드가 존재
data : static 변수 등이 저장
heap : dynamic data 저장, return 주소 저장
① basic attack
- 프로그램에서 함수 호출 시 Return Address(복귀 주소)가 존재함
- return 시 복귀 주소를 통해 함수 호출 종료 후 회귀하게됨(stack이 복귀 주소를 관리)
- os에 다시 제어권을 넘겨줌
- 이때 overflow를 의도적으로 발생 시켜 Return value의 원래 값이 비정상적인 값으로 덮어쓰기 되도록함으로써 crash 발생을 유도 (즉,복귀주소가 저장된 공간이 다른 데이터값으로 덮어쓰기됨★)
② severe attack
- 이 복귀 주소를 "임의의 값"으로 덮어쓰기 하는 대신 "악성 코드가 실행되는 주소"로 덮어쓰기하면 해당 악성 코드를 실행하게됨(stack의 복귀 주소는 항상 실행되니깐,무조건)
- 이를 방지하고자 scanf 대신 scanf_s (입력 길이도 체크하도록)
※ 결론 : concept seems easy!!
: Buffer에 악성 코드를 넣고 return 주소값을 바꾸면 됨.
<- 공격이 매우 간단해 보이지만 heap 영역 어디에 return address가 있는지 알 수 없고, 그 주소에 evil code(악성코드가 실행되는 주소)를 제대로 넣는 것도 쉽지 않음. 따라서 공격 확률을 높이고자 "Stack Smashing"을 사용한다.
2) Stack Smashing
공격자는 '복귀 주소'(ret)에 '악성 코드의 주소'(addr of evil code)를 삽입해야하는데 이 둘을 파악하기 어려움
=> 공격 성공 확률을 높이고자 nop(유령 코드)를 위아래로 길게해서 (landing point를 최대한 많이 확보)
![](https://velog.velcdn.com/images/hjee02018/post/bab6eff3-f5c1-4525-9750-255d6aa5479d/image.jpg)
- landing point란?
stack smashing 공격에서 공격자가 조작한 복귀 주소가 가르키는 지점
3) Example of Buffer overflow
(전체) : 공격자는 source code를 가지고 있지 않으며 exe(bindary code)만 가지고 있음)
- buffer overflow 발생 여부 확인
A(input value)를 매우길게 써서 입력
=> ERROR msg : overflow가 되면서 return될 곳에 a가 입력됨(crash)
=> return 주소를 0x4141이 덮어쓰면서 어디로 갈지 모르겠다는 메시지
- overflow 발생을 확인
- exe를 dis-assemble를 통해 분석
=> 특정 주소(-serial number가 맞았을 때의 분기 주소)
- 위 주소를 사용하면 어떤 값을 넣어도 serial number is correct하다고 함
- simple한 공격 with binary code(.exe)
3) Stack Smashing Prevension
① buffer overflow자체를 막아( NX bit : 비실행 영역, 애초에 실행 권한을 안줌)발생 시 바로 detect (stack에서 코드 실행이 불가하도록, stack에
② 안전한 언어 사용 (자동 검사를 하므로)
③ 안전한 C 함수 사용 (scanf_s, strcpy말고 strncpy,와 같이 길이 정보를 체크하여 프로그래머의 의도와 부합하는 입력만 받도록)
④ Canary 기법
: Runtime으로 stack 검사, 무언가 덮어졌다면 조치를 취하도록
buffer랑 return value사이에 위치하여, buffer가 덮어진다면
( canary가 변경되면 바로 알려주도록 => 바로 종료하도록)
⑤ gs compiler option을 사용해
: compile 시 canary를 자동으로 들어가도록 옵션을 설정
이때 canary가 죽었을때 어디로 돌아갈지를 지정해주어야함.
(이부분이 또 공격의 대상이 될수도 있긴 함)