들어가기에 앞서,
- 구매한 도서를 본인의 능력으로 직접 DRM을 해제한 경우는 국내법상 합법으로 알고 있습니다.
- 다른 사람이 도와주거나 대신 해제해준 경우 불법입니다.
- 구매가 아닌 대여 도서의 해제도 당연히 불법이겠죠?
이 글은 작업의 기록이지 세부 내용이나 방법은 다루지 않습니다.
솔직히 난 종이책이든 이북이든 책을 잘 읽지 않는다.
그렇지만, 우연히 지인의 이북 리더기를 보았는데 갖고 싶다는 생각이 들었다.
모델명은 물어보지 않았지만, 아마 오닉스 포크6 인 것 같은데,, 가볍고 생각보다 빠른 화면 전환...

그래서 어떤 제품이 있을까 뒤적이다가, 뜬금없이 epub drm 에 꽂혔다.
이북리더를 산들, drm 에 묶인 전자책을 전용 뷰어앱으로만 보고 싶진 않았거든.
옛날 옛적에 리디북스의 DRM 해제에 대한 방법과 코드가 공개된 적이 있었다.
블로그 글은 사이트가 날아간 것 같고, 깃헙은 남아있네 - https://github.com/disjukr/ridi-drm-remover
GitHub - disjukr/ridi-drm-remover: https://www.bpak.org/blog/2018/04/%EB%A6%AC%EB%94%94%EB%B6%81%EC%8A%A4-%EC%9E%90%EC%8B%A0%EC%
https://www.bpak.org/blog/2018/04/%EB%A6%AC%EB%94%94%EB%B6%81%EC%8A%A4-%EC%9E%90%EC%8B%A0%EC%9D%B4-%EC%86%8C%EC%9C%A0%ED%95%9C-%EC%B1%85-drm-%ED%95%B4%EC%A0%9C%ED%95%98%EA%B8%B0-feat-%EC%9C%84%ED%9...
github.com
저분은 무슨 깡으로 저런걸 공개했는지 모르겠지만,, 나도 당시에 코드를 받아 한권 정도 재미로 풀어봤었다.
이게 생각이 나서, 나도 DRM을 풀어서 소장해야겠다.. 라는 이상한 의식의 흐름이랄까.
그래서 시작된, 이북리더 구매도 전에 EPUB DRM 부터 해제하기!
플랫폼마다 난이도는 천차만별일거라,, 일단은 EPUB 의 DRM 대해 공부해볼겸 만만하게 공공도서관의 전자책 대여 시스템을 타겟으로 삼았다. 물론 대여한 도서의 DRM 제거는 빼박 불법이겠지만,, DRM 기술에 대한 학습 목적으로...?
난 취미삼아 다른 서비스들 리버싱을 종종 해보는데, 그러면서 배우는게 꽤 많았던 것 같다.
그리고 미리 전자책 업체에 대한 변명을 해주자면,, 소프트웨어에서 창과 방패의 싸움에서는 절대적으로 창이 유리하다.
특히 전자책과 같이 소프트웨어와 컨텐츠가 사용자 기기로 내려받아지고, 로컬 기기에서 복호화를 해서 내용을 표시하는 경우엔 무조건 뚫릴 수 밖에 없다. (극단적으론 책 한장한장 다 사진 찍어서 만들면 그걸 어떻게 막을 것인가?)
그래서 기술 외적으로 사법의 힘을 빌려 처벌하거나, 최대한 귀찮게 만들어 효용 가치를 사라지게 하는 방법이 유효하다. OTT 서비스가 부상하면서 쉽게 VOD를 볼 수 있게 되자 웹하드나 토렌트가 상당히 죽은 것과 비슷하달까?
그러니 이렇게 뚫린다고 해서 그 기관이나 개발사를 괴롭히는 일은 없었으면 좋겠다..
가장 먼저 해볼 일은, 책을 구매하든 대출하든 전용 뷰어로 열어보는 일이다.
그래야 중간에서 컨텐츠를 훔치던가 복호화를 하던가 할 수 있으니까...
나쁜 업체, 하지만 내 입장에선 고마운 업체가 대충 만들면 중간 네트워크 패킷을 훔치는 것만으로 DRM 프리한 컨텐츠를 그대로 얻을 수 있을지도 모른다.

