
CVE-2020-0796을 통한 버퍼 오버플로우 유발 PoC
./CVE-2020-0796.py servername
이 스크립트는 대상 호스트에 연결하고, 변환 헤더에 잘못된 오프셋 필드를 설정하여 인증 요청을 압축하며, 이로 인해 압축 해제기가 버퍼 오버플로우를 일으켜 대상이 충돌합니다.
이것은 우수한 smbprotocol을 수정한 것으로, SMB 3.1.1 압축/압축 해제(LZNT1만 해당) 지원이 추가되었습니다. 대부분의 추가 사항은 smbprotocol/connection.py에 있습니다. lznt1의 버전이 포함되어 있으며, Python 3을 지원하도록 수정되었습니다.
압축 변환 헤더는 해당 클래스 SMB2CompressionTransformHeader에 있습니다. 함수 _compress는 트리 요청을 압축하기 위해 호출됩니다. 여기서 오프셋 필드를 모두 높게 설정하여 충돌을 유발합니다.
def _compress(self, b_data, session):
header = SMB2CompressionTransformHeader()
header['original_size'] = len(b_data)
header['offset'] = 4294967295
header['data'] = smbprotocol.lznt1.compress(b_data)
CVE-2020-0796은 Windows 10 1903/1909의 새로운 SMB3 압축 기능의 버그입니다. SMB 프로토콜 버전 3.1.1은 클라이언트 또는 서버가 압축 기능을 광고하고, 유리한 대로 SMB3 메시지를 선택적으로 압축할 수 있는 기능을 도입합니다. 이를 위해 SMB 세션을 협상할 때 클라이언트와 서버는 모두 MS-SMB2 2.2.3.1.3에 문서화된 SMB2_COMPRESSION_CAPABILITIES를 포함해야 합니다.
이 기능으로 세션이 협상되면 클라이언트나 서버는 특정 SMB 메시지를 선택적으로 압축할 수 있습니다. 이를 위해 전체 SMB 패킷이 압축되고, MS-SMB2 2.2.42에 문서화된 대로 변환 헤더가 앞에 추가됩니다. 이 헤더는 매직 값, 압축되지 않은 데이터 크기, 사용된 압축 알고리즘 및 오프셋 값을 가진 작은(16바이트) 구조체입니다.
CVE-2020-0796은 여러 서브루틴에 직접 전달되는 해당 오프셋 크기에 대한 경계 검사 부족으로 인해 발생합니다. 큰 값을 전달하면 버퍼 오버플로우가 발생하고 커널이 충돌합니다. 추가 작업을 통해 이는 RCE 익스플로잇으로 발전될 수 있습니다.