hacktricks/mobile-pentesting/android-app-pentesting/android-applications-basics.md

32 KiB

Android Applications Basics

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Try Hard Security Group

{% embed url="https://discord.gg/tryhardsecurity" %}


Android Security Model

두 개의 레이어가 있습니다:

  • OS, 설치된 애플리케이션을 서로 격리합니다.
  • 애플리케이션 자체, 개발자가 특정 기능을 노출하고 애플리케이션 기능을 구성할 수 있게 합니다.

UID Separation

각 애플리케이션은 특정 사용자 ID가 할당됩니다. 이는 앱 설치 중에 이루어지며, 앱은 자신의 사용자 ID가 소유한 파일이나 공유 파일과만 상호작용할 수 있습니다. 따라서 앱 자체, OS의 특정 구성 요소 및 루트 사용자만 앱 데이터를 접근할 수 있습니다.

UID Sharing

두 개의 애플리케이션이 동일한 UID를 사용하도록 구성될 수 있습니다. 이는 정보를 공유하는 데 유용할 수 있지만, 그 중 하나가 손상되면 두 애플리케이션의 데이터가 모두 손상됩니다. 그래서 이러한 행동은 권장되지 않습니다.
동일한 UID를 공유하려면, 애플리케이션은 매니페스트에서 동일한 android:sharedUserId 값을 정의해야 합니다.

Sandboxing

안드로이드 애플리케이션 샌드박스각 애플리케이션을 별도의 사용자 ID로 별도의 프로세스로 실행할 수 있게 합니다. 각 프로세스는 자신의 가상 머신을 가지고 있어, 앱의 코드는 다른 앱과 격리되어 실행됩니다.
안드로이드 5.0(L)부터 SELinux가 시행됩니다. 기본적으로 SELinux는 모든 프로세스 상호작용을 거부하고, 그들 간의 예상되는 상호작용만 허용하는 정책을 생성합니다.

Permissions

애플리케이션을 설치할 때 권한을 요청하는 경우, 앱은 AndroidManifest.xml 파일의 uses-permission 요소에 구성된 권한을 요청하는 것입니다. uses-permission 요소는 name 속성 내에서 요청된 권한의 이름을 나타냅니다. 또한 maxSdkVersion 속성이 있어, 지정된 버전보다 높은 버전에서는 권한 요청을 중지합니다.
안드로이드 애플리케이션은 처음에 모든 권한을 요청할 필요는 없으며, **동적으로 권한을 요청할 수 있지만 모든 권한은 **매니페스트에 선언되어야 합니다.

앱이 기능을 노출할 때, 지정된 권한을 가진 앱만 접근할 수 있도록 제한할 수 있습니다.
권한 요소는 세 가지 속성을 가집니다:

  • 권한의 이름
  • 관련 권한을 그룹화할 수 있는 permission-group 속성.
  • 권한이 부여되는 방식을 나타내는 protection-level. 네 가지 유형이 있습니다:
  • Normal: 앱에 알려진 위협이 없을 때 사용됩니다. 사용자가 승인할 필요가 없습니다.
  • Dangerous: 요청하는 애플리케이션에 상승된 접근 권한을 부여하는 권한을 나타냅니다. 사용자에게 승인을 요청합니다.
  • Signature: 구성 요소를 내보내는 것과 동일한 인증서로 서명된 앱만 권한을 부여받을 수 있습니다. 이는 가장 강력한 보호 유형입니다.
  • SignatureOrSystem: **구성 요소를 내보내는 것과 동일한 인증서로 서명된 앱이나 시스템 수준 접근 권한으로 실행되는 앱만 권한을 부여받을 수 있습니다.

Pre-Installed Applications

이 앱들은 일반적으로 /system/app 또는 /system/priv-app 디렉토리에서 발견되며, 그 중 일부는 최적화되어 있습니다 (심지어 classes.dex 파일을 찾지 못할 수도 있습니다). 이러한 애플리케이션은 때때로 너무 많은 권한으로 실행되고 있기 때문에 확인할 가치가 있습니다 (루트 권한으로).

  • AOSP (Android OpenSource Project) ROM과 함께 제공되는 것들
  • 장치 제조업체에 의해 추가된 것들
  • 전화 제공업체에 의해 추가된 것들 (그들로부터 구매한 경우)

