1. 브로드캐스트 리시버(Broadcast Receiver) 결함
[개 요]
브로드캐스트 리시버는 안드로이드 4대 컴포넌트 중 하나로, 안드로이드 디바이스에서 이벤트가 발생하면 브로드캐스트 신호를 보내는데, 이 신호를 받아 처리하는 역할을 수행합니다.
애플리케이션에서 발생하는 브로드캐스트를 받기 위해서는 브로드캐스트 리시버가 설정되어 있어야 하며, 신호를 받는 경우 애플리케이션에 정의해 놓은 작업을 수행합니다. (ex: 전화 및 메시지 수신, 배터리 부족, 사진 촬영 및 캡처 등)
이때 공격자가 임의의 브로드캐스트를 생성하여 원하는 정보를 가로채거나 조작할 수 있는데 이를 브로드캐스트 리시버 결함이라고 합니다.
[진단 과정]
1) 먼저 AndroidManifest.xml 내 <receiver> 태그를 확인합니다. 해당 태그는 브로드캐스트 리시버 컴포넌트를 정의한 태그로 특정 인텐츠를 수신하고 처리하는 역할을 합니다.
2) 브로드캐스트 리시버의 정확한 동작을 확인하기 위해서 MyBroadCastReceiver 클래스 파일을 확인해보겠습니다. 해당 클래스 파일은 특정 브로드캐스트를 수신 시 저장된 사용자 정보와 비밀번호를 복호화한 후, 주어진 전화번호로 새 비밀번호를 포함한 SMS를 전송하는 기능을 수행합니다.
3) 여기서 주목해야 할 부분은 System.out.println("For the changepassword - phonenumber: " + textPhoneno + " password is: " + textMessage); 부분으로 기존 비밀번호와 새 비밀번호를 포함하는 메시지 텍스트를 생성하는데 이 때 System.out.println를 통해 변경된 비밀정보를 포함하는 디버그 메시지를 콘솔에 출력합니다.
콘솔에 출력되는 부분은 총 2가지로 textPhoneno와 textMessage 부분인데 textPhoneno는 저장된 번호값을 출력하고 textMessage는 decryptedPassword와 newpass 값을 출력합니다. 즉 기존 비밀번호와 새 비밀번호를 출력한다는 취약점이 존재합니다.
4) 위 방법 처럼 AndroidManifest.xml 파일을 통하여 취약점을 확인할 수도 있지만 drozer를 이용해서 취약점을 확인할 수 있습니다. drozer 실행 후 attacksurface 명령을 사용하면 외부에 노출된 취약점을 확인할 수 있는데 1개의 브로드캐스트 리시버 취약점이 있는 것을 확인하였습니다. 즉 해당 앱의 브로드캐스트 리시버는 외부에서 접근이 가능하다는 얘기입니다.
- 명령어 : run app.package.attacksurface com.android.insecurebankv2
5) 이번에는 해당 앱의 브로드캐스트 리시버 정보를 확인해 보겠습니다. 인시큐어뱅크 패키지 내 MyBroadCastReceiver라는 이름의 브로드캐스트 리시버가 포함되어 있으며 브로드캐스트 리시버를 호출하는 데 특별한 권한이 없는 것을 확인하였습니다.
- 명령어 : run app.broadcast.info -a com.android.insecurebankv2
6) 2~3번 실습에서 획득한 정보를 통해 폰넘버를 111로 설정하고 새로운 패스워드를 test로 설정해서 인시큐어뱅크 앱 내 브로드캐스트 리시버에 접근하여 브로드캐스트 메시지를 보냅니다. 이때 로그캣 확인 시 입력한 전화번호, 문자 메시지 전송 로그와 함께 기존 비밀번호가 노출된 것을 확인하였습니다. (이 때 실제로 패스워드가 변경되지는 않습니다)
- 명령어 : run app.broadcast.send --component com.android.insecurebankv2 com.android.insecurebankv2.MyBroadCastReceiver --extra string phonenumber 1111 --extra string newpass test
[대응 방안]
o AndroidManifest.xml의 리시버 항목에 위치하는 android:exporeted="true" 항목을 "false"로 설정
- 설정값이 true일 경우 외부 애플리케이션에서 발생하는 인텐트에 영향을 받지 않게 되므로 브로드캐스트 리시버도 임의의 브로드캐스트에 영향을 받지 않게 됩니다.
1) APKStudio를 실행하여 InsecureBankv2.apk을 실행합니다. 실행 시 경로 안에 해당 디렉터리가 생성됩니다.
2) AndroidManifest.xml 파일을 열고 리시버 항목 내 'android:exported=true' 부분을 'android:exported=false'로 변경 후 저장, 빌드를 실행합니다.
3) 빌드시 apk 파일이 생성됩니다. 기존에 녹스에 설치된 인시큐어뱅크 앱을 삭제 후 생성된 apk 파일을 녹스에 설치 시 설치가 되지 않는데 이때 jarsigner을 이용하여 서명을 하고 zipalign을 이용하여 파일을 정렬해 준 후 InsecureBankv3.apk파일을 새로 생성해 줍니다. 생성된 InsecureBankv3.apk 파일을 다시 녹스에 설치 시 정상적으로 설치가 됩니다.
4) 그 후 drozer를 통하여 6번 실습을 재시도 시 메시지가 출력됩니다. (BroadcastQueue: Permission Denial: broadcasting Intent { flg=0x10 cmp=com.android.insecurebankv2/. MyBroadCastReceiver (has extras) } from cohttp://m.withsecure.dz (pid=3366, uid=10059) is not exported from uid 10062 due to receiver com.android.insecurebankv2/.MyBroadCastReceiver) 드로저(com.withsecure.dz 패키지)에서 생성된 브로드캐스트는 권한이 없다는 뜻으로 더이상 외부에서 접근이 불가능함을 확인하였습니다.
5) 또한 drozer를 통하여 외부에 노출된 취약점 확인시 기존과는 다르게 broadcast receiver exported 부분에 취약점이 없는 것을 확인하였고 broadcast 정보 확인 시에도 노출되는 리시버가 없는 것을 확인하였습니다.
6) 이처럼 AndroidManifest.xml 파일 리시버 항목에 위치하는 android:exporeted="true" 항목을 "false"로 변경하는 것으로 외부에서 해당 브로드캐스트 리시버의 접근을 막을 수 있습니다.
o 각 리시버에 별도의 권한 부여
- 브로드캐스트 리시버마다 특정 권한을 지정하여, 해당 권한을 가진 앱만 브로드캐스트를 보낼 수 있도록 설정할 수 있습니다. 이를 위해 android:permission 속성을 사용하는데 이 속성을 사용하면, 브로드캐스트를 수신하는 리시버가 특정 권한을 요구하도록 설정할 수 있다.