모든 C 프로그래머가 알아야 할 보안 위험 / 취약점은 무엇입니까? [닫은]


13

높은 수준의 프로그래밍 언어에서 잘 테스트되고 입증 된 API를 사용하는 것과는 달리 하드웨어에 밀접하게 접촉하면 많은 보안 위험이 발생합니다. Java와 같은 언어보다 C에서 버퍼 오버플로를 발생시키는 것이 훨씬 쉽습니다.

모든 C 프로그래머가 알아야 할 위험 또는 취약점 (예 : 버퍼 오버 플로우)은 무엇입니까 (C 프로그래머와 관련된 IE 취약점)? 이로 인해 어떤 문제가 생길 수 있습니까? 이를 피하는 방법과 프로그램에서 발생하는 일반적인 실수는 무엇입니까?


이 목록 은 어떻 습니까 : owasp.org/index.php/Category:OWASP_Top_Ten_Project 이것보다 더 필요한 것은 무엇입니까?
S.Lott

2
@ S.Lott : 웹 개발의 보안 문제에 관한 것 같습니다. 내가 실제로 요구하는 것보다 일반적으로 더 많은 리소스가있는 것 같습니다.
Anto

@Anto : 보안에 관한 모든 자료와 요구하는 보안을 구분하기 위해 질문을 업데이트 하십시오.
S.Lott

@ S.Lott : 무슨 말인지 잘 모르겠습니다. 나는 대부분의 C 프로그래머에게 중요한 보안, 즉 버퍼 오버 플로우와 같은 것들과 C에서 가능한 다른 것들을 요구한다.
Anto

@Anto : "실제로 요청하는 것보다 일반적으로 [웹 보안?]에 더 많은 리소스가있는 것 같습니다"웹 보안이 아닌 일부 보안에 대해 묻는 것 같습니다. 진실? 그렇다면 질문을 업데이트 하여 원하는 내용을 설명하십시오. 그릇된? 그럼 당신은 되어 있는 경우에, 왜 귀하의 질문에 언급 된 OWASP 목록이 아닌, 웹 보안에 대해 물어?
S.Lott

답변:


13

버퍼 오버 플로우는 큰 문제입니다. C의 어떤 것도 기본적으로 범위 검사가 없으므로 버퍼를 덮어 쓰는 것이 매우 쉽습니다. gets()버퍼 오버플로를 막을 수 없으며 거의 ​​사용해서는 안되는 표준 라이브러리 함수 가 있습니다.

스크램블링 힙 블록과 같은 악용을 방해하는 몇 가지 구현 수준 기술이 있지만 로컬 버퍼의 버퍼 오버플로를 중지하지는 않으며 함수가 반환 할 주소 변경과 같은 흥미로운 작업을 수행 할 수 있습니다.

C에는 좋은 일반적인 해결책이 없습니다. 많은 라이브러리 함수에는 작성할 양을 제한하는 버전이 있습니다. 계산하기는 어색하지만 적절한 테스트가 실행되는 한 테스트에서 힙 버퍼 오버 플로우를 감지 할 수있는 소프트웨어가 있으며 스택 오버 플로우는 종종 테스트에서 충돌로 표시됩니다. 그 외에는 신중한 코딩과 코드 검토가 중요합니다.

관련된 문제는 하나의 문자로 너무 작은 버퍼에 쓰는 문제입니다. n 문자 길이의 C 문자열은 '\0'종료 문자로 인해 메모리에 n + 1 문자가 필요하다는 것을 잊어 버립니다 . 공격자가 터미네이터없이 문자열을 저장할 수있는 경우 문자열을 예상하는 모든 C 함수는 0 바이트에 도달 할 때까지 처리를 계속하여 원하는 것보다 많은 정보를 복사하거나 출력 할 수 있습니다 (또는 DOS 공격에 대해 보호 된 메모리에 충돌). ). 해결책은 인식, 관리 및 코드 검토입니다.

printf()가족 에게는 또 다른 위험이 있습니다 . 글을 쓰면 인쇄 할 때 '%'가 포함되어 char * str; ... printf(str);있으면 문제가 생길 수 str있습니다. %n형식 지시어는 허용 printf()메모리에 쓰기. 해결책은 printf("%s", str);또는 puts(str);입니다. (또한 C99를 snprintf()대신 사용하십시오 sprintf().)

특히 루프 인덱스로 부호없는 정수를 사용하면 문제가 발생할 수 있습니다. 작은 음수 값을 부호없는 값에 할당하면 큰 양수 값을 얻습니다. 그것은 N 개의 인스턴스 만 처리하는 것과 같은 것들을 제한하거나 같은 제한된 기능을하는 것을 방해 할 수 있습니다 strncpy(). 부호없는 정수를 모두 검사하십시오. unsigned short그 중 하나의 값이 클수록 큰 양수 값으로 변환되므로 피하고 싶을 수도 있습니다 int.

C에서 문자 상수는 실제로는임을 잊지 마십시오 int. 로 표현할 수 없으므로 같은 것을 쓰면 char c; while((c = getchar()) != EOF) ...쉽게 실패 할 수 있습니다 .EOFchar

내가 생각할 수있는 더 많은 특징적인 C 실수가 있지만 보안 문제가 발생할 수 있습니다.