Rooting

물리적 안드로이드 장치에 루트 접근을 얻기 위해 일반적으로 **1개 또는 2개의 취약점을 악용해야 합니다, 이는 장치버전특정입니다.
익스플로잇이 성공하면, 일반적으로 리눅스 su 바이너리가 사용자의 PATH 환경 변수에 지정된 위치인 /system/xbin에 복사됩니다.

su 바이너리가 구성되면, 다른 안드로이드 앱이 su 바이너리와 인터페이스하여 루트 접근 요청을 처리합니다. 예를 들어 SuperuserSuperSU (Google Play 스토어에서 사용 가능).

{% hint style="danger" %} 루팅 과정은 매우 위험하며 장치를 심각하게 손상시킬 수 있습니다. {% endhint %}

ROMs

커스텀 펌웨어를 설치하여 OS를 교체하는 것이 가능합니다. 이를 통해 오래된 장치의 유용성을 확장하거나 소프트웨어 제한을 우회하거나 최신 안드로이드 코드에 접근할 수 있습니다.
OmniROMLineageOS는 사용하기에 가장 인기 있는 두 가지 펌웨어입니다.

커스텀 펌웨어를 설치하기 위해 장치를 루팅할 필요는 항상 없습니다. 일부 제조업체는 잘 문서화되고 안전한 방식으로 부트로더 잠금을 해제하는 것을 허용합니다.

Implications

장치가 루팅되면, 어떤 앱이든 루트로 접근을 요청할 수 있습니다. 악의적인 애플리케이션이 이를 얻으면 거의 모든 것에 접근할 수 있으며, 전화기를 손상시킬 수 있습니다.

Android Application Fundamentals

  • 안드로이드 애플리케이션의 형식은 _APK 파일 형식_으로 언급됩니다. 본질적으로 ZIP 파일입니다 (파일 확장자를 .zip으로 변경하면 내용을 추출하고 볼 수 있습니다).
  • APK 내용 (포괄적이지 않음)
  • AndroidManifest.xml
  • resources.arsc/strings.xml
  • resources.arsc: 이진 XML과 같은 미리 컴파일된 리소스를 포함합니다.
  • res/xml/files_paths.xml
  • META-INF/
  • 여기에서 인증서가 위치합니다!
  • classes.dex
  • 기본적으로 애플리케이션이 실행하는 컴파일된 Java (또는 Kotlin) 코드를 나타내는 Dalvik 바이트코드를 포함합니다.
  • lib/
  • CPU 아키텍처에 따라 하위 디렉토리로 분리된 네이티브 라이브러리를 포함합니다.
  • armeabi: ARM 기반 프로세서용 코드
  • armeabi-v7a: ARMv7 및 그 이상의 프로세서용 코드
  • x86: X86 프로세서용 코드
  • mips: MIPS 프로세서 전용 코드
  • assets/
  • 앱에 필요한 다양한 파일을 저장하며, 추가 네이티브 라이브러리나 DEX 파일을 포함할 수 있으며, 때때로 악성 코드 작성자가 추가 코드를 숨기기 위해 사용합니다.
  • res/
  • resources.arsc에 컴파일되지 않은 리소스를 포함합니다.

Dalvik & Smali

안드로이드 개발에서는 Java 또는 Kotlin을 사용하여 앱을 생성합니다. 데스크톱 앱처럼 JVM을 사용하는 대신, 안드로이드는 이 코드를 Dalvik Executable (DEX) 바이트코드로 컴파일합니다. 이전에는 Dalvik 가상 머신이 이 바이트코드를 처리했지만, 이제는 최신 안드로이드 버전에서 Android Runtime (ART)가 이를 처리합니다.

리버스 엔지니어링을 위해 Smali가 중요해집니다. 이는 DEX 바이트코드의 사람이 읽을 수 있는 버전으로, 소스 코드를 바이트코드 명령어로 변환하는 어셈블리 언어처럼 작용합니다. Smali와 baksmali는 이 맥락에서 어셈블리 및 분해 도구를 나타냅니다.

