[목차]

 

 

1. Flawed Broadcast Receivers (취약한 브로드캐스트 리시버)

    - 브로드캐스트 리시버란

    - 취약점 설명

    - 취약 유무 확인 방법

    - ADB를 통한 컴포넌트 호출 실습

    - Drozer을 통한 컴포넌트 호출 실습

           - Drozer란

           - Drozer 환경 구성

           - Drozer 기동

           - No module named drozer.cli.console 이슈 해결

           - 컴포넌트 호출 실습

    - 대응 방안

           - ADB와 Drozer 차이

 

 


 

 

 

[Flawed Broadcast Receivers]

 

 

 

1. 브로드캐스트 리시버란

: 말 그대로 [안내 방송 수신기]

 

안드로이드 시스템은

안드로이드 앱에게

특정 조건이나 상황이 되면

intent라는 메시지를 보내는데

 

해당 메시지(intent)를

안드로이드 앱 안에 있는

브로드캐스트 리시버가

받아 처리하는 역할을 한다.

 

예로

안드로이드 시스템에서 '배터리 부족'을 감지한 경우,

(1) 시스템은 배터리 부족 메시지(intent)를

기동 중인 각 앱에게 전송하고

(2) 앱 내부의 브로드캐스트 리시버가 이를 전달받아

필요한 동작('충전기를 연결하세요' 등의 메시지 팝업 오픈)을

수행하는 것

 

상황에 따라 메시지(intent)는 제 각각이며

처리해야 하는 동작 또한 제 각각이다.

 

이미지 출처 : 보안프로젝트

 

참고로

위 이미지만 보면 마치

메시지(intent)가 전송되는 방향이

일방적으로 시스템에서 앱 쪽으로만

이루어지는 것 같지만

 

앱에서 특정 메시지를 시스템으로 보내

시스템에서 해당 메시지를

브로드캐스트 리시버로 전송하고

브로드캐스트 리시버에서 다시 시스템으로

전송하는 등의 양방향 작용이 이루어진다.

 

이미지 출처 : 보안프로젝트
.

 


 

 

 

2. 취약점 설명

 

 

위 이미지를 보면

한 브로드캐스트 리시버의 동작 기능 안에

'비밀번호 변경 기능'이 있고

 

해당 동작 기능을 사용할 수 있는 것은

빨간색으로 표시된 app만 가능하다.

 

하지만

'비밀번호 변경 기능'이 있는

브로드캐스트 리시버가 노출되어

접근제어가 되지 않는 경우

 

인가되지 않은 파란색 app들 혹은

인가되지 않은 사용자들이 강제적으로

빨간색 비밀번호 변경 메시지(intent)를

시스템 측에 보낼 수 있게 되고

 

이를 수신한 브로드캐스트 리시버는

해당 명령을 수행하게 되어

결과적으로 해당 메시지를 요청한

임의의 앱 혹은 임의의 사용자가

비밀번호 변경 기능을 사용할 수 있게 된다.

 

 

 

 

 

 

 

3. 취약 유무 확인 방법

 

 

(1) AndroidManifest.xml에 있는 <Receiver> 컴포넌트 설정 점검

: 안드로이드 스튜디오에서 InsecurebankV2 프로젝트를 열고

main 폴더 내 AndroidManifest.xml 파일에 접근해 보면

하단에 [receiver] 컴포넌트가 정의되어 있다.

 

 

이 중

exported 값이 true 면

다른 application으로부터 intent를 받을 수 있고

 

false 면 같은 application 또는

같은 UID를 가진 application 으로부터 만

intent를 받을 수 있는데

 

인시큐어뱅크의 경우

exported 값이 true로 되어있어

다른 외부 개체로부터 intent를 받을 수 있는

상황이기에 [취약한 브로드캐스트 리시버]

취약점이 있는 상황으로 볼 수 있다.

 

 

 

 

 

4. ADB를 통한 컴포넌트 호출 실습

 

(1) Receiver 컴포넌트가 구현된 해당 Class의 메소드 기능 점검

: reveiver 컴포넌트에 어떤 기능이 있는지 확인해 본다.

 

우선 컴포넌트의 구현부인

[MyBroadCastReceiver] class로 가능 방법은

해당 클래스 명에서 우 클릭 > Go To > Declaration or Usages 선택

 

 

해당 Class를 살펴본다.

 

안드로이드 시스템에서 메시지(intent)를 받으면

receiver 컴포넌트의 구현부인

MyBroadCastReceiver Class 내

