관리 메뉴

Dork's port

Wavve(웨이브) MPEG-DASH 프로토콜 분석 및 DRM 다운로드 분석 -2 본문

DRM

Wavve(웨이브) MPEG-DASH 프로토콜 분석 및 DRM 다운로드 분석 -2

Dork94 2022. 1. 24. 14:55

2022.01.24 - [DRM] - Wavve(웨이브) MPEG-DASH 프로토콜 분석 및 DRM 다운로드 분석 -1

 

1 에서는 video재생에 필요한 사전 준비 과정 (mpd 파일 요청 -> mpd 파일 분석 -> pssh 분석)까지 알아보았다.

 

mpd 요청 이후의 network activities

이번엔 실제로 wavve에서는 어떻게 video를 요청하고 재생하는 지 알아보자.  위의 네트워크 프로토콜을 보면 mpd 파일 요청 이후 init.mp4, media_*.m4s, licenseManager.do와 같은 주소로 요청을 보내는 것을 알 수 있다. 

그럼 init.mp4와 media_*.m4s는 무엇이고 어디에서 이 주소들이 온것일까? 바로 mpd 파일에서 이 주소들의 정보를 얻을 수 있다.

<!-- chunklist5000.mpd -->

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" mediaPresentationDuration="PT3480.9S" minBufferTime="PT2.0S">
  <Period duration="PT3480.9S" start="PT0.0S">
    <AdaptationSet mimeType="video/mp4" segmentAlignment="true" startWithSAP="1" subsegmentAlignment="true" subsegmentStartsWithSAP="1" contentType="video">
      <SegmentTemplate timescale="90000" media="$RepresentationID$/0/media_$Number$.m4s" startNumber="1" initialization="$RepresentationID$/0/init.mp4">

      ...

      </SegmentTemplate>
      <Representation id="5000/video" codecs="avc1.4D4028" width="1920" height="1080" frameRate="29.97" sar="1:1" bandwidth="5000000"/>
      <Representation id="2000/video" codecs="avc1.4D401F" width="1280" height="720" frameRate="29.97" sar="1:1" bandwidth="2000000"/>
      <Representation id="1000/video" codecs="avc1.4D401F" width="854" height="480" frameRate="29.97" sar="1:1" bandwidth="1000000"/>
      <Representation id="500/video" codecs="avc1.4D401E" width="640" height="360" frameRate="29.97" sar="1:1" bandwidth="500000"/>
      <Representation id="250/video" codecs="avc1.4D4015" width="480" height="270" frameRate="29.97" sar="1:1" bandwidth="200000"/>
      <Representation id="150/video" codecs="avc1.4D4015" width="480" height="270" frameRate="29.97" sar="1:1" bandwidth="100000"/>
    </AdaptationSet>
    <AdaptationSet mimeType="audio/mp4" segmentAlignment="true" startWithSAP="1" subsegmentAlignment="true" subsegmentStartsWithSAP="1" contentType="audio">
      <SegmentTemplate timescale="90000" media="$RepresentationID$/und/mp4a/media_$Number$.m4s" startNumber="1" initialization="$RepresentationID$/und/mp4a/init.mp4">
      	
      	...
        
      </SegmentTemplate>
      <Representation id="5000/audio" codecs="mp4a.40.2" audioSamplingRate="48000" bandwidth="192000">
        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
      </Representation>
      <Representation id="500/audio" codecs="mp4a.40.2" audioSamplingRate="48000" bandwidth="128000">
        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
      </Representation>
      <Representation id="250/audio" codecs="mp4a.40.2" audioSamplingRate="48000" bandwidth="64000">
        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

위의 mpd 파일에서 SegmentTemplate을 보면 media 필드와 initalization 필드에 우리가 요청한 주소와 비슷한 형식의 string을 존재하는 것을 알 수 있다. 

이 두 과정만 놓고 보았을때, 위의 mpd파일에서 bandwidth와 비디오의 재생 시간(duration)에 따라 주소를 알맞게 변환해서 요청을 한다고 가정할 수 있다. 그렇다면 init.mp4은 무엇이고 왜 필요할까?

