'안드로이드'에 해당되는 글 2건

  1. 2013.05.06 Bluebox crackme workthrough [ Codeinjection in android ] (2)
  2. 2012.12.27 Code obfuscation and JNI

2013.05.06 01:53 WarGame

[+] ... 


 


시간이 널널해지면 널널해질수록 블로그 글 작성 횟수가 줄어들고 있습니다.


문제를 푼건 1달 전 쯤인거 같은데 이제서야 키보드를 잡았네요.


이번 문제는 android platform이 대상입니다.


생각해보니 일반 pc 말고  mobile platform 을 대상으로 하는 wargame을 대상으로 글을 쓰는 건 이게 처음인 것 같네요.



[+] ? 


 

문제 파일은 아래 링크에서 받을 수 있습니다.

 

 

 

Bluebox 라는 Android 보안 회사에서 낸 문제입니다.

 

우리 보안이 자신 있으니 깨보아라 같은 경우가 아니라

 

회사 홍보 겸 샘플로 간단히 제작한 걸로 보입니다.

 

먼저 App을 받아 폰에서 실행 시켜보도록 하죠.

 

 

<Fig1. App 실행 화면 >

 


군더더기 없는 깔끔한 문제군요.

 

특정 String을 입력하면 통과하는 간단한 crackme 입니다.

 

이제 code를 뜯어보기 위해 App 압축을 풀어보..

 

는 풀리지 않습니다.  암호가 걸려있다는군요..

 

위 링크에 있는 unpack.py 를 통해 압축을 해제 하셔야 합니다.

 

<Fig2. unpack.py>

 

Mobile에 설치할 때는 아무 이상 없이 설치 되었는데 PC에서는 압축 해제가 되지 않는다?

 

상당히 흥미로운 주제입니다.

 

중요한 부분은 이 한줄이죠.

 

member.flag_bits ^= member.flag_bits%2

 

특정 flag를 제거합니다. 


Zip file의 format 을 확인해보면.. 암호화 여부를 판단하는 bit 임을 확인 할 수 있군요.


Android 의 apk manager는 password flag를 무시하고 설치를 시도하기에 이런 트릭을 걸 수 있습니다.


역으로 pack 하는 것도 매우 간단합니다.


Local file Header 와 Central directory file header 의 general purpose bit flag에 xor 1을 해주면 되죠.


어떠한 apk 파일이라도 쉽게 이런 트릭을 걸 수 있다는 점에서 꽤 유용해보이네요.

 

아무튼 이렇게 압축을 해제하고 decompile 해서 문제를 구성하는 간단한 알고리즘을 풀면 해결!

 

...

 

되면 이렇게 글을 쓸 일도 없었겠죠.

 

여러모로 트릭이 몇가지 씩 들어간 문제인데요.

 

코드를 확인해 보시면 아래와 같이 so file을 Load하는 것을 볼 수 있습니다.

 

<Fig2. MainActivity 에서 so file을 Load하는 모습>

 

JNI 를 통하여 so file의 함수를 호출합니다.

 

readmem 함수는 다시 search 함수를 호출하게 되고... 이 함수는

 

 

 

 

<Fig3. search 함수 >

 


 

findmagic 함수를 통해 memory 상에서 dex file이 올라간 시작 지점을 찾고 [ dex\x0a ]

 

Lava/lang/String 의 add Method의 위치를 찾습니다.

 

그 후 mprotect 함수를 사용하여 [ sub_F04 부분 ] 쓰기 속성을 준 뒤

 

memcpy 를 통해 inject 함수에 있는 assembly 를 복사합니다.

 

즉, So file에서 Memory에 Load된 String Class의 add method를 Code Injection 한 겁니다.

 

정확히 말하자면 덮어 씌운 거지요.

 

그러니까 앞서 살펴 본 decompiled code는 전혀 실행이 되지 않을 거란 겁니다.
 


[+] !




Injection 될 Code는 아래와 같습니다.

 

 

<Fig4. Injection 될 길이 0xDE의 Code>



add method가 시작하는 address에 이 code를 덮어 씌우신 후 다시 분석 하면 된다는 거죠.

 

ida를 활용하여 해당 function 의 address를 확인합시다.  직접 memory를 dump 뜬 후에 비교하는 방법으로도 address를 쉽게 구할 수 있습니다.

 

이를 통해 구한 실제 파일의 offset 은 0x27680 입니다.

 

 classes.dex파일에 저 code를 덮어 씌운 다음 Tool을 돌려보면..


 dex2jar 는 해석을 못하고 오류를 뱉습니다.


baksmali도 안되네요.


