Xamarin Apps

Tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

기본 정보

Xamarin은 .NET 및 C# 프레임워크를 사용하여 iOS, Android, 그리고 Windows용 앱을 빌드하도록 설계된 오픈 소스 플랫폼입니다. 이 플랫폼은 현대적인 애플리케이션을 효율적으로 만들기 위한 다양한 도구와 확장 기능에 대한 접근을 제공합니다.

Xamarin의 아키텍처

  • Android의 경우, Xamarin은 .NET 바인딩을 통해 Android 및 Java 네임스페이스와 통합되며, Mono 실행 환경에서 Android Runtime(ART)과 함께 동작합니다. Managed Callable Wrappers(MCW)와 Android Callable Wrappers(ACW)는 Mono와 ART 간의 통신을 용이하게 하며, 둘 다 Linux 커널 위에서 빌드됩니다.
  • iOS의 경우, 애플리케이션은 Mono 런타임 하에서 실행되며, C# .NET 코드를 ARM 어셈블리 언어로 변환하는 전체 Ahead of Time(AOT) 컴파일을 사용합니다. 이 프로세스는 Objective-C Runtime과 함께 UNIX 유사 커널에서 동작합니다.

.NET Runtime 및 Mono Framework

.NET 프레임워크는 애플리케이션 개발을 위한 어셈블리, 클래스 및 네임스페이스를 포함하고 있으며, .NET Runtime이 코드 실행을 관리합니다. 플랫폼 독립성과 하위 호환성을 제공합니다. Mono Framework는 .NET을 Linux로 확장하기 위해 2005년에 시작된 오픈 소스 .NET 구현체로, 현재 Microsoft의 지원을 받으며 Xamarin이 주도하고 있습니다.

Xamarin 앱 리버스 엔지니어링

Xamarin 어셈블리의 디컴파일

디컴파일은 컴파일된 코드를 다시 소스 코드로 변환하는 과정입니다. Windows에서는 Visual Studio의 Modules 창을 통해 디컴파일할 모듈을 식별할 수 있으며, 이를 통해 서드파티 코드에 직접 접근하고 분석을 위해 소스 코드를 추출할 수 있습니다.

JIT vs AOT 컴파일

  • Android는 Just-In-Time(JIT) 및 Ahead-Of-Time(AOT) 컴파일을 지원하며, 최적의 실행 속도를 위해 Hybrid AOT 모드를 제공합니다. Full AOT는 Enterprise 라이선스에 한해 제공됩니다.
  • iOS는 Apple의 동적 코드 실행 제한으로 인해 AOT 컴파일만을 사용합니다.

APK/IPA에서 dll 파일 추출

APK/IPA 내의 어셈블리에 접근하려면 파일을 unzip하여 assemblies 디렉터리를 탐색합니다. Android의 경우 XamAsmUnZxamarin-decompress와 같은 도구로 dll 파일을 압축 해제할 수 있습니다.

python3 xamarin-decompress.py -o /path/to/decompressed/apk

APK를 디컴파일한 후 unknown/assemblies/ 폴더 안에 .dll 파일들이 보이는 경우, dnSpy.dll들에 직접 사용해 분석할 수 있습니다. 그러나 때로는 unknown/assemblies/ 폴더 안에 assemblies.blobassemblies.manifest 파일들이 들어 있는 경우도 있습니다. pyxamstore 도구는 Xamarin apps의 assemblies.blob 파일을 풀어 .NET 어셈블리에 접근하여 추가 분석을 할 수 있게 해줍니다:

pyxamstore unpack -d /path/to/decompressed/apk/assemblies/
# After patching DLLs, rebuild the store
pyxamstore pack

.NET MAUI 9 / .NET for Android: ELF .so 내부의 어셈블리 저장소

최근 Android MAUI 9 빌드에서는 더 이상 assemblies.blob을 직접 노출하지 않습니다. 대신 각 ABI는 lib/arm64-v8a/libassemblies.arm64-v8a.blob.so와 같은 ELF 컨테이너를 배포합니다. 이는 관리되는 어셈블리 저장소를 포함하는 커스텀 payload 섹션을 가진 유효한 공유 라이브러리입니다.

빠른 워크플로:

unzip app.apk -d app_unpacked
llvm-readelf --section-headers app_unpacked/lib/arm64-v8a/libassemblies.arm64-v8a.blob.so
llvm-objcopy --dump-section=payload=payload.bin \
app_unpacked/lib/arm64-v8a/libassemblies.arm64-v8a.blob.so
hexdump -c -n 4 payload.bin   # XABA

만약 llvm-readelfpayload 섹션을 표시하면, 이를 덤프하고 추출된 blob이 XABA (0x41424158)로 시작하는지 확인하세요. 그 payload는 .NET for Android에 문서화된 assembly store이며, 단일 DLL이 아닙니다.

스토어 레이아웃은 어셈블리를 수동으로 캐빙하거나 추출기 검증이 필요할 때 유용합니다:

  • 헤더: struct.unpack('<5I', ...)magic, version, entry_count, index_entry_count, index_size
  • 디스크립터: entry_count개의 레코드, 각 레코드는 struct.unpack('<7I', ...)data_offset / data_size 및 선택적 debug/config 오프셋 포함
  • 인덱스: index_size 바이트를 건너뜁니다
  • 이름: uint32 length + UTF-8 바이트
  • 데이터: 각 data_offset로 이동(seek)하여 data_size 바이트를 <name>.dll로 씁니다

일부 추출된 항목은 추가로 XALZ로 래핑되어 있어 dnSpy/ILSpy/dotPeek에서 바로 열리지 않을 수 있습니다. 이 경우:

  • 각 추출 파일의 처음 4바이트가 XALZ인지 확인하세요
  • 바이트 8:12에서 little-endian uint32로 원래(압축 해제된) 크기를 읽으세요
  • 바이트 12:lz4.block.decompress(...)로 압축 해제하세요

최소 압축 해제 로직:

import struct
import lz4.block

def decompress_xalz(data):
size = struct.unpack('<I', data[8:12])[0]
return lz4.block.decompress(data[12:], uncompressed_size=size)

스토어를 수동으로 파싱하고 싶지 않다면, pymauistore는 MAUI 9 APK에 대해 ELF 페이로드 추출, XABA 스토어 파싱, 그리고 XALZ 압축 해제를 자동화합니다.

일부 이전 Xamarin/MAUI 빌드는 /assemblies.blob 또는 /resources/assemblies 내부에 XALZ 형식으로 압축된 어셈블리를 저장합니다. 다음 xamarout 라이브러리로 빠르게 압축 해제할 수 있습니다:

from xamarout import xalz
import os
for root, _, files in os.walk("."):
for f in files:
if open(os.path.join(root, f), 'rb').read(4) == b"XALZ":
xa = xalz.XamarinCompressedAssembly(os.path.join(root, f))
xa.write("decompressed/" + f)

iOS dll files are readily accessible for decompilation, revealing significant portions of the application code, which often shares a common base across different platforms.

AOT on iOS: managed IL is compiled into native *.aotdata.* files. DLL만 패치하는 것으로는 로직이 바뀌지 않으며, IL bodies가 빈 플레이스홀더이기 때문에 네이티브 스텁을 훅해야 합니다(예: Frida).

정적 분석

Once the .dlls are obtained it’s possible to analyze the .Net code statically using tools such as dnSpy or ILSpy that will allow modifying the code of the app. This can be super useful to tamper the application to bypass protections for example.
앱을 수정한 후에는 다시 패키징하고 재서명해야 한다는 점을 유의하세요.

dnSpy is archived; maintained forks like dnSpyEx keep working with .NET 8/MAUI assemblies and preserve debug symbols when re-saving.

동적 분석

동적 분석은 SSL pinning을 확인하고 Xamarin 앱의 .NET 바이너리를 런타임에 수정하기 위해 Fridax와 같은 도구를 사용하는 것을 포함합니다. Frida 스크립트는 root detection이나 SSL pinning을 우회하는 데 사용 가능하여 분석 역량을 향상시킵니다.

Other interesting Frida scripts:

Updated Frida-xamarin-unpin (Mono >=6) hooks System.Net.Http.HttpClient.SendAsync and swaps the handler to a permissive one, so it still works even when pinning is implemented in custom handlers. 앱이 시작한 후에 실행하세요:

frida -U -l dist/xamarin-unpin.js com.target.app --no-pause

번들로 제공되는 frida-mono-api로 관리되는 메서드를 후킹하기 위한 빠른 템플릿:

const mono = require('frida-mono-api');
Mono.ensureInitialized();
Mono.enumerateLoadedImages().forEach(i => console.log(i.name));
const klass = Mono.classFromName("Namespace", "Class");
const m = Mono.methodFromName(klass, "Method", 2);
Mono.intercept(m, { onEnter(args){ console.log(args[1].toInt32()); } });

재서명

이 도구 Uber APK Signer은 동일한 키로 여러 APK에 서명하는 작업을 단순화하며, 앱에 변경을 가한 후 재서명하는 데 사용할 수 있습니다.

참고자료

Tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기