Android_security

4.Drozer 실습 (Insecurebankv2) - Broadcast Receiver

G_OM 2025. 2. 10. 18:25

1.Broadcast Receiver 개념

브로드캐스트 리시버(Broadcast Receiver)는 안드로이드 앱이 시스템 또는 다른 앱으로부터 특정 이벤트(Broadcast)를 수신하고 이에 따라 동작을 수행할 수 있도록 하는 컴포넌트이다.

예를 들어 배터리 부족, 네트워크 변경, 부팅 완료 등등 시스템 이벤트를 감지하거나 앱 내부에서 정의한 이벤트를 처리하는 데 사용한다.

 

 

 

2.Exported된 브로드캐스트 리시버 찾기

run app.broadcast.info -a com.android.insecurebankv2
->insecurebankv2에 대한 브로드캐스트 리시버 정보를 확인

 

 

 

해석하자면...

 

Package: com.android.insecurebankv2 -> 패키지 이름
  com.android.insecurebankv2.MyBroadCastReceiver -> 브로드캐스트 리시버가 존재함
    Permission: null -> 별도의 보안 권한 없이

 

 

자 그럼 MyBroadCastReceiver 가 뭐 하는 class 인지 확인해 보자.

 

 

 

3.MyBroadCastReceiver 확인

package com.android.insecurebankv2;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.telephony.SmsManager;
import android.util.Base64;
import java.io.PrintStream;

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);
        byte[] arrayOfByte = Base64.decode(sharedPreferences.getString("EncryptedUsername", null), 0);
        String str4 = new String();
        this(arrayOfByte, "UTF-8");
        this.usernameBase64ByteString = str4;
        str4 = sharedPreferences.getString("superSecurePassword", null);
        CryptoClass cryptoClass = new CryptoClass();
        this();
        str4 = cryptoClass.aesDeccryptedString(str4);
        String str3 = str2.toString();
        StringBuilder stringBuilder1 = new StringBuilder();
        this();
        str1 = stringBuilder1.append("Updated Password from: ").append(str4).append(" to: ").append(str1).toString();
        SmsManager smsManager = SmsManager.getDefault();
        PrintStream printStream = System.out;
        StringBuilder stringBuilder2 = new StringBuilder();
        this();
        printStream.println(stringBuilder2.append("For the changepassword - phonenumber: ").append(str3).append(" password is: ").append(str1).toString());
        smsManager.sendTextMessage(str3, null, str1, null, null);
      } catch (Exception exception) {
        exception.printStackTrace();
      } 
      return;
    } 
    System.out.println("Phone number is null");
  }
}

 

핵심만 본다면

 

 

SharedPreferences sharedPreferences = paramContext.getSharedPreferences("mySharedPreferences", 1);
byte[] arrayOfByte = Base64.decode(sharedPreferences.getString("EncryptedUsername", null), 0);
String str4 = new String(arrayOfByte, "UTF-8");  // Base64 디코딩하여 사용자 ID 복원
this.usernameBase64ByteString = str4;

str4 = sharedPreferences.getString("superSecurePassword", null);  // 암호화된 비밀번호 가져오기
CryptoClass cryptoClass = new CryptoClass();
str4 = cryptoClass.aesDeccryptedString(str4);  // 비밀번호 복호화

 

1. 원래 있던 사용자 정보를 복호화해서 ID, 비밀번호를 가져온다.

 

StringBuilder stringBuilder1 = new StringBuilder();
str1 = stringBuilder1.append("Updated Password from: ").append(str4)
                      .append(" to: ").append(str1).toString();

 

2. 기존 비밀번호 + 새로운 비밀번호를 조합하여 문자열을 생성한다.

 

SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(str3, null, str1, null, null);

 

3.SMS로 비밀번호를 전송한다.

 

PrintStream printStream = System.out;
StringBuilder stringBuilder2 = new StringBuilder();
printStream.println(stringBuilder2.append("For the changepassword - phonenumber: ")
                                  .append(str3).append(" password is: ").append(str1).toString());

 

4. 전화번호와 비밀번호를 로그에 출력한다 (평문출력)

 

 

문제점이라고 하면...

1.SMS로 비밀번호에 대한 정보를 평문으로 전송하다는 점

2. 로그에 휴대폰번호, 비밀번호가 평문으로 노출된다는 점 

 

한번 로그에 평문으로 노출되는지 확인해 보자.

 

 

 

 

 

 

4.MyBroadCastReceiver - 취약점 확인

 

run app.broadcast.send --component com.android.insecurebankv2 com.android.insecurebankv2.MyBroadCastReceiver --extra string phonenumber 01012345678 --extra string newpass GrayOM

 

run app.broadcast.send -> 브로드캐스트 인텐트를 전송하는 명령어
--component -> 이 플래그는 특정 컴포넌트(액티비티,서비스,브로드캐스트리시버) 를 지정할 때 사용
--extra -> 인텐트의 데이터를 전달하는 부분 (휴대폰 번호 , 새로운 비밀번호 ) 를 설정함

 

 

이제 로그에 평문으로 노출되는지 확인하면 부분이다.

 

 

로그를 확인하면 휴대폰 번호와 비밀번호를 평문인 채로 노출되는 걸 확인할 수 있다.

 

 

 

5. 대응 방안

Xml 파일에서 MyBroadCastReceiver의 exported 값을 false로 설정하거나 Permission 속성을 사용해 권한을 제한하고 IntentFilter을 이용해서 브로드캐스트를 차단한다.

 

<receiver android:name=".MyBroadCastReceiver"
          android:exported="false">
</receiver>
<receiver android:name=".MyBroadCastReceiver"
          android:permission="com.android.insecurebankv2.PERMISSION_ACCESS">
</receiver>
<receiver android:name=".MyBroadCastReceiver">
    <intent-filter>
        <action android:name="com.android.insecurebankv2.ACTION_RECEIVE_MESSAGE"/>
    </intent-filter>
</receiver>