2014.01.04 17:57 System


[+] Blah Blah 

 


 

 

2014년 첫 포스팅입니다.

 

마지막 포스팅이 13년 5월 이었으니까 하 죽일놈의 게으름.

 

최근에 모바일쪽 일을 하고 있어서 이번 글 역시 모바일 관련 이야깁니다.

 

android app을 사용하여 shell 을 띄우려면 어떻게 해야 할까요?


크게 2가지 방법이 있습니다.

 

1. App 내에서 shell 실행

 

2. App 에서 호출하는 library 내에서 shell 실행

 

전자는 dalvik vm 내에서 , 후자는 library 가 직접 실행하게 됩니다.


전자의 경우는 app 내의 취약점이라기 보다는 repacking 공격에서 사용되겠죠.

 

본문은 후자의 방법을 통해 취약점을 공략해보는 방법을 기술합니다.

 

 


[+] about vulnerable library

 


 

pc에서 사용되는 많은 library들이 cross-compile을 통해 모바일에서도 재사용되곤 합니다.

 

그 덕에 취약한 library도 자기 영역을 확장시켜가고 있고 여러 플랫폼으로 배포가 이루어진 library들은

 

비단 하나의 플랫폼에만 취약한게 아니게 되었습니다.

 

예를 들어 libpng 라는 이미지 처리 library를 들어보죠.

 

해당 library는 open source project로서 linux의 system library로 실제 사용되고 있으며

 

cross-compile이 가능한 덕에 android에서도 사용하는 사람이 있죠.

 

compile 옵션과 compiler 버전에 따라 약간 달라질 수 있겠지만 취약점이 있으면 사용하고 있는 다른 플랫폼도 취약점에

 

노출될 수 있다는건 누구나 다 알 수 있습니다.  

 

더구나 이미지 파일의 특성 상 파일 전송을 통한 공격이 매우 수월한 것은 두 말 할 필요도 없겠죠.


그런 이유로 android app 내부에서 jni 형태로 호출되는 취약한 image library 가 본문의 희생양으로 출현해주셨습니다.


<Fig 1. libpng 공식 사이트에 올라온 보안 위협>

 

 



[+] attack

 


 

 

libpng의 취약점 중 입맛에 맞는 것으로 하나 골라 공격합니다.

 

x86 shell code 대신 arm shell code를 삽입하고 환경에 맞게 stack 위치만 조정해주면 공격에 성공합니다.

 

참 쉽죠?

 

는 구버전에서만 가능한 일이고, 최신 버전에서는 DEP 덕에  ROP를 사용해야 합니다.

 

ASLR이 적용되어 있기는 하나, system library는 아예 고정적으로 사용하고 있는 경우도 많고 그렇지 않다하더라도

 

대부분 system library 들은 load되는 memory 위치가 대동소이 합니다.

 

그렇기 때문에 ROP 체인을 구성 하실 때, 하나의 system library에서만 모아서 구성하시면 모든 파일에 ASLR이 적용되어있더라도

 

공격 성공 확률을 높이실 수 있습니다.

 

더구나 Process가 다르더라도 system library 들은 같은 위치에 load되는 경우가 많아 한 앱의 memory map을 구했다고 하면

 

공격은 거저 먹는게 되죠. 

 

<Fig2. 두 Process의 memory map 비교>

 

 

필자의 경우 ARM shell code의 재활용을 위해 mprotect를 활용하여 stack에 권한을 주고 shell 을 띄우는 방법을 선택했고,

 

전체 code는 아래 Fig3 처럼 구성될 수 있습니다.

 

<Fig3. ROP 체인 구성>

 

물론 위 code는 얼마든지 유동적으로 바뀔 수 있습니다.

 

모로가도 서울만 가면 되니까요.

 

정리하자면 아래와 같습니다.

 

 

<Fig4. ROP 체인 구성 정리>

 

 

원하는 명령어를 포함하는 ROP 체인 검색 스크립트 +  ROP 체인 구성 스크립트 + 취약 image 생성 스크립트

 

대략 이 3가지 스크립트가 사용된거 같네요.


이렇게 만들어진 취약한 Image를 피해자에게 전송하면 파일 내에 삽입된 code가 실행되고 

 

최종적으로 reverse shell을 얻을 수 있습니다.

 

 

<Fig5. reverse shell을 얻은 모습>




 

[+]  More and more


 

library 내에서 execve 류 함수가 실행되면 Process가 아예 바뀌기 때문에 앱이 죽게 됩니다.

 

물론 시스템에서 재 실행 시켜주기 때문에 잠깐 깜빡거리는 수준이지만 ..


앱이 아예 죽지 않고 임의의 코드를 실행하려면 아래 조건을 만족해야 합니다.

 

1. execve 류 함수 사용 X 

 

2. fork 사용 X [ System 함수는 fork & execve의 조합 사용이므로 역시 불가 ]

 

library 내에서 fork를 사용하게 되면 Fig6 과 같이 정상적으로 생성되지 않고 zombie가 됩니다.


android app은 fork 함수를 지원하지 않는 거 같네요.

 

<Fig6. fork 사용 후 Process>

 

3. stack 복구

 

취약점 발생 구간과 메모리 참조 영역을 주의 깊게 살펴보셔야 합니다.


덮어 씌운 부분이 후에 참조될 경우 crash가 날 수 있으니까요.


취약 함수가 return 값을 가지고 있는지, 가지고 있다면 어디서 참조 하는지 ..


호출된 jni 함수가 아예 void return 이면 그 쪽으로 단번에 넘어가버리는 게 가장 좋겠죠.

 

아무튼 이런 조건이 맞는다면 execve 함수 사용이 제한되기는 하나 특정 코드는 무인지 공격이 가능하게 됩니다.

 

예를 들어 stack 에 권한을 주는 코드를 무인지로 실행한다던가 말이죠.

 

 

 

Posted by LinkC

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
이전버튼 1 이전버튼

블로그 이미지
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    

최근에 받은 트랙백

글 보관함


. .