IDA도 안되요. 

<Fig. 아오.. >


 

다행히 한 Tool에서 오류가 나는 곳이 다른 Tool에서는 잘 분석 될 때도 있더군요.

 

이건 뭐 드래곤볼도 아니고 Code를 모아 소원을 빌어 문제를 해결하는 것도 아니고 ..

 

아무튼 한땀한땀 짜깁기를 하면 ..

 

<Fig5. 모은 Dalvik code>

 

뭐 아무튼 실마리는 다 모였고 Tool에서 해석되다 만 Code들과 Hand-ray를 사용하면

 

아래와 같은 Code를 얻을 수 있습니다.

 

<Fig6. Code를 다 모았으니 문제를 풀어주세요!>

 

 

사실 ... 부분은 모든 Tool이 Error를 낸 부분인데

 

다행히 4byte 정도라 manual 해석 및 추측이 가능한데요.

 

map.put 이 들어가겠죠.

 

자.. 이제 package 쪽은 다 해결 됐습니다.

 

마지막으로 본 문제쪽 Java Code를 살펴봐야 합니다

 

문제에 앞서 ..

 

한가지 퀴즈를 내볼까요?

 

Lјava/lang/String 과 Ljava/lang/String;

 

같을까요 다를까요?

 

 

 

...

 

다릅니다.

 

아니 이게 무슨 소리야..

 

ј가 j가 아니라니

 

사실 전자의 j로 보이는 문자는

 

0xD1 0x98의 Unicode 문자입니다.

 

이런 거지같..

 

그런고로

 

전자 Fake j는 출제자의 Class를 참조하고

 

후자 진짜 j는 java 기본 Class를 따릅니다.

 

까도 까도 깔게 나오는 너란 문제.. 양파 같은 문제..

 

<Fig7. Verify Botton을 눌렀을 때 호출되는 함수>

 

 

fake.String 에서 new를 통해 생성하는 건 위에서 한땀 한땀 빚어낸 Add Method를 타게 됩니다.

 

남은 잡다구리한 함수를 거쳐 생성한 String  "RKGMKAQEGJATGAVWABJKGTG" 를

 

add method에 넣고 돌려주면 답이 나옵니다.


THECHANGESAREALWABSHERE

THECHANGESAREALWAYSHERE

 

2가지네요.

 

 

<Fig8. 보고 싶던 너>

 

 


[+]  ++ 


Code injection을 통해 동적으로 Code를 바꾼다.

 

난독화에 있어 괜찮은 방법이 될 수 있을 거 같습니다.

 

특정 함수가 불릴때만 잠깐 바꾼다면 Memory dump를 통해 알아내기도 힘들겠죠.

 

물론 넣을 Code가 다 노출되는 단점이 있습니다만.. 이 또한 알아보기 어렵도록 꼬아놔야할 겁니다.

 

섞고 , 섞고, 돌리고 섞고..

 

하지만 이렇게 꼬아놔도 어쨌든 깨지는건 시간의 문제이기 때문에 많은 기업들이 이제

 

Hardware를 이용한 보안 기술 접목을 준비하고 있습니다.

 

TPM 이나 Trust zone을 사용해서 말이죠.

 

이러한 Hard 기반 보안 기술이 과연 얼마나 튼튼한 방패가 될 지는 아직 두고봐야 할 것 같습니다.


 

Posted by LinkC

2012.12.27 20:25 System

[+] Introduction 


 

사람이 가장 잉여스러워지는 시간인 방학이 찾아왔습니다.


정신차리고 보니 크리스마스가 지났네요 

 

<Fig. 24일에 올렸어야 할 짤방>

 


왠지 1년 전에도 이와 비슷한 일이 있었던 것 같지만 그냥 넘어가요 우리..


아무튼 새해가 찾아오기 전에 글이라도 하나 올려야 제 자신에게 변명거리라도 될 거 같아요.

 

 




[+] What is "Code obfuscation"? 


 

코드 난독화는 Program들이 나날이 자신들을 역공학 해주는 리버서들의 열정에 몸둘바를 몰라 만들어낸 일종의


자기 방어술입니다.


리버서들의 목적이 대부분 악용에 있다 보니 , Program 업체들은 자신들의 자산이 까발려지지 않기 위해 혹은 악용되지 않기 위해


Anti-debugging 부터 해서 실행 압축 [ Packer ] , 여기서 더 나아간 Protector 까지 적용합니다.


물론 , 이 기술들이 악성 코드에 적용되고 있는 건 다시 말할 것도 없겠죠.


