[HACKING] Android Cloak & Dagger Attack과 Toast Overlay Attack(CVE-2017-0752)

오늘은 최근 말이 많았었던 Android 취약점 2가지에 대한 이야기를 할까 합니다. 바로 Cloak & Dagger Attack 과 Toast Overlay Attack 입니다.

직접 앱으로 만들어서 보여드릴까 하다가.. 그냥 가볍게 포스팅해봅니다. (사실 안드로이드 안만든지 너무 오래됨.. | 심지어 대학생때에도 난 서버담당..)

What is Cloak & Dagger Attack?

먼저 Cloak & Dagger부터 보면 최근 안드로이드의 새로운 공격 벡터로 나타나 기법입니다. 엄청 독특하다기 보단 사용자를 낚는 고전적인 방법이긴 하나 적당한 공격 환경이 갖춰졌을 때 권한 탈취가 가능하기 때문에 중요하게 봐야합니다.

관련해서 black 2017에서도 이야기 나왔으니 참고해주세요. https://www.blackhat.com/docs/us-17/thursday/us-17-Fratantonio-Cloak-And-Dagger-From-Two-Permissions-To-Complete-Control-Of-The-UI-Feedback-Loop.pdf

Cloak & Dagger 공격은 악성앱이 다른 앱들이 실행될 때 가짜 팝업(업데이트하세요, 새로운 뭐가 나왔어요, 권한 요청)을 띄어서 현혹시켜 권한을 얻어오는 등의 행위를 수행할 수 있습니다.

다만.. 조건이 필요한데요.

  • 공식 앱 설치 경로(플레이스토어, 원스토어 등)에 올라가야 함(신뢰성을 얻기 위해)
  • 앱에서 최상단에 팝업을 띄울 수 있는 옵션이 활성화되어야 함

여기서 두번째로 언급드린 팝업 활성화에 대한 옵션이 아주 중요합니다. 저 옵션이 켜져있지 않다면 공격 자체가 불가능해지죠. (왜냐면 팝업을 맨위로 못올리니깐 / 그 위에 실행한 다른 앱이 올라가니깐)

여기서 필요한 권한은 2가지 입니다.

SYSTEM_ALERT_WINDOW (“draw on top”) BIND_ACCESSIBILITY_SERVICE (“a11y”)

| | |——–| |blackhat 2017 자료 중 일부| SYSTEM_ALERT_WINDOW는 시스템에서 팝업을 위로 올릴 수 있는 오버레이 기능이고 BIND_ACCESSIBILITY_SERVICE는 스크린 읽기에 대한 접근성 권한입니다. 이 친구들은 다른 앱보다 최상단으로 올라갈 수 있기 때문에 가짜 페이지나 팝업들을 마치 다른 앱이 실행한 것 처럼 보여줄 수 있죠.

여러가지 공격 시나리오가 있을 것 같습니다. 대표적으론 클릭재킹 , 입력값 탈취, 피싱 등 사용자의 액션을 이용한 공격 케이스들이 있을 것으로 생각됩니다.

정보 탈취성 공격도 중요하지만, 사용자의 액션을 통해 권한을 얻어갈 수 있다는게 중요하다고 보입니다.

What is Toast?

Android 개발을 해보신분이라면.. 아니 관심있으시다면 바로 아실것이고, 안드로이드 사용자라면 내용을 보고 “아!” 하실겁니다. Toast는 Android에서 메시지를 전달하는 방식 중 하나입니다. 메시지라고 하면 폰이 사용자에게 정보를 주는 수단이고, 팝업 창과 비슷한 개념으로 보시면 됩니다.

바로..

요런거지요.

https://i.stack.imgur.com/RYpeP.png / Message saved as draft. 부분!

Toast overlay attack

Toast를 사용하기 위해선 TYPE_TOAST를 사용해야합니다. 다만 TYPE_TOAST에는 재미있는 부분이 있는데..

권한검사를 제대로 하지 않는다는거죠.

팔로알토 분석가들이 Cloak & Dagger 에 대해 분석해서 얻어낸 결과물이라고 하네요.

일반적으로 다른 앱 위에 화면을 씌우기 위해선 권한이 필요합니다. 그래서 PhoneWindowManager에서도 권한 체크를 통해 제어하는데, TYPE_TOAST의 경우 권한 체크가 빠져있습니다.

아래 코드는 안드로이드의 정책 관련 모듈인 PhoneWindowManager.java 파일입니다. 보시죠. (https://android.googlesource.com/platform/frameworks/base/+/cd92588/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java )

 public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) {
        int type = attrs.type;
        outAppOp[0] = AppOpsManager.OP_NONE;
        if (type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
                || type > WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
            return WindowManagerGlobal.ADD_OKAY;
        }
        String permission = null;
        switch (type) {
            case TYPE_TOAST:
                // XXX right now the app process has complete control over
                // this...  should introduce a token to let the system
                // monitor/control what they are doing.
                // 아무것도 검사하지 않음
                break;
            case TYPE_DREAM:
            case TYPE_INPUT_METHOD:
            case TYPE_WALLPAPER:
            case TYPE_PRIVATE_PRESENTATION:
                // The window manager will check these.
                break;
            case TYPE_PHONE:
            case TYPE_PRIORITY_PHONE:
            case TYPE_SYSTEM_ALERT:
            case TYPE_SYSTEM_ERROR:
            case TYPE_SYSTEM_OVERLAY:
                permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW; // 권한 체크
                outAppOp[0] = AppOpsManager.OP_SYSTEM_ALERT_WINDOW; // 실행여부 확인
                break;
            default:
                permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
        }
        if (permission != null) {
            if (mContext.checkCallingOrSelfPermission(permission)
                    != PackageManager.PERMISSION_GRANTED) {
                return WindowManagerGlobal.ADD_PERMISSION_DENIED;
            }
        }
        return WindowManagerGlobal.ADD_OKAY;
    }

checkAddPermission 함수 내용을 보시면 case가 TYPE_TOAST의 경우 권한 체크를 하지 않습니다.

case TYPE_TOAST:
    // 아무것도 검사하지 않음
break;

똑같이 다른 앱에 덮씌우는 TYPE_SYSTEM_OVERLAY를 보면 퍼미션 검사와 실행여부 검사를 수행합니다.

case TYPE_SYSTEM_OVERLAY:
                permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW; // 권한 체크
                outAppOp[0] = AppOpsManager.OP_SYSTEM_ALERT_WINDOW; // 실행여부 확인

다만 TYPE_TOAST 또한 실행 시 창으로 인식되고 화면을 덮을 수 있습니다. 그럼 권한을 사용하지 않고 Cloak & Dagger Attack이 가능하겠지요?!

마지막으로 blackhat 2017 영상으로 마무리합니다.

Reference

https://researchcenter.paloaltonetworks.com/2017/09/unit42-android-toast-overlay-attack-cloak-and-dagger-with-no-permissions/#table https://www.blackhat.com/docs/us-17/thursday/us-17-Fratantonio-Cloak-And-Dagger-From-Two-Permissions-To-Complete-Control-Of-The-UI-Feedback-Loop.pdf