Intents

인텐트는 안드로이드 앱이 구성 요소 간 또는 다른 앱과 통신하는 주요 수단입니다. 이러한 메시지 객체는 앱 간 또는 구성 요소 간에 데이터를 전달할 수도 있으며, HTTP 통신에서 GET/POST 요청이 사용되는 방식과 유사합니다.

따라서 인텐트는 기본적으로 구성 요소 간에 전달되는 메시지입니다. 인텐트는 특정 구성 요소나 앱으로 지향될 수 있으며, 특정 수신자 없이 전송될 수도 있습니다.
간단히 말해 인텐트는 다음과 같이 사용될 수 있습니다:

  • 활동을 시작하여 일반적으로 앱의 사용자 인터페이스를 엽니다.
  • 시스템과 앱에 변경 사항을 알리기 위한 브로드캐스트로 사용됩니다.
  • 백그라운드 서비스와 시작, 중지 및 통신합니다.
  • ContentProviders를 통해 데이터에 접근합니다.
  • 이벤트를 처리하기 위한 콜백으로 사용됩니다.

취약한 경우, 인텐트를 사용하여 다양한 공격을 수행할 수 있습니다.

Intent-Filter

인텐트 필터활동, 서비스 또는 브로드캐스트 수신자가 다양한 유형의 인텐트와 상호작용할 수 있는 방법을 정의합니다. 본질적으로, 이들은 이러한 구성 요소의 기능을 설명하며, 수행할 수 있는 작업이나 처리할 수 있는 브로드캐스트의 종류를 나타냅니다. 이러한 필터를 선언하는 주요 장소는 AndroidManifest.xml 파일 내에 있지만, 브로드캐스트 수신자의 경우 코딩하는 것도 옵션입니다.

인텐트 필터는 카테고리, 작업 및 데이터 필터로 구성되며, 추가 메타데이터를 포함할 수 있습니다. 이 설정은 구성 요소가 선언된 기준에 맞는 특정 인텐트를 처리할 수 있게 합니다.

안드로이드 구성 요소(활동/서비스/콘텐츠 제공자/브로드캐스트 수신자)의 중요한 측면은 그들의 가시성 또는 공개 상태입니다. 구성 요소가 exported 속성이 **true**로 설정되어 있거나 매니페스트에 인텐트 필터가 선언되어 있으면, 해당 구성 요소는 공개로 간주되며 다른 앱과 상호작용할 수 있습니다. 그러나 개발자는 이러한 구성 요소를 명시적으로 비공개로 유지하여 다른 앱과 의도치 않게 상호작용하지 않도록 할 수 있는 방법이 있습니다. 이는 매니페스트 정의에서 exported 속성을 **false**로 설정하여 달성됩니다.

또한, 개발자는 특정 권한을 요구하여 이러한 구성 요소에 대한 접근을 더욱 안전하게 할 수 있는 옵션이 있습니다. permission 속성을 설정하여 지정된 권한을 가진 앱만 구성 요소에 접근할 수 있도록 강제할 수 있으며, 이는 누가 상호작용할 수 있는지에 대한 추가 보안 및 제어 계층을 추가합니다.

<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>

암시적 인텐트

인텐트는 인텐트 생성자를 사용하여 프로그래밍적으로 생성됩니다:

Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));

The Action of the previously declared intent is ACTION_SEND and the Extra is a mailto Uri (the Extra if the extra information the intent is expecting).

이 인텐트는 다음 예와 같이 매니페스트 내에 선언되어야 합니다:

<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

An intent-filter는 메시지를 수신하기 위해 action, datacategory와 일치해야 합니다.

"Intent resolution" 프로세스는 각 메시지를 수신할 앱을 결정합니다. 이 프로세스는 priority attribute를 고려하며, 이는 intent-filter 선언에서 설정할 수 있고, 더 높은 우선 순위를 가진 것이 선택됩니다. 이 우선 순위는 -1000에서 1000 사이로 설정할 수 있으며, 애플리케이션은 SYSTEM_HIGH_PRIORITY 값을 사용할 수 있습니다. 충돌이 발생하면, 사용자가 결정할 수 있도록 "choser" 창이 나타납니다.

