취약점 개요

브로드캐스트 리시버(Broadcast Receiver)는 백그라운드로 대기하고 있다가 이벤트가 발생하면 시스템에서 전달한 메시지(인텐트, Intent)를 모든 앱에게 전달하여 처리하는 컴포넌트이다.


브로드캐스트 리시버의 대표적인 메시지는 배터리 부족, 부팅 완료, 인증코드 입력 메시지가 있다.


배터리 부족 메시지는 시스템에 배터리가 부족하면 모든 앱에 존재하는 브로드캐스트 리시버에게 배터리가 부족하다는 메시지를 전송한다.


각 앱의 브로드캐스트 리시버는 메시지를 수신하면 사용자에게 배터리 부족 메시지를 전송한다.


인시큐어뱅크 앱은 비밀번호 로깅 기능의 브로드캐스트 리시버가 존재하는데, 외부에 노출되어 있어 다른 앱에서 비밀번호를 확인할 수 있는 취약점이 존재한다.


취약점 진단

AndroidManifest.xml 파일을 보면 브로드캐스트 리시버의 이름은 MyBroadCastReceiver이고, exported 속성이 true로 설정되어 있으므로 외부에 노출된다.


또한, 인텐트 필터는 theBroadcast 메시지를 전달하여 처리한다.



MyBroadCastReceiver 클래스의 onReceive() 메소드는 인텐트를 받으면 자동으로 호출되는 메소드이다.



phonenumber, newpass가 인텐트로 전달되는 인자이며 각 변수에 저장한다.



조건문에 phonenumber 변수의 값이 없으면 "Phone number is null" 메시지가 출력되고, 변수의 값이 있으면 비밀번호 변경 완료, 전화번호, 이전 패스워드 메시지를 출력한다. (실질적으로 SMS 기능 수행하지 않는다.)



브로드캐스트 리시버가 노출되어 있으므로 외부 앱(드로저)에서 실행시킬 수 있다. 드로저로 노출된 컴포넌트를 보면 1개의 브로드캐스트 리시버가 노출되었다고 나온다.


○ run app.package.attacksurface 패키지명



노출된 브로드캐스트 리시버 정보를 보면 .MyBroadCastReceiver가 노출되었고, 접근 제어가 설정되어 있지 않아 외부 앱에서 접근이 가능하다.


○ run app.broadcast.info -a 패키지명



MyBroadCastReceiver 브로드캐스트 리시버가 노출되었으므로 인자를 전달하지 않고 브로드캐스트 리시버로 보낸다.


○ run app.broadcast.send --component 패키지명 브로드캐스트명



인자를 주지 않고 브로드캐스트 리시버를 요청하면 소스코드와 동일하게 "Phone number is null" 메시지 로그에 기록한다.



phonenumber, newpass 인자에 값을 지정하여 브로드캐스트 리시버를 요청하면 비밀번호 변경, 전화번호, 이전 비밀번호, 변경할 비밀번호를 로그에 기록한다.



인자 없이 브로드캐스트 리시버 호출

--component [패키지 이름] [브로드캐스트 리시버 컴포넌트]

component com.android.insecurebankv2 com.android.insecurebankv2.MyBroadCastReceiver


전달할 인자와 값

--extra string [인자] [값]

--extra string phonenumber 1234 --extra string newpass abcdef


SandDroid의 결과 보고서를 보면 브로드캐스트 리시버가 외부에 노출되어 있고, 브로드캐스트 리시버 이름과 인텐트 이름이 출력된다.


이는 소스 코드 분석을 통해 AndroidManifest.xml에서 확인한 결과와 동일하다.



SMS 기능을 수행하는 코드는 MyBroadCastReceiver 클래스의 onReceive() 메소드라고 출력된다. 이는 소스 코드 분석을 통해 MyBroadCastReceiver.java에서 확인한 결과와 동일하다.



대응 방안 및 검증

브로드캐스트 리시버 취약점은 AndroidManifest.xml에 <receiver> 태그 내의 android:exported 속성이 true로 설정되어 브로드캐스트 리시버 호출이 가능하다.


브로드캐스트 리시버 취약점
AndroidManifest.xml에 구현되어 있는 <receiver> 태그 내의 android:exported="true" 속성을 "false"로 변경
Permission 속성을 이용한 접근 제어

AndroidManifest.xml에 구현되어 있는 태그 내의 android:exported="true" 속성을 "false"로 변경한다.



정상적으로 보안 조치가 적용되었는지 드로저로 노출된 컴포넌트를 보면 브로드캐스트 리시버는 외부에 노출되지 않는다.



정확한 검증을 위해 인자를 전달하지 않고 브로드캐스트 리시버를 호출하면 'Permission Denial' 메시지가 로그에 기록된다.



▶ Android Drozer 설치 및 사용법

▶ 안드로이드 컴포넌트 취약점 (Android Activity)

▶ 안드로이드 백업 취약점 (Android Backup)

▶ 안드로이드 메모리 노출 취약점 (메모리 덤프)

▶ 안드로이드 난독화 (코드 보호 기법)

▶ 안드로이드 루팅 탐지 우회 (Frida Hooking)

  • 카카오톡-공유
  • 네이버-블로그-공유
  • 네이버-밴드-공유
  • 페이스북-공유
  • 트위터-공유
  • 카카오스토리-공유