그 답은 init.mp4는 각 재생 파일(m4s)의 헤더에 해당하는 부분으로, 처음에 한번 요청한 이후로 비디오를 스트리밍하는데 계속 사용한다. 

예를 들어, 400번째 영상파일을 요청하는경우 초기에 받아온 init.mp4 파일의 정보와 media_400.m4s을 요청하여 해당 데이터를 합쳐 재생하게된다. (init.mp4 + media_400.m4s) + (init.mp4 + media_401.m4s) + ... 

468번째 비디오 파일 여기서 DRM이 적용되어있기 때문에 실제로는 암호화된 데이터이다.

그럼  licenseManager.do는 무엇일까? 이 주소는 DRM을 복호화하는데에 필요한 키를 얻는 주소로 파라미터로는 pssh에서 얻은 KID와 여러 정보 (CDM 정보 등)이 파라미터로 전달되어 키를 얻게 된다. 이 정보는 모두 암호화 되어 전달된다. 

wavve의 DRM 키를 얻는데 사용되는 주소와 요청

 

licenseManager에 대한 응답, 역시 암호화되어 육안으로 보기엔 키를 얻을 수 없다.

자, 정리해보면 웨이브는 다음과 같은 프로세스를 통해 동영상을 재생한다.

content id와 사용자 정보를 통해 mpd 파일 요청 -> mpd 파일에 있는 정보로 비디오의 정보 요청, DRM 복호화에 필요한 key 요청 ->  decrpytDRM(init.mp4 + media_*.mp4) -> 재생

일반적인 콘텐츠의 경우 암호화 되어있지 않기 때문에 mpd파일을 분석하고 데이터를 요청해서 데이터를 합치는 것 만으로도 온전한 mp4파일을 만들 수 있다(e.g., wavve original과 HBO시리즈를 제외한 일반 드라마, 예능).

하지만, 우리의 목표는 DRM을 복호화 해서 재생 가능한 동영상을 다운 받는것이 목표이며, 이를 위해서는 DRM의 암호화에 사용된 키를 얻어야 한다. 이 방법은 wavve 패치가 되면 공개하도록 하겠다.

그래서 이 과정을 직접 테스트 하기 위해 프로그램을 간단하게 만들어보고 동영상이 잘 재생되는지 한번 테스트해보자.

시연 영상에서는 timeline의 468 ~ 478번째 영상을 다운로드 하였으며, 하나의 파일로 합치지 않아 끊기는 것 처럼 보일 수 있다.

하지만, 이는 ffmpeg등을 이용해 하나의 영상으로 합칠 수 있으며, 처음부터 끝까지 영상을 아래와 같이 다운로드 하여 합치면 DRM이 해제된 영상을 다운 받을 수 있다! 

 

프로그램을 통한 웨이브의 DRM 영상 다운로드
 

Wavve(웨이브) MPEG-DASH 프로토콜 분석 및 DRM 다운로드 분석 -1

오랜만에 무언갈 분석한 포스팅을 쓰려합니다! 오랜만인 이유는 취업준비로 바빴고, 취약점 분석을 많이 했지만 하고자 하는게 서비스의 취약점이고 블로그에 포스팅하면 파급효과나 악용될

blog.dork94.com

 

이상 포스팅마치도록 하겠습니다. wavve에 해당 취약점 제보 후 패치가 완료된다면, 어떻게 키를 얻었는지 포스팅을 할 수 있도록 하겠습니다.  

아마 이 포스팅이 DRM을 다운로드 하는 목적인 분들에게는 실제로 키를 얻는 방법이 없어서 허탈하실 수도 있을 것 같습니다. 이 글의 포스팅 목적은 DRM의 동작 방식과 wavve는 DRM을 어떻게 운영하고 있는지 알아보기 위해 포스팅하였습니다.

따라서, 저와 같이 DRM을 공부하고 삽질하는 분들에게 조금이나마 도움이 되셨으면 합니다 :) 

 

 

 

9 Comments
댓글쓰기 폼