# Drozer Tutorial {{#include ../../../banners/hacktricks-training.md}} ## 테스트할 APK - [Sieve](https://github.com/mwrlabs/drozer/releases/download/2.3.4/sieve.apk) (mrwlabs에서 제공) - [DIVA](https://payatu.com/wp-content/uploads/2016/01/diva-beta.tar.gz) **이 튜토리얼의 일부는** [**Drozer 문서 pdf**](https://labs.withsecure.com/content/dam/labs/docs/mwri-drozer-user-guide-2015-03-23.pdf)**에서 발췌되었습니다.** ## 설치 호스트 내에 Drozer Client를 설치합니다. [최신 릴리스](https://github.com/mwrlabs/drozer/releases)에서 다운로드하세요. ```bash pip install drozer-2.4.4-py2-none-any.whl pip install twisted pip install service_identity ``` [최신 릴리스](https://github.com/mwrlabs/drozer/releases)에서 drozer APK를 다운로드하고 설치하세요. 현재 버전은 [이것](https://github.com/mwrlabs/drozer/releases/download/2.3.4/drozer-agent-2.3.4.apk)입니다. ```bash adb install drozer.apk ``` ### 서버 시작하기 Agent는 포트 31415에서 실행되고 있으며, Drozer Client와 Agent 간의 통신을 설정하기 위해 [포트 포워딩](https://en.wikipedia.org/wiki/Port_forwarding)을 해야 합니다. 다음은 이를 수행하는 명령어입니다: ```bash adb forward tcp:31415 tcp:31415 ``` 마지막으로, **애플리케이션**을 **실행**하고 하단의 "**ON**" 버튼을 누릅니다. ![](<../../../images/image (459).png>) 그리고 연결합니다: ```bash drozer console connect ``` ## Interesting Commands | **Commands** | **Description** | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Help MODULE** | 선택한 모듈의 도움말을 보여줍니다. | | **list** | 현재 세션에서 실행할 수 있는 모든 drozer 모듈의 목록을 보여줍니다. 이는 적절한 권한이 없는 모듈은 숨깁니다. | | **shell** | 에이전트의 컨텍스트에서 장치에서 대화형 Linux 셸을 시작합니다. | | **clean** | Android 장치에서 drozer가 저장한 임시 파일을 제거합니다. | | **load** | drozer 명령이 포함된 파일을 로드하고 순차적으로 실행합니다. | | **module** | 인터넷에서 추가 drozer 모듈을 찾아 설치합니다. | | **unset** | drozer가 생성하는 모든 Linux 셸에 전달하는 이름이 지정된 변수를 제거합니다. | | **set** | drozer가 생성하는 모든 Linux 셸에 환경 변수로 전달될 값을 변수에 저장합니다. | | **shell** | 에이전트의 컨텍스트에서 장치에서 대화형 Linux 셸을 시작합니다. | | **run MODULE** | drozer 모듈을 실행합니다. | | **exploit** | Drozer는 장치에서 실행할 수 있는 익스플로잇을 생성할 수 있습니다. `drozer exploit list` | | **payload** | 익스플로잇에는 페이로드가 필요합니다. `drozer payload list` | ### Package **이름**의 일부로 필터링하여 패키지의 **이름**을 찾습니다: ```bash dz> run app.package.list -f sieve com.mwr.example.sieve ``` **패키지의 기본 정보:** ```bash dz> run app.package.info -a com.mwr.example.sieve Package: com.mwr.example.sieve Process Name: com.mwr.example.sieve Version: 1.0 Data Directory: /data/data/com.mwr.example.sieve APK Path: /data/app/com.mwr.example.sieve-2.apk UID: 10056 GID: [1028, 1015, 3003] Shared Libraries: null Shared User ID: null Uses Permissions: - android.permission.READ_EXTERNAL_STORAGE - android.permission.WRITE_EXTERNAL_STORAGE - android.permission.INTERNET Defines Permissions: - com.mwr.example.sieve.READ_KEYS - com.mwr.example.sieve.WRITE_KEYS ``` **Manifest** 읽기: ```bash run app.package.manifest jakhar.aseem.diva ``` **패키지의 공격 표면**: ```bash dz> run app.package.attacksurface com.mwr.example.sieve Attack Surface: 3 activities exported 0 broadcast receivers exported 2 content providers exported 2 services exported is debuggable ``` - **활동**: 아마도 활동을 시작하고 이를 실행하는 것을 방지해야 하는 어떤 종류의 권한을 우회할 수 있을 것입니다. - **콘텐츠 제공자**: 아마도 개인 데이터에 접근하거나 일부 취약점(SQL Injection 또는 Path Traversal)을 악용할 수 있을 것입니다. - **서비스**: - **디버깅 가능**: [자세히 알아보기](#is-debuggeable) ### 활동 내보내기된 활동 구성 요소의 “android:exported” 값은 AndroidManifest.xml 파일에서 **“true”**로 설정됩니다: ```html ``` **내보낸 활동 목록**: ```bash dz> run app.activity.info -a com.mwr.example.sieve Package: com.mwr.example.sieve com.mwr.example.sieve.FileSelectActivity com.mwr.example.sieve.MainLoginActivity com.mwr.example.sieve.PWList ``` **Start activity**: 아마도 활동을 시작하고 이를 시작하는 것을 방지해야 하는 어떤 종류의 권한 부여를 우회할 수 있을 것입니다. ```bash dz> run app.activity.start --component com.mwr.example.sieve com.mwr.example.sieve.PWList ``` **adb**를 사용하여 내보낸 활동을 시작할 수도 있습니다: - PackageName은 com.example.demo입니다. - Exported ActivityName은 com.example.test.MainActivity입니다. ```bash adb shell am start -n com.example.demo/com.example.test.MainActivity ``` ### Content Providers 이 게시물은 여기에서 너무 커서 **당신은** [**여기에서 별도의 페이지로 접근할 수 있습니다**](exploiting-content-providers.md). ### Services 내보낸 서비스는 Manifest.xml 내에서 선언됩니다: ```html ``` 코드 **check**에서 **`handleMessage`** 함수를 확인하세요. 이 함수는 **message**를 **receive**합니다: ![](<../../../images/image (82).png>) #### List service ```bash dz> run app.service.info -a com.mwr.example.sieve Package: com.mwr.example.sieve com.mwr.example.sieve.AuthService Permission: null com.mwr.example.sieve.CryptoService Permission: null ``` #### **서비스와 상호작용** ```bash app.service.send Send a Message to a service, and display the reply app.service.start Start Service app.service.stop Stop Service ``` #### 예제 `app.service.send`에 대한 **drozer** 도움말을 확인하세요: ![](<../../../images/image (1079).png>) 먼저 "_msg.what_" 안의 데이터를 전송한 다음, "_msg.arg1_"과 "_msg.arg2_"를 전송합니다. **어떤 정보가 사용되고 있는지** 코드 안에서 확인해야 합니다.\ `--extra` 옵션을 사용하면 "_msg.replyTo_"에 의해 해석되는 내용을 전송할 수 있으며, `--bundle-as-obj`를 사용하면 제공된 세부정보로 객체를 생성합니다. 다음 예제에서: - `what == 2354` - `arg1 == 9234` - `arg2 == 1` - `replyTo == object(string com.mwr.example.sieve.PIN 1337)` ```bash run app.service.send com.mwr.example.sieve com.mwr.example.sieve.AuthService --msg 2354 9234 1 --extra string com.mwr.example.sieve.PIN 1337 --bundle-as-obj ``` ![](<../../../images/image (647).png>) ### Broadcast Receivers **Android 기본 정보 섹션에서 Broadcast Receiver가 무엇인지 확인할 수 있습니다**. 이 Broadcast Receivers를 발견한 후에는 **코드를 확인**해야 합니다. **`onReceive`** 함수에 특별히 주의하세요. 이 함수는 수신된 메시지를 처리합니다. #### **모든** broadcast receivers 감지 ```bash run app.broadcast.info #Detects all ``` #### 앱의 브로드캐스트 수신기 확인 ```bash #Check one negative run app.broadcast.info -a jakhar.aseem.diva Package: jakhar.aseem.diva No matching receivers. # Check one positive run app.broadcast.info -a com.google.android.youtube Package: com.google.android.youtube com.google.android.libraries.youtube.player.PlayerUiModule$LegacyMediaButtonIntentReceiver Permission: null com.google.android.apps.youtube.app.common.notification.GcmBroadcastReceiver Permission: com.google.android.c2dm.permission.SEND com.google.android.apps.youtube.app.PackageReplacedReceiver Permission: null com.google.android.libraries.youtube.account.AccountsChangedReceiver Permission: null com.google.android.apps.youtube.app.application.system.LocaleUpdatedReceiver Permission: null ``` #### Broadcast **상호작용** ```bash app.broadcast.info Get information about broadcast receivers app.broadcast.send Send broadcast using an intent app.broadcast.sniff Register a broadcast receiver that can sniff particular intents ``` #### 메시지 보내기 이 예제에서는 [FourGoats apk](https://github.com/linkedin/qark/blob/master/tests/goatdroid.apk) Content Provider를 악용하여 사용자의 허가 없이 **임의의 SMS**를 비프리미엄 목적지로 **보낼 수 있습니다**. ![](<../../../images/image (415).png>) ![](<../../../images/image (573).png>) 코드를 읽어보면, "_phoneNumber_"와 "_message_" 매개변수를 Content Provider에 전송해야 합니다. ```bash run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --component org.owasp.goatdroid.fourgoats.broadcastreceivers SendSMSNowReceiver --extra string phoneNumber 123456789 --extra string message "Hello mate!" ``` ### Is debuggeable 생산용 APK는 절대 디버깅 가능해서는 안 됩니다.\ 이것은 **자바 디버거**를 실행 중인 애플리케이션에 연결하고, 런타임에서 검사하고, 중단점을 설정하고, 단계별로 진행하며, 변수 값을 수집하고 심지어 변경할 수 있음을 의미합니다. [InfoSec institute has an excellent article](../exploiting-a-debuggeable-applciation.md) on digging deeper when you application is debuggable and injecting runtime code. 애플리케이션이 디버깅 가능할 때, 매니페스트에 나타납니다: ```xml