Reddit

If-statement that caused HTTP2Shell was itself undisclosed patch of vulnerability

HTTP2Shell의 가드는 과거 Brotli의 테이블 읽기 결함도 막았지만, 보안 패치였는지는 확인되지 않았다

Bugsink의 분석에 따르면 Brotli 1.0.3 이전 버전에는 초기화되지 않았거나 이전 메타블록에서 남은 전환 테이블을 읽어 범위를 벗어난 메모리를 참조할 경로가 있었습니다. 2018년 추가된 가드가 이를 막았지만, 개발자가 취약점을 알고 수정했는지와 실제 공격 가능성은 공개 자료로 확인되지 않습니다.

본문

Brotli 디코더는 블록 유형이 하나뿐인 메타블록에서 블록 전환 테이블을 만들지 않을 수 있습니다. 그런데 이전 코드에는 이 상황에서도 테이블을 읽는 경로가 있었다고 Bugsink의 분석 글은 설명합니다. 앞선 메타블록에서 여러 블록 유형을 처리했다면 테이블 메모리에는 이전 값이 남습니다. 공격자가 앞선 메타블록에 넣은 값은 그때의 문맥에서 검사되지만, 현재 메타블록에 적용할 때는 유효성이 보장되지 않아 컨텍스트 맵을 범위 밖에서 읽을 수 있습니다. 앞선 메타블록이 없으면 초기화되지 않은 메모리를 읽는 경우도 생길 수 있다고 글은 덧붙입니다.

이 읽기를 막는 조건문은 2018년 2월 26일 대형 윈도 지원 커밋에 들어갔습니다. Bugsink 글은 블록 유형 수를 줄이는 명령이 반복되면 해당 조건에 도달할 수 있다고 설명합니다. 이 점은 HTTP2Shell의 취약점 사슬과도 맞닿아 있습니다. HTTP2Shell은 출력 크기 제한이 거리 기호 수를 제한한다는 가정을 무너뜨리는 명령과, 오류를 입력 부족으로 처리하는 동작, 스트리밍 재시도 과정의 버퍼 초과 등이 맞물린 문제였습니다. 가드는 그 사슬에서 실행 흐름에 영향을 주는 요소였지만, 과거의 테이블 읽기 결함은 별도의 메모리 범위 초과 읽기 경로입니다.

Bugsink 분석에 따르면 검증되지 않은 테이블 읽기는 Brotli 1.0.3 이전의 태그된 모든 릴리스에 있었으며, 가장 이른 0.1.0도 포함합니다. 1.0.3은 2018년 3월 2일 공개됐습니다. GitHub 커밋 제목과 변경 기록은 대형 윈도 기능을 다루지만, 조건문이 보안 취약점 대응으로 추가됐다는 설명은 담고 있지 않습니다. 작성자도 개발자가 카운터 고갈을 알고 있었는지, 방어적 코딩이나 도구 경고 때문에 조건문을 넣었는지 질문으로 제시합니다.

따라서 공개 자료가 뒷받침하는 결론은 구체적입니다. 오래된 버전에 범위 밖 읽기 경로가 있었고, 조건문이 그 경로를 막았다는 분석은 제시됐습니다. 그러나 당시 개발자의 의도나 해당 경로를 실제 공격으로 연결할 수 있는지는 입증되지 않았습니다. Bugsink 글은 실용적인 악용 방법을 제시하지 않으며, 이를 원격 코드 실행 취약점으로 단정할 근거도 제공하지 않습니다.

자료: Bugsink, GitHub / 정리·해설: Trawling

참고 자료