onReceive() 메소드가 호출되는데

 

메시지(intent)로 전달되는 인자를 보면

phonenumber와 newpass 두 종류가 있고

 

조건에 따라

phn(phonenumber) 값이 null이 아니라면

관련 조건문(새로운 패스워드 생성)이 수행된다.

 

(근데 password 변수

'superSecurePassword'는 암호 키 같은데

저렇게 노출시켜도 되는 건가?

아마 관련 취약점이 있을 듯)

 

 

 

 

(2) ADB를 사용한 컴포넌트 호출 실습

 

실습 환경 :

녹스, 인시큐어뱅크 앱, 인시큐어뱅크 서버,

안드로이드 스튜디오 기동 후 터미널에서

adb를 통해 실습 진행

 

실습 과정 :

adb로 인시큐어뱅크의 리시버 컴포넌트에

Intent를 전달해 보고 전달 가능 여부 확인,

onReceive() 메소드 조건문에 맞는 인자 전달 시

수행 가능 여부 확인

 

 

(3-1) adb 명령어 확인

C:> adb shell am broadcast -a TAKUDADDY -n com.android.insecurebankv2/.MyBroadCastReceiver
 

'adb shell am broadcast [Intent]'

명령어로 Intent(메시지)를 broadcast에 전달

 

-a 옵션 뒤에는 메시지(Action)을 입력하고

해당 Action을 가지고 있는 Intent가

브로드캐스트로 전달된다.

 

-n 옵션 뒤에는 전송할 패키지/컴포넌트명을 입력하는데

패키지 명은 AndroidManifes.xml 파일 상단에서 확인 가능하고

 

 

컴포넌트 명은

각 컴포넌트 상단에서 확인 가능

 

 

 

(3-2) 컴포넌트 호출 실습 1

이제 adb 쉘로 위 명령어를 입력한 뒤

 

 

로그를 살펴보면

 

phn(phonenumber) 값이 null이기 때문에

else 구문이 실행되었는데 우선

호출은 정상적으로 이루어지고 있다.

 

 

 

 

(3-3) 컴포넌트 호출 실습 2

호출이 정상적으로 이루어졌으니

이번에는 조건문에 맞는 인자를 추가해

전송하는 실습을 해본다.

 

adb 명령어에 인자를 추가하는 명령어

C:> adb shell am broadcast -a takudaddy -n com.android.insecurebankv2/.MyBroadCastReceiver --es phonenumber 4444 --es newpass asdf
 
 

--es 뒤에 변수 인자명(phonenumber)과 인자 값(4444)

--es 뒤에 변수 인자명(newpass)과 인자 값(asdf)

 

 

이렇게 Intent를 전송하면

phn 변숫값은 4444이고

newpass 변숫값은 asdf로

세팅이 되겠다.

 

 

위 명령어를 실행시킨 뒤

 

로그를 살펴보면

 

조건에 부합하여 정상 수행되었다.

 

 

 


 

 

 

4. Drozer를 통한 컴포넌트 호출 실습

 

 

(1) Drozer 란

FSecureLABS에서 개발한

안드로이드 동적 분석 프레임워크로

PC와 디바이스 사이의 Agent를 통해

앱의 취약성을 점검할 수 있는 도구

(한마디로 취약점 스캐너!)

 

Drozer 전에 Mercury라는 이름으로 사용되었었고

안드로이드 앱의 보안성을 테스트하기 위한

표준으로 불렸을 만큼 오랜 명성을 가지고 있었지만

현재는 추가적인 개발을 중단한 상태

 

 

 

(2) Drozer 환경 구성

두 가지 파일

ㄱ. HOST 용 'drozer-2.4.4_win32_msi'

ㄴ. 녹스(또는 단말기) 용 'drozer-agent.apk'

