Android Anti-Instrumentation & SSL Pinning Bypass (Frida/Objection)

Reading time: 9 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking'i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Bu sayfa, instrumentation tespit eden/root‑block yapan veya TLS pinning uygulayan Android uygulamalarına karşı dinamik analiz yeteneğini geri kazanmak için pratik bir iş akışı sağlar. Hızlı triyaj, yaygın tespitler ve mümkün olduğunda repack yapmadan bunları atlatmak için kopyala‑yapıştır yapılabilir hook/taktiklere odaklanır.

Detection Surface (what apps check)

  • Root kontrolleri: su binary, Magisk yolları, getprop değerleri, yaygın root paketleri
  • Frida/debugger kontrolleri (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), /proc taraması, classpath, yüklü kütüphaneler
  • Native anti‑debug: ptrace(), syscalls, anti‑attach, breakpoints, inline hooks
  • Erken init kontrolleri: Application.onCreate() veya instrumentation varsa crash yapan process başlangıç hook'ları
  • TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins

Step 1 — Quick win: hide root with Magisk DenyList

  • Enable Zygisk in Magisk
  • Enable DenyList, add the target package
  • Reboot and retest

Birçok uygulama sadece bariz göstergelere bakar (su/Magisk paths/getprop). DenyList genellikle naif kontrolleri etkisiz hale getirir.

References:

  • Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk

Step 2 — 30‑second Frida Codeshare tests

Derinlemesine incelemeye başlamadan önce yaygın hazır script'leri deneyin:

  • anti-root-bypass.js
  • anti-frida-detection.js
  • hide_frida_gum.js

Example:

bash
frida -U -f com.example.app -l anti-frida-detection.js

Genellikle Java root/debug kontrollerini, process/service taramalarını ve native ptrace() çağrılarını stub'lar. Hafifçe korunan uygulamalarda işe yarar; sertleştirilmiş hedefler için özelleştirilmiş hooks gerekebilir.

  • Codeshare: https://codeshare.frida.re/

Medusa ile Otomasyon (Frida framework)

Medusa, SSL unpinning, root/emulator detection bypass, HTTP comms logging, crypto key interception ve daha fazlası için 90+ hazır modül sağlar.

bash
git clone https://github.com/Ch0pin/medusa
cd medusa
pip install -r requirements.txt
python medusa.py

# Example interactive workflow
show categories
use http_communications/multiple_unpinner
use root_detection/universal_root_detection_bypass
run com.target.app

İpucu: Medusa, custom hooks yazmadan önce hızlı kazanımlar için mükemmeldir. Ayrıca cherry-pick modules seçebilir ve bunları kendi scripts'lerinizle birleştirebilirsiniz.

Adım 3 — Bypass init-time detectors by attaching late

Birçok tespit yalnızca process spawn/onCreate() sırasında çalışır. Spawn‑time injection (-f) veya gadgets yakalanır; UI yüklendikten sonra attaching ile atlatılabilir.

bash
# Launch the app normally (launcher/adb), wait for UI, then attach
frida -U -n com.example.app
# Or with Objection to attach to running process
aobjection --gadget com.example.app explore  # if using gadget

Bu işe yararsa, oturumu kararlı tutun ve map ile stub kontrollerine geçin.

Adım 4 — Tespit mantığını Jadx ve string aramasıyla eşleme

Static triage keywords in Jadx:

  • "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"

Tipik Java kalıpları:

java
public boolean isFridaDetected() {
return getRunningServices().contains("frida");
}

İncelenecek / hook'lanacak yaygın API'ler:

  • android.os.Debug.isDebuggerConnected
  • android.app.ActivityManager.getRunningAppProcesses / getRunningServices
  • java.lang.System.loadLibrary / System.load (native köprüsü)
  • java.lang.Runtime.exec / ProcessBuilder (sorgulama komutları)
  • android.os.SystemProperties.get (root/emülatör heuristikleri)

Adım 5 — Frida (Java) ile çalışma zamanı stubbing

Repacking yapmadan özel korumaları override ederek güvenli değerler döndürün:

