본문 바로가기

security/reverse engineering

[악성 앱 분석] InsecureBankv2 분석

insecurebankv2의 공격면을 drozer에게 요청했다. 공격벡터로 작용 가능한 구간이 Activity, broadcast receiver, content provider 이므로, 이것들을 각각 분석한다.

공격 벡터 가능한 것들: 5개의 액티비티(화면),1개의 broadcast receiver, 1개의 content provider(database objects), 1개의 서비스(backgroud worker)

is debuggable 출력: 제시된 벡터들은 디버깅이 가능하므로, 디버거가 해당 프로세스에 접근해서 adb를 통해 code를 진행해볼 수 있다. (*앱의 코드에 임의로 코드를 주입 및 변조해서 공격 가능)

 

1. Flawed Broadcast Receivers

broadcast: 다른 앱이 관심을 가질만한 이벤트가 발생할 때, broadcast 전송으로 해당 상황을 앱에 알린다.

앱은 특정 broadcast를 수신하도록 등록할 수 있고, broadcast가 전송되면 시스템이해당 broadcast 수신을 등록한 앱에 broadcast를 자동으로 라우팅한다. 일반적으로 앱 전체에 걸쳐, 그리고 일반 사용자 플로우 외부에서 메시징 시스템으로 사용될 수 있다.

broadcast receiver: manifest에 수신자를 선언하거나, 컨텍스트에 등록해놓을 수 있다. 

참고: 브로드캐스트 개요  |  Android 개발자  |  Android Developers

 

drozer로 간단히 확인해본 결과, 1개의 broadcast receiver가 노출되어있다.

 

broadcast 정보를 intent filter 포함하여 출력해보니, broadcast 권한이 설정되지 않아있고, theBroadcast 액션이 intent로 설정되어있었다. 또한 broadcast 발생 시 수행하는 동작이 MyBroadCastReceiver에 설정되어있었음을 알 수 있었다.

 

jadx-gui로  InsecureBankv2.apk를 열어준 후 AndroidManifest.xml파일을 확인해보면 broadcast receiver가 선언되어있고, exported값이 true로 되어있고, theBroadcast 액션을 브로드캐스트 설정되어있다. drozer를 통해 확인했던 것이 그대로 코드로 구성되어있었다.

해석 : 어플리케이션 외부에서 intent를 받음 → theBroadcast 액션 발생 → MyBroadCastReceiver 클래스 내의 작업 실행

 

MyBroadCastReceiver 클래스 코드를 확인해보면, 2개의 key(phonenumber, newpass)로 지정된 문자열을 인텐트로부터 받아서 처리한다. 전달받은 phonenumber의 문자열이 null이 아니면, 비밀번호를 newpass의 문자열로 갱신한다. 

 

[참고]위에서의 intent는 ChangePassword클래스 내에서 smsIntent에 지정된다. 

 

broadcast receiver가 노출되어있으므로, 외부 앱인 drozer에서 실행시켜 볼 수 있다. (adb에서 그냥 보내도 되는 것 같다.) intent를 날렸을 때, 결과를 logcat으로 보는 것 같은데, 두개가 동시에 실행이 안된다.. 

분명 broacast실행까지는 된 것 같은데 결과가 안나온다,,, drozer가 연결한 기기명을 보면 Nox와 연결한 건 분명한데, 왜 안되는 건지 모르겠다.

 

대응방안: AndroidManifest.xml에서 broadcast receiver의 exported가 true로 되어있어서 취약점으로 작용한 것이므로, exported를 false로 설정해준다, 

 

 

참고: 취약점별 상세 진단 - Broadcast Receiver 결합 (tistory.com), Vulnerable Android Broadcast Receivers (oldbam.github.io), [안드로이드 모바일 앱 취약점 진단] 인시큐어뱅크 취약점 진단 실습 - 취약한 브로드캐스트 리시버 취약점 : 네이버 블로그 (naver.com)

 

 

2. Intent Sniffing and Injection

Intent Sniffing은 노출된 intent를 확인한다. drozer에 app.broadcast.sniff라는 모듈이 존재한다. 

너무 대기만 해서 강제 종료했다..

 

3. Weak Authorization mechanism

로그인 후에 보여질 activity가 호출되었으므로 인증에 취약한 부분.

 

 

 

4. Local Encryption issues

평문 암호화

 

 

5. Vulnerable Activity Components

접근 가능한 Activity들을 확인해보았다.

앱 파악을 위해 실행해 봤을 때 접근 가능했던 대부분의 액티비티가 기본으로 접근 가능한 것으로 설정되어있었다.

문제는 LoginActivity를 제외한 액티비티들은 로그인 성공 후 접근 가능한 액티비티들이라는 점이다. 

접근 가능한 Activity 목록
LoginActivity 처음에 열리는 화면으로 당연히 항상 포함된다.
PostLogin 로그인 성공 후의 화면
DoTransfer insecurebankv2 앱에서 로그인 성공한 뒤 선택할 수 있는 기능들
ViewStatement
ChangePassword

 

이 명령어는 적절한 Intent를 백그라운드에서 만들어서 startActivity를 통해 시스템에 전달하기 때문에 실행되는 것이다.

원래 인증과정 이후에 접근가능한 액티비티에, 인증을 우회하여 접근가능하다.  

물론 Username은 수정 불가능하게 설정되어있어서 Username정보만으로 패스워드 변경은 불가능하다. 

다른 액티비티들에 대해서도 가능하다.

6. Root Detection and Bypass

7. Emulator Detection and Bypass

8. Insecure Content Provider access

한개의 content provider 공격 면을 확인 가능.

*content provider: 응용 프로그램들 사이에서 데이터를 공유하는 유일한 방법. 데이터 베이스에 있는 정보를  URI로 공유하므로, 데이터베이스에 접근하기 위해 URI정보가 반드시 필요하다.

 

content provider가 사용하는 URI 정보를 검색해보았다.(아래의 명령어와의 차이는? 이건 전체고, 아래꺼는 그 중에서도 상세하게 쿼리가  가능한 여부를 구분해준다.)

접근 가능한 uri들. Data Leackage발생. 2개니까 다 해보자.

사용자 name을 확인가능한 것 같다.

'로 쿼리를 날려보니, 위에서 출력된 것들이 name이라는 것을 정확히 알 수 있었다. 

해당 테이블에 있는 내용을 모두 출력해보았으나, id와 name이라는 columns만 존재하는 테이블이었다.

 

위에서 확인한 URI로 접근 가능한 주소 목록을 출력해보았다. 

 

SQL injection과  directory traversal에 취약한 여부를 확인해보았다.

위에서 확인 했던 접근가능한 URI에 SQL injection이 가능하다고 출력해준다. 

Insecure Webview implementation

Weak Cryptography implementation

Application Patching

/////

Sensitive Information in Memory

Insecure Logging mechanism

Android Pasteboard vulnerability

Application Debuggable

Android keyboard cache issues

Android Backup vulnerability

Runtime Manipulation

Insecure SDCard storage

Insecure HTTP connections

Parameter Manipulation

Hardcoded secrets

Username Enumeration issue

Developer Backdoors

Weak change password implementation

 

Frida - Hooking