일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 |
- 금리인하
- 유튜버 김재석
- 임영규
- 스페인 코로나
- 김영권
- libtins
- 양적완화
- 이지혜
- 리리남매
- 킹덤 고근희
- 최강욱
- 이상형 만들기
- 은혜의 강 교회
- 불가피
- 성남은혜의강교회
- 뭉쳐야 찬다
- 홍혜걸
- 김재석
- 성남 코로나 확진자
- 픽크루
- 폰폰테스트
- 해킹
- 제넥신
- 미국 금리인하
- 학교 개학 연기 4월
- 조희연
- 이태원 클라쓰 15회 예고
- 스콜피온킹
- 고민정
- 김영권 아내
- Today
- 38
- Total
- 427,946
Dork's port
Wavve(웨이브) MPEG-DASH 프로토콜 분석 및 DRM 다운로드 분석 -2 본문
2022.01.24 - [DRM] - Wavve(웨이브) MPEG-DASH 프로토콜 분석 및 DRM 다운로드 분석 -1
1 에서는 video재생에 필요한 사전 준비 과정 (mpd 파일 요청 -> mpd 파일 분석 -> pssh 분석)까지 알아보았다.
이번엔 실제로 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) + ...
그럼 licenseManager.do는 무엇일까? 이 주소는 DRM을 복호화하는데에 필요한 키를 얻는 주소로 파라미터로는 pssh에서 얻은 KID와 여러 정보 (CDM 정보 등)이 파라미터로 전달되어 키를 얻게 된다. 이 정보는 모두 암호화 되어 전달된다.
자, 정리해보면 웨이브는 다음과 같은 프로세스를 통해 동영상을 재생한다.
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이 해제된 영상을 다운 받을 수 있다!
Wavve(웨이브) MPEG-DASH 프로토콜 분석 및 DRM 다운로드 분석 -1
오랜만에 무언갈 분석한 포스팅을 쓰려합니다! 오랜만인 이유는 취업준비로 바빴고, 취약점 분석을 많이 했지만 하고자 하는게 서비스의 취약점이고 블로그에 포스팅하면 파급효과나 악용될
blog.dork94.com
이상 포스팅마치도록 하겠습니다. wavve에 해당 취약점 제보 후 패치가 완료된다면, 어떻게 키를 얻었는지 포스팅을 할 수 있도록 하겠습니다.
아마 이 포스팅이 DRM을 다운로드 하는 목적인 분들에게는 실제로 키를 얻는 방법이 없어서 허탈하실 수도 있을 것 같습니다. 이 글의 포스팅 목적은 DRM의 동작 방식과 wavve는 DRM을 어떻게 운영하고 있는지 알아보기 위해 포스팅하였습니다.
따라서, 저와 같이 DRM을 공부하고 삽질하는 분들에게 조금이나마 도움이 되셨으면 합니다 :)
'DRM' 카테고리의 다른 글
Wavve(웨이브) HLS 프로토콜 분석 및 None DRM 콘텐츠 핑거프린트(워터마킹) 분석 -1 (0) | 2022.01.30 |
---|---|
MPD 파일에서 segment의 개수 구하기 (How to get the number of segment) (0) | 2022.01.29 |
Wavve(웨이브) MPEG-DASH 프로토콜 분석 및 DRM 다운로드 분석 -1 (0) | 2022.01.24 |
Known PSSH System ID list (0) | 2022.01.19 |
PSSH 구조 (0) | 2022.01.19 |