js
Java.perform(() => {
const Checks = Java.use('com.example.security.Checks');
Checks.isFridaDetected.implementation = function () { return false; };

// Neutralize debugger checks
const Debug = Java.use('android.os.Debug');
Debug.isDebuggerConnected.implementation = function () { return false; };

// Example: kill ActivityManager scans
const AM = Java.use('android.app.ActivityManager');
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
});

Erken çökme triage'i mi yapıyorsunuz? Çökmeden hemen önce Dump classes ile muhtemel detection namespaces'leri tespit edin:

js
Java.perform(() => {
Java.enumerateLoadedClasses({
onMatch: n => console.log(n),
onComplete: () => console.log('Done')
});
});

// Quick root detection stub example (adapt to target package/class names) Java.perform(() => { try { const RootChecker = Java.use('com.target.security.RootCheck'); RootChecker.isDeviceRooted.implementation = function () { return false; }; } catch (e) {} });

Şüpheli yöntemleri kaydedin ve yürütme akışını doğrulamak için etkisizleştirin:

js
Java.perform(() => {
const Det = Java.use('com.example.security.DetectionManager');
Det.checkFrida.implementation = function () {
console.log('checkFrida() called');
return false;
};
});

Bypass emulator/VM detection (Java stubs)

Yaygın heuristikler: Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE alanlarında generic/goldfish/ranchu/sdk bulunması; QEMU artifaktları (ör. /dev/qemu_pipe, /dev/socket/qemud); varsayılan MAC 02:00:00:00:00:00; 10.0.2.x NAT; telefon/sensörlerin yokluğu.

Build alanlarının hızlı spoof'lanması:

js
Java.perform(function(){
var Build = Java.use('android.os.Build');
Build.MODEL.value = 'Pixel 7 Pro';
Build.MANUFACTURER.value = 'Google';
Build.BRAND.value = 'google';
Build.FINGERPRINT.value = 'google/panther/panther:14/UP1A.231105.003/1234567:user/release-keys';
});

Dosya varlığı kontrolleri ve tanımlayıcılar (TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList) için gerçekçi değerler döndüren stub'larla tamamlayın.

SSL pinning bypass quick hook (Java)

Özel TrustManagers'ı nötralize edin ve izin verici SSL context'lerini zorlayın:

js
Java.perform(function(){
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');

// No-op validations
X509TrustManager.checkClientTrusted.implementation = function(){ };
X509TrustManager.checkServerTrusted.implementation = function(){ };

// Force permissive TrustManagers
var TrustManagers = [ X509TrustManager.$new() ];
var SSLContextInit = SSLContext.init.overload('[Ljavax.net.ssl.KeyManager;','[Ljavax.net.ssl.TrustManager;','java.security.SecureRandom');
SSLContextInit.implementation = function(km, tm, sr){
return SSLContextInit.call(this, km, TrustManagers, sr);
};
});

Notlar

  • OkHttp için genişlet: gerekli olduğunda okhttp3.CertificatePinner ve HostnameVerifier'ı hook et veya CodeShare'den evrensel unpinning script'ini kullan.
  • Çalıştırma örneği: frida -U -f com.target.app -l ssl-bypass.js --no-pause

Adım 6 — Java hooks başarısız olduğunda JNI/native izini takip et

Native loader'ları ve detection init'ini bulmak için JNI giriş noktalarını izle:

bash
frida-trace -n com.example.app -i "JNI_OnLoad"

Paketlenmiş .so dosyalarının hızlı yerel triyajı:

bash
# List exported symbols & JNI
nm -D libfoo.so | head
objdump -T libfoo.so | grep Java_
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'

Etkileşimli/yerel reversing:

  • Ghidra: https://ghidra-sre.org/
  • r2frida: https://github.com/nowsecure/r2frida

Örnek: ptrace'i etkisizleştirerek libc'deki basit anti‑debug'i atlatma:

js
const ptrace = Module.findExportByName(null, 'ptrace');
if (ptrace) {
Interceptor.replace(ptrace, new NativeCallback(function () {
return -1; // pretend failure
}, 'int', ['int', 'int', 'pointer', 'pointer']));
}