이 중에서 코드 난독화는 Protector에 흔히 적용되는 기술인데 말그대로 코드를 읽기 어렵게 하는 겁니다.


암호화 하고 코드를 치환하고 API 호출을 빙빙 돌려서 정적 분석 뿐만 아니라 동적 분석 까지 막는 것이 그들의 임무입니다.


리버서들이 해석하기 어렵게 코드를 짜야 합니다. 이를 해석해주는 Disassembler가 해석하기 어렵게 코드를 짜야 합니다.

 

이를 위해서 실제 소스 코드 상에서 말도 안되는 Dummy code를 집어넣어 흐름을 헷갈리게 만드는 경우도 있습니다만,

 

그보다는 Assembly 단에서 명령어를 꼬아서 혼란시키는 방법을 많이 사용하고 있습니다.

 

오늘 말하려고 하던 주제가 여기서 더 깊숙히 들어가면 멀어지는 관계로 간단히 정리만 하고 넘어가죠.

 

Disassembly 기법은 크게 2가지 정도 나눌 수 있습니다.

 

- Linear sweep

 

- Recursive traversal

 

이 2가지 방법의 알고리즘을 이해하고 나서,

 

그 알고리즘으로서는 해석하면 실제 실행한 것과 다른 결과를 내는 임의의 코드를 삽입하는 거죠.

 

실행과는 전혀 상관 없는 Dummy assembly 를 잔뜩 집어 넣는 방식도 해석하는 입장에서는 정말 짜증날 수 밖에 없습니다.

 

 

<Fig. 코드 난독화가 되어 있는 것을 확인했을 때>

 

 

 

[+] what`s the applicability of code obfuscation?


 

코드 난독화의 대상이 될만한 것이 무엇이 있을까요?


Disassembly 혹은 Decompile이 매우 쉽게 이루어지며 그 결과물이 실제와 가장 근접한 것이 이 난독화의 힘을 가장 많이 볼 수 있지 않나 싶은데요.

 

떠오르신 바로 그겁니다.

 

Java

 

아니라구요? ㅈㅅ...

 

Java는 그 특성상 구동방식이 일반 Application 과 다르기 때문에 코드 난독화를 적용하는데 어려움이 있는 건 사실입니다.

 

하지만 Java에서도 C, C++ 를 사용할 수 있는 방법이 있으니 [ 즉 우리가 알고 있는 Disassembly 를 적용할 수 있는 언어 ]

 

그것이 바로 JNI [ Java Native Interface ] 입니다.

 

* 이 방법외에도 이미 Java 에서는 안드로이드 시장이 활성화됨에 따라 Dex guard, Pro guard 등 코드 분석을 어렵게 하는 방식들이 존재합니다.

 

 

 

 

[+] Considering about JNI 


 

JNI 는 Java에서 Loadlibrary 를 통해 C, C++ 혹은 assembly 로  이루어진 library 를 호출 할 수 있도록 하는 Framework 입니다.

 

원래 목적은 말그대로 C, C++ 등으로 이루어진 library 를 추가 구현 없이 java에서 사용하기 위함입니다.

 

혹은 복잡한 수학연산 등은 JVM 보다 native code가 빠르므로 JNI 를 이 분야에서 사용하기도 하죠.

 

아무튼 이 JNI 를 통해서 기존에 사용했던 코드 난독화 기법등을 사용할 수 있게 됩니다.

 

Library 자체를 packing 하여 실행 압축을 사용할 뿐만 아니라 dummy code등을 사용할 수 있죠.

 

추가적으로 api redirection 이나 함수 포인터를 이용하여 분기 하는 모듈을 리버서에게 노출 시키지도 않을 수 있습니다.

 

가변 인자를 사용하면 모든 함수들의 호출을 일반화 할 수 있고, 함수를 구분하는 식별 인자 또한 고정방식이 아니라

 

유동적으로 변하되 항상 같은 값을 유도할 수 있게 만들 수 있죠.

 

이렇듯 코드 난독화 기법은 고정적인 방법이 아니라 얼마든지 다양한 방법으로 접근 할 수 있습니다.

 

 

 

 

 

 

쓰고보니 별로 기술적인 내용이 들어갈 게 없네요..

 

기존 난독화 기술을 설명하자니 좀 식상할 것 같고 .. 좀 더 신박한 난독화 기술이 있다면 들고 오도록 하겠습니다.

 

 

Posted by LinkC
이전버튼 1 이전버튼

블로그 이미지
LinkC

태그목록

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

공지사항

Yesterday49
Today18
Total323,952

달력

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

최근에 받은 트랙백

글 보관함


. .