보안개구리

2. Hardcoding Issues(하드코딩 이슈) 본문

앱 진단(Android)/Diva 실습

2. Hardcoding Issues(하드코딩 이슈)

보안개구리 2024. 7. 18. 15:18

[Part 1]

1) 2.Hardcoding Issues - Part1에 접속합니다. 접속 시 아래와 같은 화면이 출력됩니다.

목표: 어떤 것이 어디에 하드코딩되어 있는지 찾기

힌트: 개발자들은 편의를 위해 가끔 민감한 정보를 하드코딩할 수 있습니다.

위 정보들을 보면 현재 액티비티 어딘가에 민감한 정보가 하드코딩되어 있다고 추측할 수 있습니다. 앱 중앙에 "Enter the vendor key"라는 키값을 입력할 수 있는 곳이 보입니다. 임의의 키값을 입력한 후 "ACCESS" 버튼을 클릭해 보겠습니다.

 

2) 임의의 키값('apple0915')을 입력한 후 "ACCESS" 버튼을 클릭하면 "Access denied! See you in hell"라는 메시지가 출력됩니다. 이 문자열을 jadx에서 검색하여 해당 문자열이 존재하는 클래스로 이동해 보겠습니다.

 

3) 확인 시, 해당 문자열이 존재하는 액티비티가 두 개 있는데 Part1에 접속할 때 로그를 보면 HardcodeActivity인 것을 알 수 있습니다. 따라서 두 번째 HardcodeActivity를 확인해 보도록 하겠습니다.

 

4) 해당 클래스 내 access 메서드입니다. if 문을 보면, 입력한 문자열이 "vendorsecretkey"일 경우 조건이 참이 되어 "Access granted! See you on the other side :)"라는 메시지를 출력합니다. 앱 화면으로 돌아가 해당 문자열을 입력해 보겠습니다.

 

5) 문자열을 입력하면 "Access granted! See you on the other side :)"라는 메시지가 출력됩니다. 해당 실습에서는 키 값을 입력해야 하는데, 이 키 값이 소스 코드 내에 하드코딩되어 있는 취약점이 있었습니다.

 

 

[Part 2]

1) 12. Hardcoding Issues - Part2에 접속합니다. 보이는 화면은 Part1과 크게 다르지 않으므로 동일하게 취약점을 찾아보도록 하겠습니다. 임의의 키 값을 입력한 후 출력되는 문자열을 jadx에서 검색하겠습니다.

 

2) 검색 결과, 두 개의 액티비티가 나왔으나, 로그 정보를 통해 액티비티명을 확인했기 때문에 상단에 있는 Hardcode2Activity로 이동하겠습니다.

 

3) access 메서드를 확인해 보면 조건문이 존재하며, 해당 조건이 참일 경우 "Access granted! See you on the other side :)"라는 메시지가 출력됩니다. 하지만 키 값이 하드코딩되어 있어 해당 키 값을 입력하면 조건이 참이 되었던 기존과는 달리, 조건을 참으로 만들기 위해서는 djni.access 메서드를 호출하여 사용자가 입력한 키 값을 전달한 후 access의 반환값이 0이 아닌 경우 참이 됩니다. 따라서 djni.access 메서드를 확인해 보도록 하겠습니다.

Part1 access 메서드
Part2 access 메서드

 

4) DivaJni 클래스는 네이티브 메서드를 선언하고 네이티브 라이브러리를 로드합니다. soName이라는 상수에 'divajni'라는 네이티브 라이브러리 이름을 지정한 후 access와 initiateLaunchSequence라는 네이티브 메서드를 선언합니다.

여기서 네이티브 메서드들은 Java 코드에서 직접 구현되지 않고 네이티브 라이브러리에서 구현됩니다. 따라서 해당 내용만으로는 직접 확인이 불가하기 때문에 Ghidra라는 분석 툴을 이용하여 확인해 보도록 하겠습니다.

 

5) Ghidra 툴을 이용해 분석을 원하는 파일을 실행합니다.

 

6) 아래 화면과 같은 과정을 통해 최종적으로 디컴파일 된 access 메서드 내용을 확인할 수 있습니다.

 

7) 디컴파일된 내용을 자세히 살펴보면, 주어진 문자열을 "olsdfgad;lh"와 비교하여 액세스 권한을 결정합니다. 따라서 우리가 입력해야 했던 키 값은 바로 "olsdfgad;lh"입니다.

 

8) Diva 앱 실행화면으로 돌아와 키값 입력란에 "olsdfgad;lh"를 입력해 보겠습니다. 입력 시 "Access granted!"라는 메시지가 출력되며 올바른 키값을 입력한 것을 알 수 있습니다.

 

9) 위 방법은 소스코드를 분석하여 키값을 얻은 후 해당 키값을 입력하는 방식을 통해서 인증에 성공했습니다. 해당 실습과는 별개로 Frida라는 툴을 이용하여 후킹을 통하여 인증에 성공하도록 실습해 보겠습니다.

 

10) 다시 한번 소스코드를 보면 조건문이 참이 되어야 하는데 어떤 값을 입력을 하든 access 메서드가 참값을 반환하면 인증에 성공할 수 있습니다. 

 

11) 아래 코드는 DivaJni 클래스의 access 메서드를 후킹 하여 해당 메서드의 반환값을 항상 1로 되게 설정하였습니다. 따라서 우리가 원래의 키값을 입력하지 않아도 해당 메서드는 반드시 참값을 반환하게 됩니다. Frida를 통하여 실행 보겠습니다.

Java.perform(function() {
    var Hard2 = Java.use('jakhar.aseem.diva.DivaJni');

    Hard2.access.implementation = function(input) {
        console.log('hooking success');

        return 1;
    };
});

 

12) Frida를 통해 위 스크립트를 로드하여 실행 시 임의의 값을 입력하더라도 Access granted!라는 메시지가 출력되었습니다.