[Insecure Bank] 액티비티 컴포넌트 취약점
안녕하세요! 이번시간엔 '액티비티 컴포넌트 취약점' 에 대하여 알아보며 Insecure Bank로 실습해보는 포스팅입니다.
[액티비티 컴포넌트 취약점 이란?]
> 안드로이드 랙티비티는 애플리케이션을 구성하는 가장 기본적인 구성단위 중 하나로, 안드로이드 애플리케이션과 사용자 간의 상호 작용에 필요한 기능과 화면을 제공합니다. 이런 액티비티 설정들은 AndroidManifest.xml 이라는 파일에 <activity> 요소로 선언이 되는데, 이 선언이 취약하게 선언이 될 경우 특정 액티비티에 권한 없이 접근하여 특정기능을 사용할 수 있습니다. 예를들면 악성앱에서 취약한 앱의 비밀번호 변경 액티비티에 접근하여, username 과 newpassword 를 적은후 타인의 비밀번호를 바꿀수 있는 경우도 액티비티 컴포넌트 취약점에 해당합니다.
- 점거해야할 취약한 부분은 다음과 같습니다.
- exported="true" 로 설정되어 있는 부분
- Intent-filter 를 사용후 exported="false" 설정을 안해둔 부분
>> 보통 <activity>를 선언하면 exported="false" 가 디폴트 값인데, Intent-filter를 사용하면 exported="true" 설정이 디폴트 값이 되므로, 필요하지 않다면 반드시 exported="false" 로 명시적으로 선언해주어야 합니다. 참고로 false로 설정할땐 동일한 애플리케이션 & 동일한 사용자 ID를 가진 애플리케이션에서만 액티비티를 호출할 수 있지만, true로 설정하게 되면 다른 애플리케이션에서 exported="true" 상태인 액티비티를 호출할 수 있게됩니다!
1. 취약점 탐색
1. 우선 Jadx로 Insecure Bank 앱을 디컴파일링 한 후, AndroidManifest.xml 파일의 코드를 살펴봅시다. exported="true" 설정을 한 액티비티들이 많이 보입니다. 저희가 타겟으로 삼을건 이 액티비티들중 ChangePassword 액티비티를 통해 사용자의 비밀번호 변경으로 까지 공격을 진행해 보겠습니다.
# AndroidManifest.xml 소스코드중 취약한 부분 발췌
<activity
android:label="@string/title_activity_post_login"
android:name="com.android.insecurebankv2.PostLogin"
android:exported="true"/>
<activity
android:label="@string/title_activity_wrong_login"
android:name="com.android.insecurebankv2.WrongLogin"/>
<activity
android:label="@string/title_activity_do_transfer"
android:name="com.android.insecurebankv2.DoTransfer"
android:exported="true"/>
<activity
android:label="@string/title_activity_view_statement"
android:name="com.android.insecurebankv2.ViewStatement"
android:exported="true"/>
<activity
android:label="@string/title_activity_change_password"
android:name="com.android.insecurebankv2.ChangePassword"
android:exported="true"/>
<provider
android:name="com.android.insecurebankv2.TrackUserContentProvider"
android:exported="true"
android:authorities="com.android.insecurebankv2.TrackUserContentProvider"/>
2.다음과 같은 명령어를 nox_adb 로 실행시키자 ChangePassword 가 외부에서 호출된 것을 확인하실 수 있습니다! 액티비티 컴포넌트 취약점이 있는 부분은 확인했으니, 이를 활용한 공격으로 까지 이어보겠습니다.
[사용된 명령어]
> nox_adb shell am start com.android.insecurebankv2/com.android.insecurebankv2.ChangePassword
2. 공격 결과
1. 일단 액티비티로 접근은 했지만 Username 값은 저희가 수정할 수 없는것으로 보입니다. Password 만 입력되는 상태라 소스코드가 어떻게 이루어지는지 한번 확인해봐야 겠습니다.
2. ChangePassword 소스코드를 보면 password 란은 (EditText)를 사용해서 저희가 수정이 가능한데 Username은 (TextView)를 사용해서 고정된 값만 적힌것 같습니다. 그리고 username은 intent에 uname이라는 키값으로 전달되는 것같으니 이를 활용해서 다시 adb 명령어를 작성해보겠습니다.
3. 이번엔 --es 설정을 추가하여 uname 이란 변수에 jack 이라는 값을 넣고 전달해주었습니다. 그랬더니 Username 부분에 해당 값이 적힌것을 확인하실 수 있습니다. 그러면 newpass란에는 Test!123$ 라고 적어주고 Change Password 버튼을 눌러보겠습니다!
[사용된 명령어]
> nox_adb shell am start -n com.android.insecurebankv2/com.android.insecurebankv2.ChangePassword --es uname jack
4. 비밀번호가 성공적으로 바뀐것을 확인하실 수 있습니다!
3. 대응 방안
1. exported="false" 설정
> 정말 필요한 경우가 아니라면 명시적으로 exported="false" 설정을 해두는 것이 보안상 안전합니다.
2. 커스텀 권한 설정
> 만약exported="true" 설정을 꼭 써야하는 상황이라면, 액티비티에 퍼미션(권한)을 추가한 후 특정 권한을 가진 겨웅에만 실행되도록 해야합니다. 다음과 같이 액티비티 설정을 수정해야합니다.
<activity
android:name="com.android.insecurebankv2.DoTransfer"
android:exported="true"
android:permission="com.android.insecurebankv2.PERMISSION_ACCESS_CUSTOM">
</activity>