Explicit Intents

명시적 인텐트는 타겟으로 하는 클래스 이름을 지정합니다:

Intent downloadIntent = new (this, DownloadService.class):

다른 애플리케이션에서는 이전에 선언된 인텐트에 접근하기 위해 다음을 사용할 수 있습니다:

Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);

Pending Intents

이것은 다른 애플리케이션이 당신의 애플리케이션을 대신하여 행동을 취할 수 있게 해주며, 당신의 앱의 아이덴티티와 권한을 사용합니다. Pending Intent를 구성할 때는 의도와 수행할 행동을 지정해야 합니다. 선언된 의도가 명시적이지 않으면 (어떤 의도가 호출할 수 있는지 선언하지 않음) 악의적인 애플리케이션이 피해자 앱을 대신하여 선언된 행동을 수행할 수 있습니다. 게다가, 행동이 지정되지 않으면, 악의적인 앱은 피해자를 대신하여 어떤 행동이든 할 수 있습니다.

Broadcast Intents

이전의 의도와 달리, 단일 앱만 수신하는 것이 아니라, broadcast intents는 여러 앱이 수신할 수 있습니다. 그러나 API 버전 14부터는 메시지를 수신해야 하는 앱을 지정할 수 있습니다 Intent.setPackage를 사용하여.

또한 브로드캐스트를 보낼 때 권한을 지정할 수도 있습니다. 수신 앱은 해당 권한을 가져야 합니다.

브로드캐스트에는 두 가지 유형이 있습니다: 정상 (비동기) 및 정렬된 (동기). 순서수신자 요소 내에서 구성된 우선 순위에 기반합니다. 각 앱은 브로드캐스트를 처리, 중계 또는 삭제할 수 있습니다.

Context 클래스의 sendBroadcast(intent, receiverPermission) 함수를 사용하여 브로드캐스트보낼 수 있습니다.
또한 **LocalBroadCastManager**의 sendBroadcast 함수를 사용하면 메시지가 앱을 떠나지 않도록 보장합니다. 이를 사용하면 수신자 구성 요소를 내보낼 필요조차 없습니다.

Sticky Broadcasts

이런 종류의 브로드캐스트는 전송된 후 오랜 시간 동안 접근할 수 있습니다.
이것은 API 레벨 21에서 사용 중단되었으며 사용하지 않는 것이 권장됩니다.
이들은 어떤 애플리케이션이 데이터를 엿볼 수 있게 할 뿐만 아니라 수정할 수도 있습니다.

"sticky"라는 단어가 포함된 함수, 예를 들어 sendStickyBroadcast 또는 **sendStickyBroadcastAsUser**를 발견하면, 영향을 확인하고 제거하려고 시도하세요.

안드로이드 애플리케이션에서 딥 링크는 URL을 통해 직접 행동(Intent)을 시작하는 데 사용됩니다. 이는 활동 내에서 특정 URL 스킴을 선언함으로써 이루어집니다. 안드로이드 장치가 이 스킴을 가진 URL에 접근하려고 할 때, 애플리케이션 내에서 지정된 활동이 시작됩니다.

스킴은 AndroidManifest.xml 파일에 선언되어야 합니다:

[...]
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="examplescheme" />
</intent-filter>
[...]

이전 예제의 스킴은 exampleapp://입니다 (또한 **category BROWSABLE**도 주목하세요)

그런 다음, 데이터 필드에서 hostpath를 지정할 수 있습니다:

<data android:scheme="examplescheme"
android:host="example"
/>

웹에서 접근하기 위해 다음과 같은 링크를 설정할 수 있습니다:

<a href="examplescheme://example/something">click here</a>
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>

앱에서 실행될 코드를 찾기 위해, 딥링크로 호출된 액티비티로 가서 onNewIntent 함수를 검색하세요.

HTML 페이지를 사용하지 않고 딥 링크를 호출하는 방법을 배우세요.

AIDL - 안드로이드 인터페이스 정의 언어