그러다보니, 훔쳐보지 못하게 하는 보안 기술 중에 SSL Pinning 이란 것도 있다. 이걸 적용하는 경우는 잘 없는데,, 좀 의외...
물론 창이 유리하다고 했지? 이런 것도 우회할 수 있다.
그래도 환경에 따라 우회가 상당히 제한되기도 하고 방법이 더 복잡해지기 때문에, 이런 조치만으로도 나같은 툴 키디의 공격으로부터 서비스를 보호할 수 있게 된다.
다른 OS에서 SSL pinning 을 우회활 방법을 만들어 뒀었기에 OS 를 바꿨는데, 다른 OS의 앱에선 pinning 이 안걸려 있어서 편하게 바로 스니핑이 가능했다.

얘들은 로그인 인증이 개판이라 이런건 좀 혼나도 될 것 같긴 한데,, 지금 중요한건 아니니 넘어가도록 하자.
주고 받는 패킷에 epub 주소가 있고, 그냥 다운받아 쓰고 있다. '어라? 그냥 저 epub 를 다운받아주기만 하면 되나?'

까비~
파일을 열어보니 신기하게 파일이 통째로 암호화된게 아니다. 뷰어에서도 책의 이름은 정상적으로 가져오더라.
EPUB 는 컨테이너로 zip 을 사용하고 있어서, 확장자만 zip 으로 바꾸면 압축파일처럼 내부 파일이 풀린다.
그 안에 책에 대한 정보나 이미지, 본문 텍스트 등이 있는 구조인데, 기본 정보 외에 폰트, 이미지, 텍스트는 모두 암호화된 상태였다.
도서를 한번 열람하면 앱 내부에 .epub 파일을 .zip 으로 저장하던데, 아쉽게도 암호화는 유지한 상태로 저장을 하고 있었다. 책을 열 때 마다 복호화하는 구조.
xml 구조인 메타 데이터 내에서 눈에 띄는 키워드로 검색해보니 EPUB 의 DRM 에 주로 사용되는 표준 암호화 방식이 있더라.


대충 정리하면 리소스는 각 aes 암호화가 되어 있으면서, 그 aes 키는 license 파일에 다른 키로 암호화된 상태로 저장되는 구조였다.
암호화 하는 다른 키는 구현하기 나름이겠지만, 내가 본 업체는 RSA 키로 암호화가 되어 있었다.
조금 특이한건, 서버에서 내려주는 epub 파일 자체는 키가 없어서 내가 복호화할 수 없는 license 파일이다. 대신 도서를 열 때 내 기기에 저장된 RSA 키 페어 인증서를 서버에 보내는데, 그 때 내 공개키로 암호화된 값을 가진 새 license 파일만 내려준다.
그러면 앱은 로컬에 저장된 epub 내의 license 파일을 서버에서 새로 내려준 파일로 덮어씌운채로 저장해둔다.
리소스 자체는 aes, 즉 대칭키로 암호화되어 있기 때문에, 라이선스 파일이 교체되지만, epub 리소스를 복호화 하기 위한 키 자체는 고정된 동일한 값이다. 어차피 한번만 복호화 키를 얻으면, 완전 복호화한채로 저장하면 되기 때문에 뭔들...
이제 남은건 2가지.
1. 뷰어 앱 혹은 기기에 저장된 개인키
2. 복호화 방식
개인키를 추출하는데 가장 오래걸렸는데,, 결국 내 기기에 설치된 뷰어 앱이 해당 개인키로 복호화를 하기 때문에, 어딘가엔 있다. 굳이 꺼낼 수 있는 방법이 마련되어 있지 않을 뿐. 어디에 있는지 모르기 때문에 찾는게 좀 귀찮다.
드물게 하드웨어에 키를 저장하고 사용하는 방식의 경우 키 추출이 불가한 경우도 있는데, 다행히 그렇진 않았다.(보통 잘 안쓴다.)
저장소 자체가 어디인지는 찾지 못한게 아쉽지만,,, 뷰어앱도 결국 복호화를 위해 비밀키를 메모리로 불러오기 때문에 그 과정에서 키를 가로채는게 가능하다.
내가 분석한 앱은 앱 자체는 하는 작업이 거의 없는 가벼운 앱이었고, DRM 프레임워크가 앱 용량의 대부분을 차지하고 있었다.
멀티플랫폼 지원용인지, OpenSSL 을 프레임워크 내에 내장하고 있더라.

시간이 조금 걸렸지만, 어쨋든 비밀키 추출 성공!
난 리버싱을 잘하는건 아니라서, 비효율적인 편법을 주로 사용한다. 상당한 노가다를 동반한다고 생각하면 됨.
위에서 서버에 보내는 내 기기 인증서의 키와 페어임도 확인했다.

참고로 복호화는 키가 틀려도 일단 복호화 자체는 문제없이 된다. 결과물이 쓰레기일 뿐...
그래서 키가 올바른 키인지 검증 과정이 따로 필요한데, 라이센스 파일의 encryption.device_key.key_check 값을 비밀키로 복호화하면 license 파일의 id 와 동일한 값이 튀어나온다. 이를 통해 올바른 키인지 확인할 수 있다.
조금 특이한건, 암호화 과정에서 보통 PKCS7 패딩을 많이 쓰는데,, ISO 10126 패딩인 것 같더라?
리버싱으로 복호화를 할 땐 기껏 키를 찾고 나면 iv와 패딩을 찾는데도 꽤나 시간을 쓰기도 한다. 이번엔 다행히 쉽게 해결함.
그 후에 찾은 복호화 방식은 비교적 간단했다.
encryption.content_key.encrypted_value 를 내 개인키로 복호화하면 32바이트 키가 나오고, 이를 이용해 리소스 파일들을 각각 복호화하면 된다.
기술적으론 암호화 키를 여러개 사용할 수도 있나본데, 어차피 하나만 쓰고 있으니 그런 경우는 무시.
먼저 압축한 후 암호화된 경우도 있으나 이 정보도 xml 에 기록되어 있으니 적절히 리소스에 따라 복호화 및 압축 해제해주기...
복호화 방식을 알고 비밀키가 있으니, 나머지 과정은 자동화할 수 있다.
대여/구매한 책의 라이선스 키를 받고, 암호화된 epub 를 다운받은 뒤 복호화까지 한방에 하는 스크립트 작성이 가능하단 의미.

drm 해제가 완료되면 평범한 epub 파일이 된다. epub 포매을 지원하는 어떠한 앱(나의 경우엔 애플 도서 앱)으로도 볼 수 있다.

근데 여긴 아쉽게도 내가 읽고 싶은 책이 없네.
그냥 poc 삼아, drm 구현의 공부 삼아 대출 도서로 진행해봤다.
실제론 이북으로 구매하고 그 구매한 책을 대상으로 사용할 예정인데, 업체마다 DRM의 구현 방법은 다 제각각이기 때문에, 완전 처음부터 다시 분석해야하고 방법이 완전 다를 가능성도 있다.
운 좋으면 같은 외주사가 개발했다거나,, 사용 기술이 비슷해서 날먹할 수도 있지만....
어쨋든 시도해보기 전엔 난이도를 알 수 없는데, 부디 내가 쉬운 이북 업체를 잘 찍기를 바라보며,,,
다른 서비스의 DRM 해제는 이북리더를 진짜 사게되면 진행해봐야겠다.




