Android

앱 취약점 - 브로드캐스트 리시버(Broadcast Receiver) 결함 분석

Ate1es 2021. 8. 12. 17:36

취약점 개요 

 

브로드캐스트 리시버(Broadcast Receiver)는 다양한 이벤트에서 발생하는 브로드캐스트 신호를 받아 처리하는 역할을 수행합니다. 신호를 받으면 애플리케이션에 미리 정의 해놓은대로 작업을 수행합니다.

하지만, 악의적인 의도로 브로드캐스트를 생성하여 외부에서 보내는 이벤트를 악의적으로 수행하게 할 수 있기 때문에 해당 취약점은 점검이 필수적입니다.

 

취약점 진단 과정

 

취약점 진단을 진행할 인시큐어뱅크 앱의 AndroidManifest.xml 파일에 있는 리시버 선언 부분입니다.

AndroidManifest.xml의 일부분

위 코드에서 브로드캐스트의 이름은 theBroadcast 이며, 해당 브로드캐스트 신호를 받으면 MyBroadCastReceiver에 설정된 작업을 수행하게 되어있습니다. 

그리고 android:exported="true"로 설정되어있기 떄문에 외부 애플리케이션으로부터 Intent(신호)를 받을 수 있는 상태입니다.

 

Jadx 툴의 navigation 기능을 이용해서, 해당 브로드캐스트 메소드 부분으로 이동하여 코드분석을 해보겠습니다.

MyBroadcastReceiver 메소드 정의

위 코드를 통해 브로드캐스트가 발생하면 Intent-filter에 의해 걸러진 신호들이 onReceive() 메소드로 들어와 입력된 전화번호에 메시지를 전송하도록 정의되어 있습니다.

 

이 과정에서 애플리케이션이 사용자 정의 브로드캐스트 리시버를 사용하거나, Intent-filter에 특정 권한을 명시하지 않는다면 해당 애플리케이션은 다른 애플리케이션에 의해 브로드캐스트가 오-남용 될 수 있습니다.

 

ADB를 이용해서 브로드캐스트 생성

 

점검할 브로드캐스트 리시버에게 악의적인 브로드캐스트를 보내기 위해 adb의 am 명령을 사용하겠습니다.

해당 명령은 adb shell 명령을 통해 쉘에 진입 후 사용합니다.

명령어 : < am broadcast -a theBroadcast -n com.android.insecurebankv2/.MyBroadcastReceiver >

 

정상적으로 Intent가 생성되었습니다.

브로드캐스트 생성(with adb)

해당 브로드캐스트를 보내는 순간, 안드로이드 로그에 Phone number is null이라는 문자열이 출력됩니다. 

위 코드에서 전화번호 인자값이 없으면 해당 문자열을 출력시키라고 정의되어있기 때문입니다.

조건 구문에 따른 출력결과 로그 (logcat 명령어로 확인)

이번에는 인자값까지 포함하여 브로드캐스트를 생성해서 보내보겠습니다.

명령어 : < am broadcast -a theBroadcast -n com.android.insecurebankv2/.MyBroadCastReciever --es phonenumber 5555 --es nwepass test >

 

아래 그림과 같이, 개발자가 정의해놓은 브로드캐스트리시버가 동작을합니다.

브로드캐스트에 대한 응답 메시지가 출력.

로그 결과를 보면, 비밀번호가 새로 바뀌었다고 리시버가 출력을 하고 있는데 이 정보에 기존 비밀번호가 포함됩니다. 해당 공격은 실제 비밀번호를 변경하지 않기 때문에(리시버만 동작시킨 것이므로) 기존 사용자들의 비밀번호를 그대로 노출시킬 위험이 있습니다.

 

취약점 대응 방안

 

두 가지 방법이 있습니다.

 

1번 - AndroidManifest.xml 파일에 옵션인 android:exported=true 항목을 false로 설정하는 것입니다.

 

해당 설정을 false로 함으로써 외부에서 발생하는 인텐트(신호)에 영향을 받지 않기 때문에 위에서 처럼 adb로 브로드캐스트를 보내도 반응하지 않습니다.

 

2번 - 각 브로드캐스트 리시버에 별도의 권한을 주는 것입니다. 별도의 권한이 있어야만 브로드캐스트 리시버에 접근 할 수 있도록 하면 접근제한을 관리하기 편해집니다.

 

exported 옵션을 false로 설정