**안드로이드 인터페이스 정의 언어 (AIDL)**는 프로세스 간 통신 (IPC)을 통해 안드로이드 애플리케이션에서 클라이언트와 서비스 간의 통신을 용이하게 하기 위해 설계되었습니다. 안드로이드에서는 다른 프로세스의 메모리에 직접 접근하는 것이 허용되지 않기 때문에, AIDL은 객체를 운영 체제가 이해할 수 있는 형식으로 변환하여 서로 다른 프로세스 간의 통신을 쉽게 합니다.

주요 개념

  • 바운드 서비스: 이러한 서비스는 IPC를 위해 AIDL을 사용하여 액티비티나 컴포넌트가 서비스에 바인딩하고 요청을 하며 응답을 받을 수 있게 합니다. 서비스 클래스의 onBind 메소드는 상호작용을 시작하는 데 중요하며, 취약점을 찾기 위한 보안 검토의 중요한 영역으로 표시됩니다.

  • 메신저: 바운드 서비스로 작동하는 메신저는 onBind 메소드를 통해 데이터를 처리하는 데 중점을 두고 IPC를 용이하게 합니다. 이 메소드를 면밀히 검사하여 안전하지 않은 데이터 처리나 민감한 기능의 실행이 있는지 확인하는 것이 중요합니다.

  • 바인더: AIDL의 추상화로 인해 바인더 클래스를 직접 사용하는 경우는 드물지만, 바인더가 서로 다른 프로세스의 메모리 공간 간 데이터 전송을 용이하게 하는 커널 수준의 드라이버 역할을 한다는 것을 이해하는 것이 유익합니다. 더 자세한 이해를 위해 https://www.youtube.com/watch?v=O-UHvFjxwZ8에서 자료를 확인할 수 있습니다.

구성 요소

여기에는 액티비티, 서비스, 브로드캐스트 리시버 및 프로바이더가 포함됩니다.

런처 액티비티 및 기타 액티비티

안드로이드 앱에서 액티비티는 화면과 같으며, 앱의 사용자 인터페이스의 다양한 부분을 보여줍니다. 앱은 여러 개의 액티비티를 가질 수 있으며, 각 액티비티는 사용자에게 고유한 화면을 제공합니다.

런처 액티비티는 앱의 주요 게이트웨이로, 앱 아이콘을 탭할 때 시작됩니다. 이는 앱의 매니페스트 파일에 특정 MAIN 및 LAUNCHER 인텐트와 함께 정의됩니다:

<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

모든 앱이 런처 액티비티가 필요하지는 않으며, 특히 사용자 인터페이스가 없는 백그라운드 서비스와 같은 앱은 그렇습니다.

액티비티는 매니페스트에서 "exported"로 표시하여 다른 앱이나 프로세스에서 사용할 수 있도록 만들 수 있습니다. 이 설정은 다른 앱이 이 액티비티를 시작할 수 있도록 허용합니다:

<service android:name=".ExampleExportedService" android:exported="true"/>

그러나 다른 앱의 활동에 접근하는 것이 항상 보안 위험은 아닙니다. 민감한 데이터가 부적절하게 공유될 경우 우려가 발생하며, 이는 정보 유출로 이어질 수 있습니다.

활동의 생명주기 는 onCreate 메서드로 시작되며, UI를 설정하고 사용자와의 상호작용을 위해 활동을 준비합니다.

애플리케이션 서브클래스

안드로이드 개발에서 앱은 Application 클래스의 서브클래스를 생성할 수 있는 옵션이 있지만, 필수는 아닙니다. 이러한 서브클래스가 정의되면 앱 내에서 가장 먼저 인스턴스화되는 클래스가 됩니다. 이 서브클래스에서 구현된 attachBaseContext 메서드는 onCreate 메서드 이전에 실행됩니다. 이 설정은 나머지 애플리케이션이 시작되기 전에 초기화를 조기에 수행할 수 있게 합니다.

public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Initialization code here
}

@Override
public void onCreate() {
super.onCreate();
// More initialization code
}
}

Services

Services백그라운드 작업자로, 사용자 인터페이스 없이 작업을 실행할 수 있습니다. 이러한 작업은 사용자가 다른 애플리케이션으로 전환하더라도 계속 실행될 수 있어, 서비스는 장기 실행 작업에 필수적입니다.

