64비트 마이그레이션 취약점

임정환·2023년 7월 3일
0

32비트 아키텍처에서 문제가 없는 코드가, 64비트 아키텍처에서는 문제를 발생시킬 수 있다.

Twice the Bits, Twice the Trouble:
Vulnerabilities Induced by Migrating to 64-Bit Platforms
Christian Wressnegger, Fabian Yamaguchi, Alwin Maier, and Konrad Rieck
Institute of System Securit

초록

32비트 아키텍처의 64비트 마이그레이션시, 보안취약점을 야기할 수 있다. Integer의 width가 달라질경우 overflow 문제가 발생할 수 있으며 이는 심각한 보안 취약점을 만든다.

배경지식

  • Size_t는 아키텍처의 최대 크기의 unsigned 값을 나타낸다. 즉, 64비트 아키텍처와 32비트 아키텍처의 Size_t는 다르다.
  • 64bit Integer값을 32bit로 캐스팅된 변수에 대입하게 되면, high 32비트가 잘려나가게 된다.
  • 32비트에서는 문제없는 코드가, 64비트 아키텍처에서는 취약점이 발생하는 케이스
    • 첫 번째 코드에서, -1을 대입할경우 int는 32비트이므로 len에는 0x00000000ffffffff이 대입된다.
    • 두 번째 코드, malloc에 len이 인자로 들어가면 buffer에 0x00000000ffffffff의 heap공간이 할당된다.
    • 세 번째 코드, memcpy의 세번째 인자는 size_t로 인자를 캐스팅하므로 len이 0xffffffffffffffff이 된다.
    • buffer의 공간은 0x0000000ffffffff만 할당되었으나 0xffffffffffffffff을 넣어주게 되면 heap overflow가 발생하게된다.

Architecture Data Model

각 아키텍처별 type에 따른 width.

Integer Truncations


int type은 4 byte , short type은 2 byte이다. buffer포인터에 y의 width만큼 heap 공간을 할당했지만 4 byte인 x를 대입할 경우 Int trucation으로 인한 buffer overflow가 발생할 수 있다.

Integer Signedness Issue


배경지식과 동일하다. Sign-extension으로 인해 heap buffer overflow가 발생할 수 있다.

64-BIT migration vulnerability

개발자들은 32비트로 충분한 데이터를 표현할 수 있다고 생각했다. 하지만, 기술의 발전으로 인해 64비트 아키텍처의 시대가 도래하였고 이로인해서 기존의 레거시 코드에서 integer truncation으로 인한 overflow문제가 발생할 수 있게 되었다.

Truncation의 대상이 포인터인 경우 , 다른 취약점이 발생 가능하다.

Incorrect Pointer Differences

32비트 아키텍처의 경우 width(int) == width(ptrdiff_t) 이다. 하지만, 64비트 아키텍처의 경우 width(int) < width(ptrdiff_t) 이므로 취약점이 발생할 수 있다.
위의 코드를 보면, 5행에서 integer truncation이 발생하고 있다.
예를들어 MAX_LINE_SIZE = 0x100 이고, eol - str = 0x1000000ff 이라면, len은 잘린 길이인 0x000000ff 가 된다.
32비트 아키텍처의 경우 if를 통해 흐름을 제어하지만, 64비트에서 truncation이 발생할경우 if문을 지나치게 되고 결국 buffer overflow를 일으키게된다.

Casting Pointer to integers

32비트 아키텍처의 경우 Width (int) = Width (pointer) 와 동일하다.
하지만 , 64비트 아키텍처의 경우 Width (int) < Width (pointer) 이다.
포인터에서 int로 type casting을 변환하게 된다면. Truncation 현상이 발생할 수 있다.

Effects on Larger Address Space

32비트 아키텍처를 개발하던 개발자들은, 4GB를 넘는 주소공간을 다룰 수 있을 거라고 생각하지 않았다. 64GB 아키텍처를 사용하게 되자 Truncation과 Overflow를 고려해야한다.

Dormant Integer Overflow


64비트 아키텍처로의 이행은 더 높은 데이터를 다룰 수 있는 자료형과 객체를 사용할 수 있게 해주었다.
위의 5행의 경우, len의 경우 64bit unsigned 값의 자료형이고 i의 경우 32비트 unsigned이다. 즉, i는 영원히 종료조건에 도달하지 못할 위험이 있고 buf의 overflow가 발생할 수 있다.

Dormant Signedness Issue


2행에서 strlen 함수의 반환값이 32비트 len에 대입되어 truncation된다면 if문을 넘어가서 memcpy가 실행될 수 있다. 만일, overflow로 인해 len이 음수의 값을 가지게 된다면 unsigned int로 casting이 일어나고 overflow를 야기할 수 있다.

Conclusion

32비트 아키텍처 당시의 개발자들은, 더 높은 주소공간을 사용하거나 더 많은 bit를 가진 자료형을 사용할 것이라 예상하지 못하였다. 현재 64비트 아키텍처로의 마이그레이션 이후, 수 많은 보안 취약점이 발생하였다.
특정 플랫폼에서 정상적이고 안전하게 작동하는 플랫폼에서, backward compatibility를 보장하는 상위 플랫폼으로 migration하는 것은 보안 취약점을 야기할 수 있으며 주목해야할 과제이다.

profile
CS 박제

0개의 댓글