동일한 작업을 수행 printf("%s", str)할 때 벌거 벗은 문자열 을 사용할 필요가 없습니다 puts(str).
Blrfl

@Blrfl이지만 puts줄 바꿈 문자를 추가 printf하지는 않습니다.
rightfold

또한 할 수 있지만 fputs(str, stdout)그렇지 않습니다.
Blrfl

정수 오버플로에 관해서 : 부호있는 정수를 사용하는 것은 해결책이 아닙니다. 오버플로하면 UB가 발생합니다. 유일하게 (유쾌한) 솔루션은 오버플로가 발생하지 않음을 공식적으로 증명하거나 런타임에 확인하는 것입니다 (그러나 올바르게 확인하면 확인에 넘치지 않고 까다 로움).
sleske

@DavidThornley : C11 및 C ++ 14 표준은 위험으로 인해 표준 라이브러리에서 gets () 함수를 제거했습니다.
소멸자

5

C 관련 위험 중 일부에는 버퍼 오버플로 , 문자열 공격정수 오버플로가 포함 됩니다.


1
버퍼 오버플로에 대한 C 고유의 것은 없습니다. 포인터가있는 모든 언어는이를 가질 수 있습니다. 정수 오버플로는 거의 모든 언어에 적용되며 관리 코드에서도 쉽게 발생할 수 있습니다.
Steve

1
@Steve, 그 문제를 일으키는 포인터가 아니라 언어가 배열 범위를 강제하지 않는 방법.
Doug T.

2
@Steve는 C에만 관련된 것이 아니라 C 프로그래머가 알아야 할 것에 대해 질문했습니다.
AttackingHobo

1
@Steve : C는 버퍼 오버 플로우에 비정상적으로 영향을받습니다. 부분적으로 범위 검사에 대한 지원이 부족하고 버퍼 오버플로를 행복하게하는 라이브러리 함수의 수 때문입니다.
David Thornley

나는 특히 C에 관해 묻는 질문을 이해하지만, 이러한 위험이 더 일반적이라는 문맥에서 답을 읽는 경우 명확히 할 가치가 있다고 생각합니다. 특히 관리 코드 개발자 (IMHO)는 보안에 대해 너무 만족스럽고 특히 정수 오버플로는 대부분의 언어에 영향을줍니다.
Steve

4

다음은 수정하는 데 몇 시간이 걸리는 문제를 일으킬 수있는 위험을 놓치기 쉬운 것입니다.

문제없이 컴파일되는 다음 코드를 고려하십시오.

if(lpstr_current_state = CONST_EMERGENCY_STATE_HOLY_CRAP)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

당신이 확인되면 경우 lpstr_current_stateCONST_EMERGENCY_STATE_HOLY_CRAP당신이 실제로 할당하고 있습니다. 상수 변수는 항상 왼쪽에 두는 것이 좋습니다. 상수를 왼쪽에 놓으면 변수에 값을 할당 할 수 없으므로 컴파일러가 실패합니다.

if(CONST_EMERGENCY_STATE_HOLY_CRAP = lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

그런 다음 코드를 수정하여 읽는 동안 "신성한 쓰레기, 나쁜 일이 있었을 것"이라고 쉽게 말할 수 있습니다.

if(CONST_EMERGENCY_STATE_HOLY_CRAP == lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

7
컴파일러는 다른 문제와 달리 경고로 경고하고 플래그를 지정하기 쉽습니다. 불행히도 모든 컴파일러가 쉽게 할 수있는 것은 아닙니다.
David Thornley

2
즉, C가 아닌 다른 언어로 어떻게 언어 사용이 가능 =하고 ==.
FrustratedWithFormsDesigner

3
이것은 또한 실제로 보안 취약점이 아니며 버그입니다.
Chris Pitman

1
이것을 요다 조건이라고합니다.

2
@Kristofer Hoch : 우리가 C 버그를 위험이라고 부르고 여기에서 고려한다면 훨씬 더 큰 포럼이 필요합니다.
David Thornley

0

보안 위험 은 가지뿐입니다 . 소프트웨어의 취약점을 포착하고 자신의 이익을 위해이를 악용하기 위해 최선을 다할 사람이 외부에 있다는 사실입니다. 그 밖의 모든 것이 거기에서 따릅니다.

따라서 "올바른 생각을 가진 사람은 ..."이라고 생각할 때 즉시 다른 사람의 컴퓨터를 해킹하려는 사람이 정확히 그렇게 할 수 있다는 점을 제외하고는 즉시 생각해야합니다.

가장 큰 결과는 외부에서 전달 된 데이터를 처리하는 등 외부 이벤트에 반응 할 때마다이 데이터가 최악의 적을 통제하고 있다고 가정해야한다는 것입니다.


단락 2와 3에 동의하지만 공격자에게 모든 책임을 두는 것은 내 눈에 약간 두껍습니다. 성공적인 공격에는 항상 두 가지가 필요합니다. 망치는 프로그래머와 그 행위에서 프로그래머를 잡는 공격자. 그러나 공격자가 악용 하기 전에 보안 취약점이 존재 합니다. 그리고이를 위해 프로그래머는 책임을 져야한다.
cmaster-monica reinstate 모니카
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.