서비스는 다재다능하며, 다양한 방법으로 시작될 수 있으며, Intents가 애플리케이션의 진입점으로서 서비스를 시작하는 주요 방법입니다. startService 메서드를 사용하여 서비스가 시작되면, onStart 메서드가 작동을 시작하고 stopService 메서드가 명시적으로 호출될 때까지 계속 실행됩니다. 또는 서비스의 역할이 활성 클라이언트 연결에 의존하는 경우, bindService 메서드를 사용하여 클라이언트를 서비스에 바인딩하고, 데이터 전송을 위해 onBind 메서드를 활성화합니다.

서비스의 흥미로운 응용 프로그램에는 백그라운드 음악 재생 또는 사용자의 앱 상호작용을 방해하지 않고 네트워크 데이터 가져오기가 포함됩니다. 또한, 서비스는 내보내기를 통해 동일한 장치의 다른 프로세스에서 접근할 수 있도록 설정할 수 있습니다. 이는 기본 동작이 아니며 Android Manifest 파일에서 명시적인 구성이 필요합니다:

<service android:name=".ExampleExportedService" android:exported="true"/>

Broadcast Receivers

Broadcast receivers는 메시징 시스템에서 리스너 역할을 하여 여러 애플리케이션이 시스템의 동일한 메시지에 응답할 수 있도록 합니다. 앱은 Manifest를 통해 또는 registerReceiver API를 사용하여 앱 코드 내에서 두 가지 주요 방법으로 리시버를 등록할 수 있습니다. Manifest에서는 브로드캐스트가 권한으로 필터링되며, 동적으로 등록된 리시버는 등록 시 권한을 지정할 수도 있습니다.

Intent 필터는 두 등록 방법 모두에서 중요하며, 어떤 브로드캐스트가 리시버를 트리거하는지를 결정합니다. 일치하는 브로드캐스트가 전송되면 리시버의 onReceive 메서드가 호출되어 앱이 저전압 경고에 대한 반응으로 동작을 조정하는 등의 방식으로 반응할 수 있게 합니다.

브로드캐스트는 비동기적일 수 있으며, 순서 없이 모든 리시버에 도달하거나 동기적일 수 있으며, 리시버가 설정된 우선 순위에 따라 브로드캐스트를 받습니다. 그러나 모든 앱이 브로드캐스트를 가로채기 위해 자신을 우선시할 수 있으므로 잠재적인 보안 위험을 주의해야 합니다.

리시버의 기능을 이해하려면 해당 클래스 내에서 onReceive 메서드를 찾아보세요. 이 메서드의 코드는 수신된 Intent를 조작할 수 있으며, 특히 Intent를 수정하거나 삭제할 수 있는 Ordered Broadcasts에서 리시버에 의한 데이터 검증의 필요성을 강조합니다.

Content Provider

Content Providers는 앱 간에 구조화된 데이터공유하는 데 필수적이며, 데이터 보안을 보장하기 위해 권한을 구현하는 것이 중요합니다. 이들은 앱이 데이터베이스, 파일 시스템 또는 웹을 포함한 다양한 소스의 데이터에 접근할 수 있도록 합니다. readPermission 및 **writePermission**과 같은 특정 권한은 접근 제어에 중요합니다. 또한, 앱의 매니페스트에서 grantUriPermission 설정을 통해 임시 접근을 부여할 수 있으며, path, pathPrefix, pathPattern과 같은 속성을 활용하여 세부적인 접근 제어를 할 수 있습니다.

입력 검증은 SQL 인젝션과 같은 취약점을 방지하기 위해 매우 중요합니다. Content Providers는 데이터 조작 및 애플리케이션 간의 공유를 용이하게 하는 기본 작업인 insert(), update(), delete(), query()를 지원합니다.

FileProvider는 파일을 안전하게 공유하는 데 중점을 둔 전문화된 Content Provider입니다. 이는 앱의 매니페스트에 정의되며, 폴더에 대한 접근을 제어하기 위한 특정 속성을 포함하고 있으며, android:exportedandroid:resource가 폴더 구성으로 지정됩니다. 민감한 데이터가 우연히 노출되지 않도록 디렉토리를 공유할 때 주의가 필요합니다.

