본문 바로가기

Basic Theory/C/C++

strncpy 함수

Buffer Over Flow(이하 BOF)를 막기위해서 쓰는 함수 中 strncpy 라는 함수가 있다. 하지만 strncpy 함수에서도 취약한 부분이 발생할 수 있다는것을 BOF 원정대 (golem -> darkknight) 문제를 풀면서 공부할 수 있었다.


= strncpy 함수에 대한 설명 =


#include <string.h> // C++ 에서는 <cstring>

char * strncpy ( char * destination, const char * source, size_t num );


- 간략한 설명 -

문자열에서 일부 문자들 만을 복사한다.

source 에서 destination 으로 source 의 처음 num 개의 문자들 만을 복사(NULL 도 포함해서) 한다. num 보다 source 의 문자 수가 더 적다면은 모자란 부분은 0 으로 생각되어서 destination 에 복사가 된다. 다시 말해 source 가 "abc" 인다, num 이 5 라면 destination 에는 "abc\0\0" 가 들어가게 된다. 


strncpy 함수는 복사시 destination 끝에 반드시 NULL 문자를 붙이는 것이 아니므로 사용에 주의를 해야 한다. 


- 인자 -

destination : destination 배열을 가리키는 포인터로 문자열이 복사될 곳이다. 

source : 복사 될 C 문자열이다. 

num : source 에서 복사 할 문자의 개수 이다. 


- 리턴값 -

destination 을 리턴한다. 


[출처] : http://itguru.tistory.com/80



이제 strncpy 함수에 대한 설명은 알았는데 어떻게 취약한 부분이 발생할 수 있는지에 대해서 알아보자. 간단한 예를 Wiki 검색 결과 내에서 찾을 수 있었다.


아래의 C 소스 코드는 일반적인 프로그래밍 실수를 보여준다. 일단 컴파일 되면, 너무 긴 커맨드라인 인자 문자열을 가지고 실행하면 프로그램은 버퍼 오버플로우 오류를 발생할 것이다. 왜냐하면 이 인자의 길이를 체크하지 않고 버퍼를 채우는 데 사용하기 때문이다. [2]

/* overflow.c - 버퍼 오버플로우를 설명한다 */
 
#include <stdio.h>
#include <string.h>
 
int main(int argc, char *argv[])
{
  char buffer[10];
  if (argc < 2)
  {
    fprintf(stderr, "사용법: %s 문자열\n", argv[0]);
    return 1;
  }
  strcpy(buffer, argv[1]);
  return 0;
}

9개 이하의 문자 스트링은 버퍼 오버플로우를 일으키지 않는다. 10 이상의 문자들은 오버플로우를 일으킨다. 이것은 언제나 부정확하지만 프로그램 오류나 세그먼트 폴트를 일으키지는 않는다. strncpy는 버퍼에 쓰일 문자의 개수를 제한할 수 있다.

이 프로그램은 strncpy를 이용해 아래와 같이 안전하게 다시 쓸 수 있다: [2]

/* better.c - 문제 해결 방법 하나를 설명한다 */
 
#include <stdio.h>
#include <string.h>
 
int main(int argc, char *argv[])
{
  char buffer[10];
  if (argc < 2)
  {
    fprintf(stderr, "사용법: %s 문자열\n", argv[0]);
    return 1;
  }
  strncpy(buffer, argv[1], sizeof(buffer));
  buffer[sizeof(buffer) - 1] = '\0';  /* 문자열의 끝을 분명히 맺는다 */
  return 0;
}










'Basic Theory > C/C++' 카테고리의 다른 글

지역변수(local variable)  (0) 2012.07.02
Libc(C 표준 라이브러리)  (0) 2012.06.26
Segmentation Fault란?  (1) 2012.06.21