Background Image

BLOG

DKHOS - Mobile 400 - Cepte Kene Yok Bir Yolunu Bulmalı
18 Şubat 2018 CTF

DKHOS - Mobile 400 - Cepte Kene Yok Bir Yolunu Bulmalı


Soru Açıklaması: 

Sonunda Mahmut'un elde ettiği .apk sayesinde Pelinsu'ya dair somut bir iz çıkabilecekti. Çok kombinasyon olsa da tek bir cevabı olmalıydı... 

Sorunun Çözümü:

Soruda verilen APK dosyasını öncelikle APKTool ile decomile edip AndroidManifest.xml dosyasını inceliyoruz. Manifest'te sadece bir adet activity olduğunu ve sadece internet izni istediğini görüyoruz. Uygulamayı offline bir cihaza ya da emulatöre kurup çalıştırarak bizden ne beklendiğine bakıyoruz.

Bir kredi kartı numarasını girip doğrulama işlemi yapmamız bekleniyor. Kart numarasının ilk 6 (BIC) ve son 4 hanesi verilmiş. Geriye kalan 6 hane ilk bakışta bir milyon ihtimal olduğunu gösteriyor, lakin kredi kartı numaralarının ipucunda da belirttiğimiz gibi Luhn algoritmasına göre generate edildiğini biliyoruz. Dolayısıyla bu ihtimalleri azaltmak adına elimizdeki verileri kullanarak Luhn algoritmasını çalıştırıyoruz:

Luhn, ihtimalleri 100 bine indiriyor, fakat ihtimaller elle denenmeyecek kadar çok fazla. "adb shell input keyevent" komutlarıyla denenirse hızlanabilir ama yine de çok zaman alacaktır.

Kart numarasının nasıl kontrol edildiğini anlamak için tersine mühendisliğe başlıyoruz. Jadx ya da benzeri bir Java decompiler ile APK'yı decompile ediyoruz. Manifest'te bulduğumuz MainActivity'nin kodlarını inceliyoruz. Bu class'ta native-lib adında bir library'nin load edildiğini ve init, ffnd ve check adında 3 adet native fonksiyonun kullanıldığını farkediyoruz. ffnd fonkisyonun Frida'yı detect etme amacıyla kullanıldığını if-else kodlarından anlayabiliyoruz. Bu aslında sorunun Frida ile rahatlıkla çözülebileceiğine dair bir ipucu niteliği taşımakta, ancak Frida detection'ını bypass etmemiz de beklenmekte. Dogrula butonuna tıklandığında EditText'teki string bir local variable'a atanmakta olduğunu ve ardından native check fonksiyonunun çağrıldığını farkediyoruz. 

APK içerisindeki lib dizininden aşina olduğunuz mimariye ait native-lib dosyasını IDA ile incelemeye başlıyoruz. Öncelike Strings View ile library'deki string'lere bakıyoruz. Şanslıyız ki string'ler şifrelenmemiş şekilde gözüküyor.

String listesine bakarak yapabileceğimiz bazı çıkarımlar:

  • /bin/su, /system/bin/su gibi dosyaların varlığı kontrol edilerek cihazda root yetkisinin olup olmadığı kontrol ediliyor.
  • 127.0.0.1 IP adresine muhtemelen bağlantı kuralacak. Ardından gelen AUTH ve REJECT stringleri localhost'a bind edilmiş Frida serverınının kontrol edildiğine dair bir işaret.
  • getPackageInfo ve signatures bize uygulamanın imzasının runtime esnasında check ediliyor olabileceğiini gösteriyor. Bu kontrol ile anti-tampering yapılıyor olabilir.
  • /proc/self/maps dosyasında uygulamanın kullandığı library dosyaları bulunur. Burada olmaması gereken (blacklisting) lıbrary'lere bakılıyor olabilir (örn: frida gadget, xposed vs). 

Import table'ına bakarak hangi system çağrılarının yapıldığını da kontrol ediyoruz.

  • ptrace, ppid, fork ve waitpid çağrılarının kullanıldığını görüyoruz. Bu bir child process'in uygulama process'ine attach ederek debugging'in önlenmesi için kullanıyor olabilir.
  • socket, inet_aton ise strings bilgisinden de anladığımız üzere localhostta çalışan frida server'ı tespit edilmeye çalışılıyor.

Sadece bu bilgiler ışığında uygulamanın;

  • Anti-tampering (signature check)
  • Anti-debugging (debuggable app, fork, waitpid)
  • Rootkit detection (su binary dosyaları)
  • Hook detection (frida)

yaptığını anlıyoruz. Bizden beklenen kart numarasını bulmak için sürekli kart no değişkenini değiştirip check fonksiyonunu çağırmak. Bunun için root yetkili bir cihaz ve frida ile instrumentation yeterli olacaktır. Rootkit tespitini Magisk Systemless rootkitiyle ve Magisk Hide ile geçmek mümkün, çünkü sadece su dosyalarının varlığı kontrol ediliyor ve Magisk Hide modülünün bu dosyaları uygulamalardan saklama özelliği bulunmakta.

Frida tespiti için localhost'a bağlanma isteği gönderiliyordu. Bunu IDA'dan da teyit edelim. Frida default olarak 27042. portta çalışır. Uygulama ise 27000 (0x6978)  ve 27100 (0x69dc) portları arasına connect isteği yolluyor.

 

Bu bilgiler ışığında frida script'imizi aşağıdaki gibi hazırlıyoruz. Luhn ile bulduğumuz kart listesini cihazın /data/local/tmp dizinine atıyoruz.

Frida serverını aşağıdaki komut ile farklı bir portta çalıştırıyoruz:

  • ./frida-server -l 0.0.0.0.0:30000

Ardından scriptimizi uygulamayı açtıktan sonra çalıştrıyoruz.

  • frida -H <cihaz ip adresi>:30000 -l run.js -f -n five.dkhos.mob.nfc_pay

Flag: DKHOS_{5575989816510364}

NFC Pay uygulamasında piyasadaki HCE uygulamalarının çoğunda olduğu gibi (tokenized) kredi kartı vb. hassas bilgilerin saklanması için WhiteBox Cryptography kullanılmaktaydı. Bunun ipucunu bir önceki soruda aslında vermiştik. Sunucudan dönen token "whitebox" kelimesinin MD5 hash'iydi. 

WhiteBox Crypto için AES-128 algoritması kullanıldı ve lookup table'ların korunması için herhangi bir önlem alınmamıştı. AES anahtarı ise "komutan_logar_mi" olarak kullanılmıştı.