FileProvider에 대한 예시 매니페스트 선언:

<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>

filepaths.xml에서 공유 폴더를 지정하는 예:

<paths>
<files-path path="images/" name="myimages" />
</paths>

For further information check:

WebViews

WebViews는 Android 앱 내의 미니 웹 브라우저와 같으며, 웹 또는 로컬 파일에서 콘텐츠를 가져옵니다. 이들은 일반 브라우저와 유사한 위험에 직면하지만, 특정 설정을 통해 이러한 위험을 줄이는 방법이 있습니다.

Android는 두 가지 주요 WebView 유형을 제공합니다:

  • WebViewClient는 기본 HTML에 적합하지만 JavaScript 경고 기능을 지원하지 않아 XSS 공격을 테스트하는 방식에 영향을 미칩니다.
  • WebChromeClient는 전체 Chrome 브라우저 경험과 더 유사하게 작동합니다.

중요한 점은 WebView 브라우저가 장치의 기본 브라우저와 쿠키를 공유하지 않는다는 것입니다.

콘텐츠를 로드하기 위해 loadUrl, loadData, 및 loadDataWithBaseURL와 같은 메서드를 사용할 수 있습니다. 이러한 URL 또는 파일이 안전하게 사용될 수 있는지 확인하는 것이 중요합니다. 보안 설정은 WebSettings 클래스를 통해 관리할 수 있습니다. 예를 들어, setJavaScriptEnabled(false)로 JavaScript를 비활성화하면 XSS 공격을 방지할 수 있습니다.

JavaScript "Bridge"는 Java 객체가 JavaScript와 상호작용할 수 있게 하며, Android 4.2 이상부터 보안을 위해 메서드에 @JavascriptInterface로 표시해야 합니다.

콘텐츠 접근을 허용하는 (setAllowContentAccess(true)) 것은 WebViews가 콘텐츠 제공자에 접근할 수 있게 하며, 콘텐츠 URL이 안전하다고 확인되지 않으면 위험이 될 수 있습니다.

파일 접근을 제어하기 위해:

  • 파일 접근을 비활성화하는 (setAllowFileAccess(false)) 것은 파일 시스템에 대한 접근을 제한하며, 특정 자산에 대한 예외가 있어 비민감 콘텐츠에만 사용되도록 보장합니다.

Other App Components and Mobile Device Management

Digital Signing of Applications

  • 디지털 서명은 Android 앱에 필수적이며, 설치 전에 정품 작성되었음을 보장합니다. 이 과정은 앱 식별을 위한 인증서를 사용하며, 설치 시 장치의 패키지 관리자가 확인해야 합니다. 앱은 자체 서명되거나 외부 CA에 의해 인증될 수 있으며, 무단 접근으로부터 보호하고 장치에 전달되는 동안 앱이 변조되지 않도록 보장합니다.

App Verification for Enhanced Security

  • Android 4.2부터 Verify Apps라는 기능이 도입되어 사용자가 설치 전에 앱의 안전성을 확인할 수 있습니다. 이 검증 과정은 사용자가 잠재적으로 해로운 앱에 대해 경고하거나 특히 악성인 앱의 설치를 방지하여 사용자 보안을 강화할 수 있습니다.

Mobile Device Management (MDM)

  • MDM 솔루션장치 관리 API를 통해 모바일 장치에 대한 감독 및 보안을 제공합니다. 이들은 모바일 장치를 효과적으로 관리하고 보호하기 위해 Android 앱의 설치를 필요로 합니다. 주요 기능에는 비밀번호 정책 시행, 저장소 암호화 의무화, 및 원격 데이터 삭제 허용이 포함되어 있어 모바일 장치에 대한 포괄적인 제어 및 보안을 보장합니다.
// Example of enforcing a password policy with MDM
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminComponent = new ComponentName(context, AdminReceiver.class);

if (dpm.isAdminActive(adminComponent)) {
// Set minimum password length
dpm.setPasswordMinimumLength(adminComponent, 8);
}

Try Hard Security Group

{% embed url="https://discord.gg/tryhardsecurity" %}

{% hint style="success" %} AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기
{% endhint %}