Skip to content

Latest commit

 

History

History
102 lines (81 loc) · 6.62 KB

File metadata and controls

102 lines (81 loc) · 6.62 KB

Shellshock 불완전 패치 우회 (CVE-2014-7169)

메타데이터

항목 내용
CVE ID CVE-2014-7169
영향 버전 GNU Bash (bash43-025 패치 적용 버전 포함, 4.3 이하)
CVSS v3.1 9.8 (Critical) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
공개일 2014-09-24 (CVE-2014-6271 과 거의 동시 공개)
관계 CVE-2014-6271(Shellshock)의 최초 패치(bash43-025)가 불완전해서 발생

개요

CVE-2014-7169는 Shellshock(CVE-2014-6271)의 최초 패치가 근본 문제를 완전히 막지 못해서 생긴 후속 취약점이다. 최초 패치는 "함수 정의 뒤에 이어지는 문자열을 명령으로 실행하는 것"은 막았지만, 그 뒤에 남은 문자열을 완전히 버리지는 못했다. 이 문서는 "패치를 했다고 해서 그 취약점 클래스 전체가 안전해지는 것은 아니다"를 보여주는 사례로서 가치가 있다.

사전 지식

리다이렉션 문법과 함수 정의 파싱의 상호작용

이 취약점을 이해하려면 Shellshock 자체(CVE-2014-6271 문서 참고)의 "함수 정의를 환경변수에서 가져온다"는 배경지식이 먼저 필요하다. 그 위에 추가로 알아야 할 것은 Bash의 출력 리다이렉션 문법(> 파일명, >> 파일명)이다. 셸에서 echo hi > /tmp/outhi 를 표준출력이 아니라 /tmp/out 파일에 쓰라는 뜻이다. 파서가 함수 정의를 "어디까지 다시 읽어서 처리하는가"와, 이 리다이렉션 문법이 함수 본문 안에서 어떻게 해석되는가가 맞물리면서 두 번째 구멍이 생겼다.

취약점 분석

최초 패치(bash43-025)가 남긴 틈

Shellshock 최초 패치는 "함수 정의 뒤에 명령이 이어지면 실행하지 않는다"는 경계는 세웠지만, 함수를 다시 파싱하는 과정 자체를 완전히 제거하지는 않았다. 즉 "뒤에 붙은 걸 실행하지 말라"는 규칙은 생겼어도, "함수 정의 문자열 자체를 다시 처리하는 경로"는 여전히 살아있었고, 그 경로 안에서 리다이렉션 문법이 특정 방식으로 조합되면 파일 쓰기가 가능했다.

환경변수 값 (최초 패치 적용 후에도):
  "() { function a() { :; }; }; echo VULNERABLE" 류의 변형된 페이로드

  ┌─────────────────────────────┬─────────────────────────┐
  │  함수 정의처럼 보이는 부분   │  리다이렉션이 섞인 나머지  │
  │  (패치가 "정상"으로 인정)   │  (패치가 놓친 재해석 경로) │
  └─────────────────────────────┴─────────────────────────┘
             │                              │
             ▼                              ▼
      최초 패치가 여기까지는          [불완전 패치] 특정 조합에서
      "함수 정의 종료"로 인정          파일 쓰기까지 이어짐
                                        [완전 패치] 이 경로 자체를 제거

핵심은, Shellshock의 근본 원인이 "파서가 함수 정의의 끝을 명확히 구분하지 못한다"는 클래스 전체의 문제였는데, 최초 패치는 그 클래스 안의 한 가지 구체적인 공격 형태(뒤에 명령을 붙이는 것)만 막았다는 점이다. 같은 클래스의 다른 변형(리다이렉션을 이용한 파일 쓰기)은 여전히 열려 있었다.

왜 이런 일이 반복됐는가

함수 정의를 파싱하는 코드가 "여러 단계로 나뉜 문자열 재해석"을 거치는 구조였기 때문에, 개발자가 한 가지 공격 벡터(trailing command 실행)에 대한 방어를 추가해도, 같은 파싱 경로의 다른 지점에서 여전히 공격자 통제 하의 문자열이 셸 문법으로 재해석될 여지가 남아있었다. 이는 "패치가 특정 PoC를 막았다"와 "근본 원인 클래스가 닫혔다"가 다른 이야기일 수 있다는 것을 보여준다.

수정 방법

CVE-2014-7169에 대한 패치(bash43-026 등 후속 패치)는 함수 정의를 가져오는 파싱 경로 자체를 더 근본적으로 손봐서, 함수 이름과 본문의 경계를 판단하는 방식을 바꾸고, 이후 이어지는 어떤 형태의 문자열이든(명령이든 리다이렉션이든) 별도로 재해석되지 않도록 했다. 이후에도 관련 파싱 문제(CVE-2014-7186, CVE-2014-7187 등 — 각각 별도의 파서 경계/스택 문제)가 추가로 보고되면서, 배포판들은 여러 차례의 패치를 순차적으로 반영해야 했다.

환경변수 값 (완전 패치 후):
  ┌─────────────────────────────┬─────────────────────────┐
  │  함수 정의처럼 보이는 부분   │  리다이렉션이 섞인 나머지  │
  └─────────────────────────────┴─────────────────────────┘
             │                              │
             ▼                              ▼
      함수로 등록됨                  함수 정의 형식 자체가 거부되거나
                                     별도 셸 문법으로 재해석되지 않음
                                     → 파일 쓰기/실행 모두 발생하지 않음

참고 자료

미해결/불확실 지점

  • 최초 패치(bash43-025)가 정확히 어떤 조건에서 뚫렸는지에 대한 구체적인 페이로드/코드 diff는 2차 자료 수준에서만 확인했고, bash 소스의 실제 패치 전후 diff를 직접 대조하지 못했다. 위 박스 그림의 "함수 정의처럼 보이는 부분 / 리다이렉션이 섞인 나머지" 구분은 공개 자료의 서술을 바탕으로 개념적으로 재구성한 것이다.
  • bash43-026 이후 정확히 어떤 커밋이 최종적으로 이 문제를 닫았는지는 이번에 특정하지 못했다.