Ayrıca bakınız: Reversing Native Libraries

Adım 7 — Objection patching (embed gadget / strip basics)

Eğer repacking'i runtime hooks yerine tercih ediyorsanız, şunu deneyin:

bash
objection patchapk --source app.apk

Notlar:

  • apktool gerektirir; build sorunlarını önlemek için resmi kılavuzdan güncel bir sürüm kullandığınızdan emin olun: https://apktool.org/docs/install
  • Gadget injection, root olmadan instrumentation'a izin verir ancak daha güçlü init‑time kontrolleri tarafından hâlâ tespit edilebilir.

İsteğe bağlı olarak, Zygisk ortamlarında daha güçlü root gizleme için LSPosed modülleri ve Shamiko ekleyin ve alt süreçleri kapsayacak şekilde DenyList'i düzenleyin.

Kaynaklar:

  • Objection: https://github.com/sensepost/objection

Adım 8 — Fallback: Ağ görünürlüğü için TLS pinning'i yama

Eğer instrumentation engellenmişse, pinning'i statik olarak kaldırarak trafiği hâlâ inceleyebilirsiniz:

bash
apk-mitm app.apk
# Then install the patched APK and proxy via Burp/mitmproxy
  • Araç: https://github.com/shroudedcode/apk-mitm
  • Ağ yapılandırması CA‑trust hileleri (ve Android 7+ user CA trust) için bakınız:

Make APK Accept CA Certificate

Install Burp Certificate

Kullanışlı komut kısa başvuru

bash
# List processes and attach
frida-ps -Uai
frida -U -n com.example.app

# Spawn with a script (may trigger detectors)
frida -U -f com.example.app -l anti-frida-detection.js

# Trace native init
frida-trace -n com.example.app -i "JNI_OnLoad"

# Objection runtime
objection --gadget com.example.app explore

# Static TLS pinning removal
apk-mitm app.apk

Evrensel proxy zorlaması + TLS unpinning (HTTP Toolkit Frida hooks)

Modern uygulamalar genellikle sistem proxy'lerini yok sayar ve birden fazla pinning katmanı uygulayarak (Java + native) kullanıcı/sistem CAs yüklü olsa bile trafiği yakalamayı zorlaştırır. Pratik bir yöntem, hazır Frida hooks kullanarak evrensel TLS unpinning ile proxy zorlamayı birleştirmek ve tüm trafiği mitmproxy/Burp üzerinden yönlendirmektir.

İş akışı

  • Hostunuzda mitmproxy'yi (veya Burp) çalıştırın. Cihazın host IP/port'una ulaşabildiğinden emin olun.
  • HTTP Toolkit’s consolidated Frida hooks'u yükleyin; hem TLS unpinning yapmak hem de yaygın stack'lerde proxy kullanımını zorlamak için (OkHttp/OkHttp3, HttpsURLConnection, Conscrypt, WebView, vb.). Bu, CertificatePinner/TrustManager kontrollerini atlar ve proxy seçicilerini geçersiz kılar; böylece uygulama açıkça proxy'leri devre dışı bıraktığında bile trafik her zaman proxy'niz üzerinden gönderilir.
  • Hedef uygulamayı Frida ve hook script ile başlatın ve mitmproxy'de istekleri yakalayın.

Örnek

bash
# Device connected via ADB or over network (-U)
# See the repo for the exact script names & options
frida -U -f com.vendor.app \
-l ./android-unpinning-with-proxy.js \
--no-pause

# mitmproxy listening locally
mitmproxy -p 8080

Notlar

  • Mümkünse sistem genelinde bir proxy ile birleştirin: adb shell settings put global http_proxy <host>:<port>. Frida hooks, uygulamalar global ayarları atlatmış olsalar bile proxy kullanımını zorlayacaktır.
  • Bu teknik, pinning/proxy atlatmanın yaygın olduğu mobil→IoT onboarding akışlarında MITM yapmanız gerektiğinde idealdir.
  • Hooks: https://github.com/httptoolkit/frida-interception-and-unpinning

Referanslar

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking'i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin