
익스플로잇
익스플로잇을 작성할 때, 원래 WebRTC 소스를 변경하고 다시 컴파일하여 대상 장치로 전송되는 SCTP 패킷을 변경했습니다. 하지만 이 방법은 폐쇄형 소스 애플리케이션을 공격하는 데 실용적이지 않았기 때문에, 결국 Frida를 사용하여 공격 장치의 바이너리를 후킹하는 방식으로 전환했습니다. Frida의 후킹 기능은 특정 네이티브 함수 호출 전후에 코드를 실행할 수 있게 해 주며, 이를 통해 익스플로잇이 발신 SCTP 패킷을 변경하고 수신 패킷을 검사할 수 있었습니다. 기능적으로는 공격 클라이언트의 소스를 변경하는 것과 동일하지만, 변경 사항이 컴파일 시점에 소스에 적용되는 대신 Frida에 의해 런타임에 동적으로 적용됩니다. 익스플로잇의 소스 코드는 여기에서 확인할 수 있습니다.
공격 장치가 후킹해야 하는 일곱 가지 함수는 다음과 같습니다.
usrsctp_conninput // 수신 SCTP 처리 DtlsTransport::SendPacket // 발신 SCTP 전송 cricket::SctpTransport::SctpTransport // SCTP 전송 준비 감지 calculate_crc32c // SCTP 패킷 체크섬 계산 sctp_hmac // HMAC 수행하여 비밀 키 추측 sctp_hmac_m // SCTP 패킷 서명 SrtpTransport::ProtectRtp // RTP 억제하여 힙 노이즈 감소
이 함수들은 심볼 또는 바이너리의 오프셋으로 후킹할 수 있습니다.
또한 익스플로잇이 작동하려면 대상 장치 바이너리에서 세 가지 주소 오프셋이 필요합니다. 이 중 두 가지는 system 함수와 malloc 함수 간의 오프셋, 그리고 이전 글에서 설명한 가젯과 malloc 함수 간의 오프셋입니다. 이 오프셋들은 Android 시스템 라이브러리인 libc에 있으므로 대상 장치의 Android 버전에 따라 결정해야 합니다. 또한 cricket::SctpTransport vtable 위치에서 전역 오프셋 테이블의 malloc 위치까지의 오프셋도 필요합니다. 이는 공격 대상 애플리케이션에 WebRTC가 포함된 바이너리에서 결정해야 합니다.
제공된 익스플로잇 스크립트에는 심각한 제한 사항이 있습니다. 메모리를 읽을 때마다 포인터의 31번 비트가 설정된 경우에만 작동한다는 점입니다. 그 이유는 2부에서 설명합니다. 익스플로잇 스크립트에는 FWD_TSN 청크를 사용하여 이 문제를 해결하고 임의의 포인터를 읽는 방법의 예시가 포함되어 있지만, 모든 읽기에 적용되지는 않습니다. 테스트 목적으로 WebRTC 라이브러리가 유리한 위치에 매핑될 때까지 장치를 재설정했습니다.
Android 애플리케이션
인기 있는 Android 애플리케이션 중 WebRTC를 통합한 애플리케이션 목록은 Google Play에서 APK 파일을 검색하여 usrsctp의 특정 문자열을 기준으로 확인했습니다. 약 5백만 명 이상의 사용자를 가진 약 200개의 애플리케이션이 WebRTC를 사용하는 것으로 나타났습니다. 이 애플리케이션들을 평가하여 익스플로잇의 취약점에 영향을 받을 가능성과 그 영향을 확인했습니다.
애플리케이션들이 WebRTC를 사용하는 방식은 매우 다양했지만, 네 가지 주요 범주로 나눌 수 있습니다.
프로젝션: 사용자 동의 하에 모바일 애플리케이션의 화면과 컨트롤을 데스크톱 브라우저에 투사하여 사용성을 향상시킵니다. 스트리밍: 오디오 및 비디오 콘텐츠가 한 사용자에서 여러 사용자에게 전송됩니다. 일반적으로 중개 서버가 있어 발신자가 수천 개의 피어를 관리할 필요가 없으며, 콘텐츠는 나중에 시청하기 위해 녹음됩니다. 브라우저: 모든 주요 브라우저는 JavaScript WebRTC API를 구현하기 위해 WebRTC를 포함합니다. 화상 회의: 두 명 이상의 사용자가 실시간으로 오디오 또는 비디오를 통해 통신합니다.
익스플로잇에 사용된 취약점의 영향은 각 범주마다 다릅니다. 프로젝션은 위험이 낮습니다. WebRTC 연결을 설정하는 데 많은 사용자 상호 작용이 필요하며, 사용자가 처음부터 연결의 양쪽에 모두 접근할 수 있기 때문에 상대방을 손상시킬 이점이 거의 없기 때문입니다.
스트리밍도 비교적 위험이 낮습니다. 일부 애플리케이션이 시청자 수가 적을 때 피어 투 피어 연결을 사용할 수 있지만, 일반적으로 발신 피어의 WebRTC 연결을 종료하고 수신 피어와 새 연결을 시작하는 중개 서버를 사용합니다. 이는 공격자가 일반적으로 직접 대상 피어에게 잘못된 형식의 패킷을 보낼 수 없음을 의미합니다. 피어 투 피어로 스트리밍이 수행되는 설정에서도 대상이 스트림을 보기 위한 사용자 상호 작용이 필요하며, 스트림에 접근할 수 있는 사용자를 제한할 방법이 없는 경우가 많습니다. 따라서 WebRTC를 사용하는 스트리밍 애플리케이션은 표적 공격에 유용하지 않을 가능성이 높습니다. 물론 이러한 취약점이 스트리밍 서비스에 사용되는 서버에 영향을 미칠 가능성도 있지만, 이 연구에서는 조사되지 않았습니다.
브라우저는 거의 확실히 WebRTC의 대부분의 버그에 취약합니다. 브라우저는 WebRTC를 구성하는 방법에 대해 많은 제어를 허용하기 때문입니다. 브라우저에서 이러한 버그를 악용하려면 공격자는 피어 투 피어 연결에서 다른 피어 역할을 하는 호스트를 설정하고, 대상이 해당 호스트에 대한 통화를 시작하는 웹페이지를 방문하도록 유도해야 합니다. 이 경우 취약점은 JavaScript의 다른 메모리 손상 취약점과 유사한 영향을 미칩니다.
화상 회의는 WebRTC 사용 중 가장 위험도가 높지만, 취약점의 실제 영향은 애플리케이션 사용자들이 서로 연락하는 방식에 크게 좌우됩니다. 가장 위험한 설계는 식별자를 기반으로 모든 사용자가 다른 사용자에게 연락할 수 있는 애플리케이션입니다. 일부 애플리케이션은 수신자가 발신자와 특정 방식으로 상호 작용한 경우에만 통화를 걸 수 있도록 하여 사용자가 대상에게 연락하기 어렵게 만들고 일반적으로 위험을 줄입니다. 일부 애플리케이션은 통화를 시작하기 위해 사용자가 코드를 입력하거나 링크를 방문하도록 요구하여 비슷한 효과를 냅니다. 또한 특정 사용자에게 전화를 걸기 어렵거나 불가능한 대규모 애플리케이션 그룹이 있습니다. 예를 들어 채팅 룰렛 애플리케이션이나 사용자가 고객 지원팀에 통화를 시작할 수 있는 기능이 있는 애플리케이션 등이 있습니다.
본 연구에서는 사용자가 특정 다른 사용자에게 연락할 수 있는 화상 회의 애플리케이션에 초점을 맞췄습니다. 이렇게 하여 200개의 애플리케이션 목록을 14개로 줄였으며, 그 목록은 다음과 같습니다.