R 3.4.4의 스택 기반 버퍼 오버플로우. x86에서는 완전한 익스플로잇이 가능하지만, x64에서는 프로그램 제약으로 인해 가젯 분석을 통한 RIP 제어만 가능합니다. 두 아키텍처에서 동일한 취약점이 서로 다른 익스플로잇 경로로 이어집니다.
R 3.4.4의 스택 기반 버퍼 오버플로입니다. x86에서는 완전한 익스플로잇이 가능하지만, x64에서는 프로그램 제약으로 인해 가젯 분석과 함께 RIP 제어만 가능합니다. 두 아키텍처에서 동일한 취약점이 존재하지만, 서로 다른 익스플로잇 경로로 이어집니다.
이 저장소는 메모리 손상 익스플로잇을 가르칠 때 사용하는 자료의 일부입니다 (정규 업무 외에도 여러 사이버 보안 과정에서 차세대 리버스 엔지니어를 양성하는 데 기여하고 있습니다).
CVE-2019-25485는 학생들이 동일한 취약점을 두 가지 다른 아키텍처에서 분석하고, 그 차이점을 직접 확인할 수 있도록 하기 위해 사용하는 사례입니다. R 3.4.4는 x86 및 x64 버전으로 제공되며, 동일한 오버플로(동일한 GUI 필드, 동일한 입력 핸들러, 동일한 크래시)가 두 버전 모두에 존재합니다. 두 경우 모두 여기에 별도의 실습으로 문서화 및 익스플로잇되어 있습니다:
R 3.4.4는 통계 컴퓨팅 애플리케이션이지, 네트워크 서비스나 브라우저가 아닙니다. 오버플로는 데스크톱 GUI 필드를 통해 트리거되므로, 공격 표면은 제가 가르치는 다른 모든 사례와 완전히 다릅니다. 이 사례가 교육에 유용한 이유:
R은 Windows, macOS, Linux에서 사용 가능한 통계 컴퓨팅 및 그래픽 환경입니다. 취약점은 GUI 환경설정(Preferences) 대화 상자, 특히 'Language for menus and messages' 필드에 있으며, 사용자 입력을 고정 크기 스택 버퍼로 길이 검증 없이 복사합니다.
주요 기술 세부 사항:
R 3.4.4는 'Language for menus and messages' 필드를 처리할 때 제공된 문자열을 길이 확인 없이 고정 크기 스택 버퍼에 복사합니다. 취약한 로직의 단순화된 버전은 다음과 같습니다:
char language_buffer[256];
strcpy(language_buffer, user_input);
충분히 긴 문자열을 보내면 복사가 버퍼 끝을 넘어 쓰여지면서, 저장된 반환 주소가 덮어쓰일 때까지 스택이 손상됩니다. 함수가 반환될 때 CPU는 스택에서 공격자가 제어하는 값을 RIP로 로드하고 해당 주소로 점프를 시도합니다.
x64에서 Windows는 점프가 발생하기 전에 정규 주소 검증을 강제합니다. 0x4141414141414141과 같은 비정규 값은 RIP가 로드되기 전에 즉시 액세스 위반을 트리거합니다. 이는 크래시가 x86과 다르게 보인다는 것을 의미합니다. RIP = 4141414141414141과 같은 깔끔한 값이 나타나지 않습니다. 오프셋은 RIP에서 직접 읽는 것이 아니라, 크래시 후 스택에서 사이클릭 패턴을 읽어 찾아야 합니다.
언어 필드에 긴 문자열을 붙여넣으면 크래시가 재현됩니다. 인증이 필요하지 않습니다. Python을 사용한 페이로드 생성 예시:
import struct
payload = b'A' * 400
with open('payload.txt', 'wb') as f:
f.write(payload)
R 3.4.4 x64 실행
편집 -> GUI 환경설정
payload.txt의 내용을 'Language for menus and messages'에 붙여넣기
확인 클릭
이 저장소의 목표는 크래시를 시연하는 것뿐만 아니라, 두 아키텍처에서 완전한 익스플로잇 과정을 안내하고, x86에서 작동하는 것과 x64에서 실패하는 것, 그리고 더 중요하게는 그 이유를 문서화하는 것입니다.
주 README를 깔끔하게 유지하기 위해 상세한 익스플로잇 노트, 스크립트 및 디버거 단계는 이 저장소의 Vulnerability 📂 폴더 안에 x86 및 x64 하위 폴더로 나누어 배치했습니다.
거기에서 두 아키텍처에 대한 전체 워크플로를 찾을 수 있습니다:
x86 - 전체 익스플로잇:
x64 - RIP 제어 및 익스플로잇 분석: