2012.07.28 12:40 System

 

[+]... 


 

<Fig0. 죽었어..>

 

네 반년 넘도록 죽었습니다. 빠져가지고..

 

다시 살아나도록 발버둥 치고 있어요.

 

이와 비슷한 전개를 작년에 본것 같은 것은 착각일겁니다.

 

아무튼 이번에 포스팅할 글은 E-book 보안에 관한 글입니다.

 

사실 심도 있는 내용의 포스팅은 아니고 한번 쯤 그냥 훑어볼만한 주제죠.

 

인터넷에서 책을 구매하신다면 종이책이 아닌 전자책 형식으로 판매하는 곳을 보셨을 겁니다.

 

사실 종이책의 책장 넘기는 맛이라던가 소장의 가치도 정말 무시할 수 없습니다만, E-book 은 또 그 나름대로의 매력을 가지고 있죠.

 

요즘 같이 스마트 기기가 많이 보급됨에 따라 E-book 이 상당한 인기 몰이를 하고 있습니다.

 

문제는 전자 문서 형식이다 보니 배포가 될 수 있는 위험성을 가지고 있고, 이에 따라 각 업체들은 여러가지 보안 기술들을 적용하게 됩니다.

 

 

 

[+] Analysis 


 

분석에 앞서 어떤 업체들이 E-book 단말기를 사용하는지 그 단말기의 지원 포맷이 무엇인지 살펴봅시다.

 

 

<Fig1. E-book 제공 업체별 단말기 및 지원 포맷>

 

호오 ePub 포맷이 많이 보이는군요.

 

ePub 포맷은 특정 파일 및 폴더들을 담고 있는 압축 포맷입니다.

 

 

<Fig2. ePub 포맷의 파일 구조>

 

 

META-INF 에는 폴더, 파일 구조, 컨텐츠 외의 내용들이 XML 형태로 저장되어 있고

 

OEBPS 에는 컨텐츠 내용이 들어있습니다.

 

하지만 이 표준화된 포맷은 자체적으로 보안 기술이 적용되어 있지 않아 각 업체별로 DRM을 걸고 있습니다.

 

그것도 다 따로 따로요..

 

 

<Fig3. 업체별 DRM 적용 기술>

 

 

실제로 이 DRM 기술들을 분석해보면 아래와 같은 구조를 가지고 있는 것을 파악 할 수 있습니다.

 

아무래도 특정 회사의 DRM 구조를 언급하는것은 피하고자 업체 명 , 아이콘등은 지운것을 감안하고 봐주세요

 

<Fig4. 모 업체의 DRM 기술 분석>

 

 

다른 업체의 DRM 기술들도 거의 비슷한 구조를 가지고 있습니다.

 

훈훈하게도 모두 암호화는 꼬박꼬박 하고 있습니다.

 

 

<Fig5. 모 업체의 DRM 기술 분석2>

 

사실 별 다를건 없습니다만 모든 업체별로 암호화 방식, 메모리 로딩 방식이 다르다 보니 한 업체의 ePub 파일이

 

다른 업체의 뷰어로 열리지도 않고 각 전용 뷰어로만 열리는 사태가 일어납니다.

 

 

 

[+] Problem & Solution


 

문제는 국내 모든 업체들의 뷰어를 살펴보았습니다만.. 모든 업체들이 하나 같이 복호화 함수 하나를 통해 ePub 파일 통째로 혹은 한 페이지 별로 복호화를 수행해 낸다는 점이죠.

 

어떤 프로그램이든지 Crack 될 수 있는 가능성이 존재합니다만 현재 eBook 뷰어들은 너무나도 취약합니다

 

아무리 복잡한 암호화 기술을 걸어도 말짱 도루묵이라는 겁니다.

 

 

 

<Fig6. 복호화하여 추출한 이미지 파일>

 

파일 개별로 암호화를 한 업체에게는 칭찬을 해 주고는 싶다는건

 

풰이크고

 

Decrypt 함수에 후킹 걸고 저장 루틴을 씌운다음에

 

그냥 파일 한페이지씩 쭉 읽어들이면 책 한권이 무방비 상태로 뚝딱 생기는 겁니다.

 

여기서 제가 말씀드리고 싶은 점은 좀 더 꼬아놓는 기술이 필요하다는 거죠.

 

Cracker를 귀찮게 하세요.

 

단번에 복호화를 하지 말고 부분 부분 하여 그걸 또 XOR 하고 Decrypt 된 Page에 또 Decoding 작업을 하고

 

또 이미지를 한번에 출력하는게 아니라 수십 조각으로 나눠서 임의의 순서로 출력을 한다던지 하는 것이 필요하다는 겁니다.

 

뷰어에 Anti debugging 이라던가 상용 Packer 등을 적용시킨다던가 하는 작업 역시 추가되면 더 좋겠죠.

 

암호화하는 알고리즘을 백방 강화 시켜봐야 헛수고라는걸 아셔야해요. [ 물론 그렇다고 해서 Base64 뭐 이런걸로 Encoding 하는건

 

문제가 있습니다;;  적용한 암호가 뚫려버리는건 그만큼 더 문제가 있겠죠 ]

 

이 부분은 구현을 하기 나름이니

 

 

또 하나 문제는 업체 하나가 뷰어를 복잡하게 바꿔놓아도

 

다른 업체가 그대로면 유출되겠군요.

 

책을 한 도서 업체만 판매하지는 않을테니까요.

 

좀 더 표준화된 기술이 공통적으로 적용되어야 할 것 같습니다

 

 

 

 

E-book이 보급화가 된다면 추후 이 문제가 불거질 수 있겠습니다만

 

아직은 좀 조용한 모양이네요.

 

하지만 불법 스캔보다 훨씬 쉽고 모든 파일에 적용가능까지 한 이상

 

9시 뉴스 타는것도 시간문제가 아닐까요?

 

...

 

ePub 파일이 암호화 되었다고 , 자신이 사용하는 뷰어는 전용뷰어라고 안심하지 마세요.

 

그럼 반년 안에 다시 포스팅 할 수 있길 기원하며 이만 패킷을 쏩니다 ㅎㅅㅎ

 

 

 

 

 

 

 

 

Posted by LinkC

2011.12.24 13:49 System

[+]Introduction


아주 간만에 포스팅입니다.

1,2주 안하다보니 한달이 되고 두달이 되고..

 

<Fig0. 하라는 공부는 안하고!>

좀 더 심도있는 내용을 올리고 싶었는데 그게 또 핑계거리가 되서 블로그에 글을 안쓰고 있네요.

그래서 간단한 내용이라도 올리고자 합니다.

Global Hooking 을 거는 손쉬운 방법으로는 SetWindowHookEx가 있죠.

Windows 에서 자동으로 Injection을 시켜주기 떄문에 Process의 생성을 catch 해서 따로 Injection 해줄필요도 없구요.

이 부분에 관해서는 Reversecore님 Blog에 아주 자세히 설명되어있기 떄문에 참조하시길 바랍니다.

제가 이번에 쓸 내용은 SetWindowsHookEX를 이용해서 Hooking 을 걸고 UnHookWindowHookEx를 이용하여 해제했는데도 

박혀있는 DLL 을 강제로 Ejection 시키는 방법입니다.

[ 추후 UnHookWindowsHookEx를 이용하지 않고 Hooking을 해제하는 방법도 올리도록 하겠습니다 :D 

Windows7 에 올라와서 물리 메모리에 접근하는게 좀 까다로워져서 고생중이네요. Driver 없이 User 모드에서 가능한지를 살펴보고 있습니다

XP는 되는데 음.. ]



[+]Problem



UnHookWindowsEx만 호출한 경우 대부분의 Process에서는 DLL이 Ejection 되지 않습니다.

[ 물론 해제가 되는 Process도 있습니다. Process 내부에서 Message 처리를 열심히 하는 녀석들이죠.

대부분 UI 가 사용자에게 보여지고 있는 상태의 녀석들이구요. ]

보통 UnHook 후에 SendMessage 를 Broadcasting 하게 뿌려서 Process에 해제하게 되죠.

이 Message는 의미있는 Message 일 필요는 없습니다. 

Message가 오면 Hook Chain을 알아서 갱신하니까요.

아무튼 이렇게 Message 를 뿌려줘도 DLL이 빠지지 않는 Process가 존재하게 됩니다.

대표적으로 AdobeARM.exe Chrome의 Rundll32.exe가 있죠.

물론 항상 빠지지 않는건 아니고 간혹 빠지지 않는 현상을 보게 됩니다.

이런 Process들은 대부분 단일 Thread라는 점을 확인할 수 있는데요.

정리하자면

1. UnHook할 때는 Message를 뿌려서 받은 Process들은 해제가 된다.

2. UnHook 되지 않는 녀석들은 대부분 단일 Thread이다.

3. 위 Process 들도 항상 DLL이 Ejection 안되는건 아니다.

이 부분에서 문제점을 유추할 수 있습니다. 

Process에 외부에서 들어온 Message를 처리할 Thread가 없으면 DLL이 Ejection 되지 않는다.

라는 점입니다.



[+]Solution


그렇다면 위 문제는 어떻게 해결해야 할까요?

많은 분들이 FreeLibrary를 CreateRemoteThread를 이용해서 삽입하는 방법을 생각하셨을겁니다.

흠, 하지만 이 방법에는 문제점이 있는데

FreeLibrary시에 해당 DLL에 접근하고 있는 Thread가 있으면 그대로 프로그램이 뻗어버린다는 것이죠.

DLL Unload 뭐 이런 Error가 났던걸로 기억합니다.

결국 DLL이 자동으로 Ejection 되게 하려면 Message를 처리하도록 만들어야한다는거죠.

Message 처리 루틴 Thread를 Process에 삽입하고 다시 Message를 보내볼까요?

너무 번거롭습니다.

생각해보면 Process 자체에서 Ejection 해주는게 아님을 파악할 수 있습니다.

빈 Message를 받았을 때 Hook Chain에 없는 DLL을 빼주는게 Process 자체 역할을 아니니까요.

Process는 단순히 Message를 받는 것이고 이 때 발생한 특정 Event를 Windows에서 받고 Ejection 해준다고 판단 내릴 수 있겠군요.

그렇다면 직접 Message를 발생시키면 어떨까요?

Code Injection을 통해서 DLL이 빠지지 않는 Process에서 Message를 발생하도록 하는거죠.

아래 Code Inejction Code는 Reversecore님의 Code를 상당부분 인용했습니다.

http://www.reversecore.com/82 

먼저 사용할 함수를 정의합니다.




다음은 실행코드입니다.

함수 호출에 필요한 String을 먼저 삽입하고 그곳을 참조하는 방법입니다.



SendMessage를 쓰기 보다 SendMssageTimeOut을 썼고

Parameter 간소화를 위해 Broadcasting을 합니다.

위와 같은 방법을 이용하면 DLL이 정상적으로 잘 Ejection되는 것을 확인하실 수 있을겁니다.

어때요 참 쉽죠?


글이 올라온 날이 12월 24일이라는 건 신경안쓰셔도 됩니다








Posted by LinkC

2011.07.16 21:45 WarGame

[+] Introduction

 


 이번에 소개할 문제는 VM 관련 문제 입니다.

VM을 이용한 기술은 VCP [ Virtualized Code Protection ] 이 있으며 해당 기술은 Protector 에 많이 쓰이곤 합니다.

언뜻 봐도 " Code를 Virtualize 하여 Protect 한다 " 라는것을 의미한다는거라고 쉽게 추측 할 수 있죠.

상용 Packer 인 Themida에 실제로 쓰이고 있는 기술이기도 하구요.

물론 Themida에는 VCP 뿐만 아니라 여러가지 Anti Reversing 기술들이 들어가있습니다만..

 이 포스팅에서는 VM만을 다루도록 하겠습니다.

 * VM이 적용되면 Reversing 하는 입장에서는 상당히 귀찮아집니다.

뒤에서 설명하겠지만 Assembly Language 로 한줄씩 실행되기 떄문에 

전체적인 구조를 살펴보려면 Script를 짜거나 손으로 직접 모아야 하기 떄문이죠.

디버거로 열어봤는데...


<Fig 0. VM이 딱 ! >


 <Fig0-1. 5초후에 빡침이 딱!>



[+] Problem


<Fig1. Bin500을 실행 시켰을 때 >

 

먼저 Debugger로 문자열을 확인해보면

key File로 짐작되는 문자열 'codegate.key' 를 찾을 수 있습니다.

적당히 아무내용이나 집어넣어서 재실행 시켜보면

역시 유효하지 않은 파일이라고 하는군요.

<Fig2. 해당 파일이 올바르지 않을 때 메세지> 

이런 류의 문제라면 해당 Key 파일을 검사하는 부분을 우회해도 

암호가 나오지 않고 그 파일을 가지고 연산을 하기 떄문에

해당 파일의 내용을 정확히 복구를 해야 합니다.

 파일을 열어 Verify 하는 부분을 찾으려 해도 도통 보이지 않는군요.

이 문제의 핵심인 Verify 부분이 VM에 의해 실행되기 때문이죠.


[+] Analysis

 
그렇다면 Debugger로 확인을 해봅시다. 

<Fig3. VirtualAlloc을 통해 특정 메모리 영역을 할당받는 모습>

 해당 영역을 확인해보면 아시겠지만

애초에 VM 영역에서 시작하네요.

후에 VirtualAlloc 을 호출하고 특정 영역에  RWE 권한을 모두 줍니다.

계속 따라가보면 VirtualAlloc을 한번 더 호출하고 .. [ 같은 크기, 다른 위치에 RWE 권한을 줍니다 ] 

이 할당한 영역에 특정 명령어를 수행하는 것을 확인 할 수 있습니다.

<Fig4. VirtualAlloc에 할당된 영역에서 코드를 실행하고 있는 모습>
 
그 후에 다시 0x40ABBD로 Return해서 특정 루틴을 반복합니다.


<Fig5. Code를 가져와 Decrypt하는 부분>

0x0040A94A를 호출함으로써 실행할 Code를 복호화 하는데

해당 함수를 살펴보면 다음과 같습니다.


<Fig6. Fig5의 Decrypt함수 내부>

 

사실 위 함수가 문제를 푸는데 큰 도움이 되는 건 아닙니다.

CPU가 해석 할 수 있는 일반 기계어로 복호화 하는 과정이지

Key 파일의 내용을 확인하는 과정이 아니기 떄문이죠.

하지만 VM의 동작 방식은 확인을 하고 갑시다.

대략적인 VM의 구현은 다음과 같습니다.

<Fig7. VM의 동작 방식>

실제 문제 파일을 Debugging 해보면 아시겠지만

text 영역과 VM 영역이 번갈아 가며 실행되는 것을 볼 수 있습니다.

Sensitive 한 곳은 VM 처리가 되어있는거죠.



즉 우리가 원하는 것은 ' Codegate.key 파일을 입력 받고 난 후 실패 메세지가 나오기 전까지의 연산 과정 ' 입니다.

이것은 1Byte 씩 검사하여 다르면 바로 실패로 return 하는 과정일수도 있고

전체 내용을 모두 검사한 후 최종적으로 실패를 판단할 수도 있습니다.

물론 전자가 훨씬 까다로워집니다. 실행중에 비교 값을 바꿔야하니까요.

ReadFile에 BP를 걸고 해당 파일을 읽어 온 후에 Buffer에 접근 하는 부분을 잡아보면

최종 Code가 실행되는 곳을 잡을 수 있습니다.

이곳을 보면 Fig4에서 할당한 곳과는 다른 공간임을 알 수 있습니다.

즉, 복호화된 Code가 실행 되는 부분은 2군데이며 

1. 일반 적인 Code가 실행되는 부분

2. Key 파일의 내용을 검사하는 부분


이 되겠습니다.

두 부분을 모두 BP 걸고 확인해보면 아시겠지만 Call , JMP 문을 찾아 볼 수 없다는걸 알 수 있습니다.

Call이나 JMP문이 가고자 하는 곳은 VM에서는 외부 , 즉 원본 프로그램의 text 영역입니다.

이 부분으로 가려면 해당 주소에 맞는 연산이 또 별도로 필요하죠.

문제 풀이엔 별로 중요한 내용이 아닙니다만,

'VM은 이런식으로 구현되고 있다' 라는 것은 염두해두시는게 좋습니다.



[+] Solution



이 다음부턴 딱히 설명 드릴게 없습니다.

Script를 짜거나 손으로 직접 코드를 바꾸시면서 진행을 하셔야 합니다.

운이 나쁘게도 앞서 설명드린 1Byte 씩 검사하고 아닐 경우 실패로 간주하는 타입이군요.

Script로 모으기 짜증 + 1  이 되었습니다.

아무튼 해당 Code를 모으면 다음과 같은 모습입니다.

Pydbg의 HardWare BP를 이용한건데 가변길이라 그런지 

다음 명령어까지 받아오더군요.. 쩝..


<Fig8. Xor, Cmp 부분 중 일부를 긁어온 모습>

이 부분을 예로 들자면

al 로 가져온 값을 xor 0x46 하고 이 값을 cmp 합니다.

xor  [ Data  ] , 0x46

cmp ( [ Data ] ^ 0x 46 )  , 0xf0

즉 Data 의 값은 0x46 과 Xor를 했을 때 0xF0 가 나오는 0xB6 이 되겠네요.

이런 식으로 Codegate.key 값을 하나씩 복원합니다.

Codegate key 값이 총 100 Byte 니 벼..별거 아니군요.

Xor 부분과 cmp 부분을 parsing 매 Byte마다 바꿔주면

다음과 같은 원본 데이터를 얻을 수 있습니다.

<Fig9. 원본 Key File >

이를 codegate.key 에 저장하면 


<Fig10. 해독된 Key File>

이게 정답은 아니겠죠?

100Byte의 16진수가 뭘 의미 할까요.

흠 분포도를 보면 문자를 의미하는건 아닌거 같습니다.

그리고 저 출력 방식도 의심해볼만 하죠

4 * 25 형식입니다.

또, 0x80 0x00 이 유독 눈에 많이 띄는걸 볼 수 있는데..

일단 이를 binary 값으로 바꿔보았습니다.


<Fig11. Binary 값으로 바꾼 모습>



<Fig11-1. !?>
왜 4 * 25 형식으로 출력했는지 알겠네요.

0x80이 binary 값으로 1000 0000 이니까

뒤의 0을 떼버리면 25 * 25 형식의 값이 완성됩니다.

여기에 모서리 부분을 보면 1과 0이 규칙적으로 나열되어있는데

전 이걸 QR 코드라고 판단했고 이를 만들어보면..



QR Code Reader로 읽어보니

I_am_in_C0d3gat3_2011!!

이라는 답이 나오는군요.















Posted by LinkC
이전버튼 1 2 3 4 5 6 7 ··· 57 이전버튼

블로그 이미지
LinkC

태그목록

Tistory Cumulus Flash tag cloud by BLUEnLIVE requires Flash Player 9 or better.

공지사항

Yesterday57
Today61
Total309,989

달력

 « |  » 2018.05
    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    

최근에 받은 트랙백

글 보관함


. .