티스토리 뷰

728x90
반응형

[ 브로드 캐스트 리시버 ]

  :  안드로이드 디바이스에서 이벤트가 발생하면 브로드캐스트 신호를 보내는데, 이 신호를 받아 처리하는 역할

 

 

- 대상 애플리케이션에서 발생하는 브로드캐스트 받기 위해선 브로드캐스트 리시버가 설정되어 있어야 함.

- 신호를 받는 경우 애플리케이션에 정의해 놓은 작업 수행.

- AndroidManifest.xml의 <receiver></receiver> 항목에 선언

 

- 애플리케이션에서 선언한 액선을 호출하면 리시버는 해당 액션을 인지해 작업을 수행.

  (이 작업은 브로드캐스트 리시버를 상속 받은 메서드에서 처리)

 

- 브로드캐스트 리시버를 호출할 때 발생하는 브로드캐스트가 정상이면 부팅 완료, 문자 메시지 송/수신, 배터리 상태 등을

   나타내는 시스템 이벤트와 다른 애플리케이션에서 발생하는 경우 있음.

   비정상이면 악의적인 애플리케이션에서 발생하거나, 공격자에 의해 임의대로 생성 가능.

    (사용자가 받는 알림(메시지, 전화 등)을 중간에서 가로채거나 특정 상황에 발생하는 작업 우회해 수행하도록 조작)

 

 

AndroidManifest.xml

<receiver
	android:name=".MyBroadCastReceiver"
    android:exported="true" >
    <intent-filter>
    	<action android:name="theBroadcast" >
        </action>
    </intent-filter>
</receiver>

브로드 캐스트 이름 : theBroadcast

브로드 캐스트 신호를 받으면 MyBroadCastReceiver에 설정된 작업 수행

exported 값이 true로 되어 있으므로 외부 애플리케이션으로부터 intent를 받을 수 있는 상태

(intent : 앱이 무엇을 할지 담는 메시지 상자. 메시지 객체. intent를 주고받으며 소통)

 

MyBroadCastReceiver.class

public class MyBroadCastReceiver extends BroadcastReceiver {
  public static final String MYPREFS = "mySharedPreferences";
  
  String usernameBase64ByteString;
  
  public void onReceive(Context paramContext, Intent paramIntent) {
    String str2 = paramIntent.getStringExtra("phonenumber");
    String str1 = paramIntent.getStringExtra("newpass");
    if (str2 != null)
      try {
        SharedPreferences sharedPreferences = paramContext.getSharedPreferences("mySharedPreferences", 1);
        this.usernameBase64ByteString = new String(Base64.decode(sharedPreferences.getString("EncryptedUsername", null), 0), "UTF-8");
        String str3 = sharedPreferences.getString("superSecurePassword", null);
        String str4 = (new CryptoClass()).aesDeccryptedString(str3);
        str3 = str2.toString();
        str1 = "Updated Password from: " + str4 + " to: " + str1;
        SmsManager smsManager = SmsManager.getDefault();
        System.out.println("For the changepassword - phonenumber: " + str3 + " password is: " + str1);
        smsManager.sendTextMessage(str3, null, str1, null, null);
        return;
      } catch (Exception exception) {
        exception.printStackTrace();
        return;
      }  
    System.out.println("Phone number is null");
  }
}

MyBroadCast Receiver 메서드는 BroadcastReceiver를 사용하기 위해 BroadcastReceiver 객체를 상속 받고

브로드캐스트가 발생하는 경우 Intent-filter에 의해 걸러진 Intent들이 onReceive() 메서드로 들어와 입력된

전화번호에 문자 메시지를 전송하도록 정의 되어 있음

 

전화번호 입력되지 않았다면 "Phone number is null"을 출력

이때, 앱 사용자 정의 브로드캐스트 리시버를 사용하거나 Intent-filter에 특정 권한을

명시하지 않으면 이 앱은 다른 앱에 의해 브로드캐스트 리시버가 악용될 수 있다.

 

 

< 취약점 진단 과정 >

1)  ADB를 이용한 브로드캐스트 생성

1. 앱 실행

2. ADB shell 실행

 adb -e shell

 

3. 브로드캐스트 생성

ADB에서 임의의 브로드캐스트를 생성해 브로드캐스트 리시버를 속이기 위해서는 am 명령 사용

am : 액티비티 매니저로, 안드로이드 시스템에 포함된 다양한 액션을 명령으로 수행 가능.

 

am broadcast -a theBroadcast -n com.android.insecurebankv2/.MyBroadCastReceiver

logcat -s System.out:I 명령어로 확인해보면 phonenumber을 입력하지 않았으므로 "Phone number is null"이 출력.

 

 

4. --es 옵션에 변수와 함께 값을 추가

am broadcast -a theBroadcast -n com.android.insecurebankv2/.MyBroadCastReceiver --es phonenumber 5555 --es newpass test

logcat -s System.out:I 으로 로그를 확인하면 입력된 전화번호로 문자 메시지 로그와

메시지 내용으로 비밀번호 변경 확인 메시지가 포함되여 출력됨.

 

계정의 비밀번호는 변경되지 않고 비밀번호만 노출됨.

 

 

2) 드로저를 이용한 브로드캐스트 생성

1. nox로 드로저 실행 후 on으로 변경

2. ADB로 window 드로저와 녹스 app 드로저 tcp 연결

adb forward tcp:31415 tcp:31415 

 

3. 드로저 연결

 

4. 앱 취약점 확인

run app.package.attacksurface com.android.insecurebankv2

1개의 브로드캐스트 리시버가 외부에서 접근 할 수 있다는 것을 확인 가능.

공격할 부분을 확인했으니 브로드캐스트 리시버에 대한 정보 확인을 한다.

 

5. 브로드캐스트 리시버 정보 확인

run app.broadcast.info -a com.android.insecurebankv2

현재 com.android.insecurebankv2 패키지에 MyBroadCastReceiver 이름인 브로드캐스트 리시버 존재 확인 가능.

Permission(권한)은 따로 설정되어 있지 않음.

 

6. 브로드캐스트 리시버 실행 

run app.broadcast.send --component com.android.insecurebankv2 com.android.insecurebankv2.MyBroadCastReceiver --extra string phonenumber 5555 --extra string newpass test

 

로그를 확인하면 ADB에서 수행한 것과 동일하게 기존 비밀번호와 문자 메시지 

전송 위한 항목이 출력되는 것을 확인 할 수 있다.

 

 

 

< 대응 방안 >

1. AndroidManifest.xml 리시버 항목에 위치하는 "android:exported=true" 를 false로 설정

AndroidManifest.xml

<receiver
	android:name=".MyBroadCastReceiver"
    android:exported="false" >
    <intent-filter>
    	<action android:name="theBroadcast" >
        </action>
    </intent-filter>
</receiver>

true로 설정되어 있을 경우 외부 앱에서 발생하는 인텐트에 영향을 받지 않아

브로드캐스트 리시버도 임의의 브로드캐스트에 영향을 받지 않게 된다. 

따라서, true를 false로 설정해야 한다.

 

만약 intent-filter 값이 포함되어 있는 경우 기본값이 true로 설정된다.

 

2. 각 리시버에 별도의 Permission(권한)을 준다.

권한을 주는 것 = 권한이 있는 경우에만 접근 가능

 

각 요소에 사용자가 임의의 권한을 부여하면 접근 제한을 관리하기 용이하다.

 

 

 

728x90
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함