source

오래된 C 컴파일러를 사용하는 것은 보안상의 위험입니까?

factcode 2022. 8. 13. 12:08
반응형

오래된 C 컴파일러를 사용하는 것은 보안상의 위험입니까?

아무도 신경 쓰지 않는 제조 시스템이 있으며, 이 기계들은 GCC 3이나 GCC 2와 같은 오래된 버전의 GCC를 실행하고 있습니다.

그리고 나는 경영진을 설득할 수 없다: 그들은 "고장나지 않았다면 고치지 말라"고 말한다.

매우 오래된 코드 베이스(80년대에 작성)를 유지하고 있기 때문에, 이 C89 코드는 이러한 컴파일러로 올바르게 컴파일 됩니다.

하지만 나는 이 오래된 물건들을 사용하는 것이 좋은 생각인지 모르겠어.

질문입니다.

오래된 C 컴파일러를 사용하면 컴파일된 프로그램의 보안이 손상될 수 있습니까?

갱신:

같은 코드가 Windows 타겟용으로 Visual Studio 2008에 의해 구축되어 MSVC는 아직 C99 또는 C11을 지원하지 않습니다(새로운 MSVC가 지원하는지 여부는 알 수 없습니다).또한 Linux 박스에 최신 GCC를 사용하여 구축할 수 있습니다.따라서 새로운 GCC를 도입하면 이전과 마찬가지로 잘 구축될 것입니다.

사실 나는 그 반대일 것이다.

동작은 C 표준으로 정의되어 있지 않지만 특정 플랫폼 상의 "덤 컴파일러"에서 어떤 일이 일어날지는 분명한 경우가 많이 있습니다.예를 들어, 서명된 정수가 오버플로우하도록 허용하거나 두 가지 다른 유형의 변수를 통해 동일한 메모리에 액세스합니다.

최근 버전의 gcc(및 clang)는 이러한 경우를 "정의되지 않은 행동" 조건에서 이진법이 어떻게 동작하는지에 관계없이 최적화 기회로 취급하기 시작했다.코드베이스가 C를 "휴대용 어셈블러"로 취급하는 사람들에 의해 작성되었다면 이는 매우 좋지 않습니다.시간이 지남에 따라 옵티마이저는 이러한 최적화를 수행할 때 점점 더 큰 코드 덩어리를 검토하기 시작했고, 결국 바이너리가 "멍청한 컴파일러에 의해 구축된 바이너리"가 아닌 다른 작업을 하게 될 가능성이 높아졌습니다.

"기존" 동작을 복원하는 컴파일러 스위치가 있습니다만(위에서 설명한2개의 경우 -fwrapv 및 -fno-strict-aliasing) 먼저 알아야 합니다.

원칙적으로 컴파일러 버그가 준거 코드를 보안상의 구멍으로 만들 수 있지만, 전체적인 계획에서는 이 위험을 무시할 수 있다고 생각합니다.

악의적인 개발자가 컴파일러 버그를 통해 백도어를 몰래 침입할 수 있는 보안 위험이 있습니다.사용하고 있는 컴파일러의 기존의 버그의 양에 따라서는, 백도어가 다소 눈에 띄지 않는 경우가 있습니다(어느 경우든, 소스 레벨에서는 코드가 올바른 것이 포인트입니다).이러한 상황에서는 백도어가 존재하지 않기 때문에 버그가 없는 컴파일러를 사용한 소스 코드 확인 및 테스트에서는 백도어를 찾을 수 없습니다).추가 거부 포인트에 대해서는 악의적인 개발자가 이전에 알려지지 않은 컴파일러 버그를 스스로 찾을 수도 있습니다.다시 말씀드리지만, 위장 기능의 품질은 발견된 컴파일러 버그의 선택에 따라 달라집니다.

이 공격은 이 기사의 sudo 프로그램에 설명되어 있습니다.bcrypt는 Javascript 미니어에 대한 훌륭한 후속 조치를 작성했습니다.

이와는 별개로 C 컴파일러의 진화는 정의되지 않은 동작을 더욱 적극적으로 이용하는 것이었기 때문에 성실하게 작성된 오래된 C코드는 그 때부터 C 컴파일러로 컴파일되거나 -O0으로 컴파일되는 것이 보다 안전합니다(단, 새로운 프로그램 브레이크 UB 활용 최적화가 도입되었습니다).-O0)에서도 컴파일러의 수를 늘릴 수 있습니다.

두 행동 모두 위험이 있다.


오래된 컴파일러는 성숙도가 높기 때문에 문제가 있는 컴파일러는 정상적으로 해결되었을 가능성이 있습니다(단, 보증은 없습니다).

이 경우 새로운 컴파일러는 새로운 버그의 잠재적인 원천입니다.


한편, 새로운 컴파일러에는 다음과 같은 추가 툴이 포함되어 있습니다.

  • GCC와 Clang은 현재 다양한 종류의 정의되지 않은 동작을 검출하기 위해 런타임에 계측할 수 있는 세정제를 갖추고 있다(Google 컴파일러 팀의 Chandler Karuth는 작년에 그들이 완전한 커버리지에 도달하기를 기대한다고 주장했다).
  • 적어도 기능 강화에는 제어 흐름의 하이잭을 검출하는 제어 흐름 무결성, 스택스매싱 공격으로부터 보호하는 강화 기능(스택의 제어 흐름 부분을 데이터 부분으로부터 분리하는 것)이 있습니다.강화 기능은 일반적으로 오버헤드가 낮습니다(CPU 오버헤드 1% 미만).
  • Clang/LLVM은 (아직 조사되지 않은 실행 경로를 선택하도록 입력을 조정하여) 테스트 대상 함수의 입력 공간을 스마트하게 탐색하는 도구인 libFuzzer도 만들고 있습니다.

sanitizer(Address Sanitizer, Memory Sanitizer 또는 Undefined Behavior Sanitizer)를 사용하여 바이너리를 인스톨 한 후 퍼지(American Fuzzy Lop 등)하면, 다수의 하이 프로파일소프트웨어의 취약성이 밝혀졌습니다.예를 들면, 이 LWN.net 기사를 참조해 주세요.

컴파일러를 업그레이드하지 않으면 이러한 새로운 도구와 미래의 모든 도구에 액세스할 수 없습니다.

파워가 부족한 컴파일러를 계속 사용하는 것은 위험을 무릅쓰고 취약성이 발견되지 않도록 기도하는 것입니다.귀사의 제품이 고부가가치 대상이라면 재고해 주시기를 권합니다.


주의: 프로덕션 컴파일러를 업그레이드하지 않더라도 새로운 컴파일러를 사용하여 취약성을 체크하는 것이 좋습니다.단, 이들 컴파일러는 다른 컴파일러이기 때문에 보증은 적어집니다.

아니.

이유는 간단합니다. 오래된 컴파일러에는 오래된 버그와 악용사항이 있을 수 있지만 새로운 컴파일러에는 새로운 버그와 악용사항이 있을 수 있습니다.

새로운 컴파일러로 업그레이드하여 버그를 수정하는 것은 아닙니다.오래된 버그와 취약성을 새로운 버그와 악용으로 전환합니다.

컴파일된 코드에는 악용될 수 있는 버그가 포함되어 있습니다.이 버그는 다음 3가지 원인에서 발생합니다.소스코드의 버그, 컴파일러와 라이브러리의 버그, 그리고 컴파일러가 버그로 바뀌는 소스코드의 정의되지 않은 동작(미정의 동작은 버그이지만 컴파일된 코드의 버그는 아직 아닙니다.예를 들어, i = i++입니다. C 또는 C++에서는 버그가 발생하지만 컴파일된 코드에서는 i가 1 증가하여 OK가 되거나 i를 정크되어 버그가 될 수 있습니다.)

컴파일된 코드의 버그 발생률은 테스트 및 고객님의 버그 보고에 의한 버그 수정으로 인해 낮은 것으로 생각됩니다.따라서 처음에는 많은 버그가 있었지만 지금은 감소했습니다.

새로운 컴파일러로 업그레이드하면 컴파일러 버그로 인해 발생한 버그가 손실될 수 있습니다.그러나 이러한 버그는 모두 아무도 발견하지 못하고 악용하지 않는 버그입니다.그러나 새로운 컴파일러는 그 자체로 버그가 있을 수 있으며, 중요한 것은 새로운 컴파일러는 정의되지 않은 동작을 컴파일된 코드의 버그로 바꾸는 경향이 강하다는 것입니다.

So you will have a whole lot of new bugs in your compiled code; all bugs that hackers could find and exploit. And unless you do a whole lot of testing, and leave your code with customers to find bugs for a long time, it will be less secure.

If it aint broke, don't fix it

Your boss sounds right in saying this, however, the more important factor, is safeguarding of inputs, outputs, buffer overflows. Lack of those is invariably the weakest link in the chain from that standpoint regardless of the compiler used.

However, if the code base is ancient, and work was put in place to mitigate the weaknesses of the K&R C used, such as lacking of type safety, insecure fgets, etc, weigh up the question "Would upgrading the compiler to more modern C99/C11 standards break everything?"

Provided, that there's a clear path to migrate to the newer C standards, which could induce side effects, might be best to attempt a fork of the old codebase, assess it and put in extra type checks, sanity checks, and determine if upgrading to the newer compiler has any effect on input/output datasets.

Then you can show it to your boss, "Here's the updated code base, refactored, more in line with industry accepted C99/C11 standards...".

That's the gamble that would have to be weighed up on, very carefully, resistence to change might show there in that environment and may refuse to touch the newer stuff.

EDIT

Just sat back for a few minutes, realized this much, K&R generated code could be running on a 16bit platform, chances are, upgrading to more modern compiler could actually break the code base, am thinking in terms of architecture, 32bit code would be generated, this could have funny side effects on the structures used for input/output datasets, that is another huge factor to weigh up carefully.

Also, since OP has mentioned using Visual Studio 2008 to build the codebase, using gcc could induce bringing into the environment either MinGW or Cygwin, that could have an impact change on the environment, unless, the target is for Linux, then it would be worth a shot, may have to include additional switches to the compiler to minimize noise on old K&R code base, the other important thing is to carry out a lot of testing to ensure no functionality is broken, may turn out to be a painful exercise.

Can using an old C compiler compromise the security of the compiled program?

Of course it can, if the old compiler contains known bugs that you know would affect your program.

The question is, does it? To know for sure, you would have to read the whole change log from your version to present date and check every single bug fixed over the years.

If you find no evidence of compiler bugs that would affect your program, updating GCC just for the sake of it seems a bit paranoid. You would have to keep in mind that newer versions might contain new bugs, that are not yet discovered. Lots of changes were made recently with GCC 5 and C11 support.

That being said, code written in the 80s is most likely already filled to the brim with security holes and reliance on poorly-defined behavior, no matter the compiler. We're talking of pre-standard C here.

Older compilers may not have protection against known hacking attacks. Stack smashing protection, for example, was not introduced until GCC 4.1. So yeah, code compiled with older compilers may be vulnerable in ways that newer compilers protect against.

Another aspect to worry about is the development of new code.

Older compilers may have different behavior for some language features than what is standardized and expected by the programmer. This mismatch can slow development and introduce subtle bugs that can be exploited.

Older compilers offer fewer features (including language features!) and don't optimize as well. Programmers will hack their way around these deficiencies — e.g. by reimplementing missing features, or writing clever code that is obscure but runs faster — creating new opportunities for the creation of subtle bugs.

Well there is a higher probability that any bugs in the old compiler are well known and documented as opposed to using a new compiler so actions can be taken to avoid those bugs by coding around them. So in a way that is not enough as argument for upgrading. We have the same discussions where I work, we use GCC 4.6.1 on a code base for embedded software and there is a great reluctance (among management) to upgrade to the latest compiler because of fear for new, undocumented bugs.

Your question falls into two parts:

  • Explicit: “Is there a greater risk in using the older compiler” (more or less as in your title)
  • Implicit: “How can I persuade management to upgrade”

Perhaps you can answer both by finding an exploitable flaw in your existing code base and showing that a newer compiler would have detected it. Of course your management may say “you found that with the old compiler”, but you can point out that it cost considerable effort. Or you run it through the new compiler to find the vulnerability, then exploit it, if your are able/allowed to compile the code with the new compiler. You may want help from a friendly hacker, but that depends on trusting them and being able/allowed to show them the code (and use the new compiler).

But if your system is not exposed to hackers, you should perhaps be more interested in whether a compiler upgrade would increase your effectiveness: MSVS 2013 Code Analysis quite often finds potential bugs much sooner than MSVS 2010, and it more or less supports C99/C11 – not sure if it does officially, but declarations can follow statements and you can declare variables in for-loops.

ReferenceURL : https://stackoverflow.com/questions/37479403/is-using-an-outdated-c-compiler-a-security-risk

반응형