이 필요하며 (https://labs.withsecure.com/tools/drozer/)

 

 

HOST 용 파일의 경우, 윈도우에서

악성파일로 분류되어 거르기 때문에

실시간 검사 기능을 잠시 꺼두고

내려받아 설치까지 진행한다.

 

 

- HOST 파일 설치

구동 시 파이썬 2.7 버전을 사용해야 하니

설치 과정에서 설치 경로가

python38\Scripts가 아닌

Python27\Scripts로 변경해 주고 설치 진행!

 

 

* 주의사항

설치 과정에서 위 이미지처럼

파이썬 3.8, 파이썬 2.7 경로

둘 다 체크되어 있는 경우

agent 연결시 문제가 발생하게 되는데

관련 부분은 아래 기술해 둠

 

정상 작동 여부 확인

 

설치 후 관련 모듈을 추가로 설치한다.

C:> pip install protobuf pyOpenSSL twisted service_identity
 

 

 

- 녹스 파일 설치

녹스에는 에이전트 파일을

드래그 앤 드롭 또는

 

 

adb로 설치해 준다.

(C: > adb install 패키지)

 

 

 

 

(3) Drozer 기동

녹스에서 drozer 앱을 실행시킨 뒤

앱 하단의 OFF 버튼을 클릭하여

ON 시키면

 

31415 포트가 활성화되고

 

 

터미널에서 adb를 통해 포트포워딩을 시켜준다.

 

 

녹스의 포트 31415(drozer-agent)을

31415로 포워딩

 

 

agent 연결을 시도하면

에러!

 

 

 

(4) No module named drozer.cli.console 에러 해결 방법

해당 에러 발생 원인은

HOST 파일 설치 과정 중

설치 경로가 파이썬 2/3 버전

둘 다로 설정되었기 때문!

(내부 모듈 경로를 못찾는다)

 

다 싹 지우고 재설치 하는데

이번에는 꼭 3버전 경로를

unavailable로 변경 후

설치를 진행해 준다.

 

 

다시 콘솔에 접속해 보면

 

해결!

Drozer 세팅 완료!

 

 

 

 

(5) 컴포넌트 호출 실습

ㄱ. 우선 공격포인트가 될 수 있는

attack surface가 있는지 스캔!

dz> run app.package.attacksurface com.android.insecurebankv2
 

결과를 살펴보면

5개의 activities가 노출

1개의 브로드캐스터 리시버 노출

1개의 콘텐트 프로바이더 노출

마지막으로 해당 앱은

디버깅이 가능하다.

 

 

ㄴ. 지금 주목할 것은 브로드캐스터 리시버,

이번에는 브로드캐스트 정보를 스캔!

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

 

결과를 보면

소스코드에서 봤던 대로

MyBroadCastReceiver가 확인되었으며

해당 리시버의 권한은 null

 

여기서

Permission: null

의 의미는

 

권한이 없다가 아닌

권한 설정이 안 되어 있어

누구나 호출이 가능하다는 뜻

 

 

 

ㄷ. 호출 실습

- 인자 없이 브로드캐스트 리시버

컴포넌트를 호출해 보면

dz> run app.broadcast.send --component com.android.insecurebankv2 com.android.insecurebankv2.MyBroadCastReceiver
 

 

else 조건이 성립되어

로그에 뜨며

 

 

 

- 인자를 추가해 호출해 보면

dz> run app.broadcast.send --component com.android.insecurebankv2 com.android.insecurebankv2.MyBroadCastReceiver --extra string phonenumber 7777 --extra string newpass takudaddy
 

 

if 참 구문이 정상적으로 실행되어

비밀번호가 변경되었다.

 

 

 


 

 

 

[대응방안]

 

 

1. AndroidManifest.xml 내

reciever 컴포넌트의 설정값을

false로 변경

 

 

코드 수정 후 빌드

 

 

이 상태로 곧바로 빌드 하면

에러가 발생하는데

 

 

위 android 부분을 삭제

 

빌드를 진행한 뒤

drozer로 취약 여부를 점검해 보면

 

빌드가 정상적으로 이루어져

브로드캐스트 리시버가 노출되어 있지

않다.

 

하지만 이 상태에서

adb로 컴포넌트 호출을 시도하는 경우

 

 

여전히 정상 호출이 가능한 것으로 확인되는데

이유는 바로 adb 툴 특성에 있다.

 

 

 

[adb와 drozer 차이]

adb는 개발자들이 사용하는 툴이기 때문에

특성상 시스템의 권한을 가지고 있어

컴포넌트 설정값이 true/false 상관없이

호출이 가능하다는 특징이 있다.

 

drozer를 통해 추가로

진단 실습을 한 이유가 바로 이 때문인데

취약 여부 판단 기준은 adb가 아닌

drozer의 결괏값이 되어야 하며

 

리시브 컴포넌트 설정을 false로

해 놓고 drozer에서 attacksurface에

리시버 관련 항목이 노출되지 않았다면

이 취약점 항목은 양호로 가져가면 된다.

 

 


 

2. 설정값을 true로 해야 하는 경우

별도의 permission 속성을 통한

권한으로 접근제어

 

728x90

+ Recent posts