CTFZone 2018 Never Ever Be Fooled to Pay the Ransomware!

Points: 269 , Yaklaşık 9 takım çözmüştü sanırım.

Sorunun açıklaması :

Has Your Android Phone Been Infected with Malware? — Yes! — It’s awful but we have a cure!

Soruda bize bir zip dosyası verildi. İçinden imageinfo.txt ve adb backup dosyası çıktı. Adb backup dosyasını

dd if=mybackup.ab bs=24 skip=1 | openssl zlib -d > mybackup.tar 

komutu ile tar dosyasına çevirdim ve açtım.
Tar içinde 2 klasor vardı. shared dosyası telefonun sd kartındaki dosyaların, apps te telefonda yüklü olan uygulamaların klasorüydü. Soru açıklaması okunduğunda bizden encrypt edilmiş dosyaları decrypt etmemizi istediği anlaşılıyordu. /shared/0/DCIM/Camera/ içinde sırasıyla

bulunmaktaydı. Flagde büyük olasılıkla resimde idi.( Uygulamalara sd kart okuma-yazma izni verirken dikkatli olmak lazım :) )

Şimdi sıra bu encryption’ı yapan uygulamayı bulmaktaydı. apps klasorunde olan com.dfwgxc.zimcdwpealgy aşırı tanıdık geldi ve bir heyecan bastı. Yakın zamanda ortaya ortaya çıkan ve Türk kullancıları hedef alan Anubis zararlısının random paket isimlerine çok benziyordu.Şurada analizini görebilirsiniz /shared/0/Download/ içindeki adobe flash player.apk yı jadx’te açınca kesin emin oldum. APK’nın paket adı com.dfwgxc.zimcdwpealgy ile uyuşuyordu. Uygulamadan ekran görüntüsü

APK

Gördüğünüz üzere uygulama obfuscated ve reflection kullanmakta. Encrypt edilmiş dosyaların isimlerinden anlaşılan o ki dosyalar AES ile encrypt edilmiş. Benimde aklıma ‘Acaba bu key obfuscated olan apk’nın içinde mi ?’ sorusu geldi. Uygulamayı çalıştırıp frida ile gerekli AES fonksiyonları hooklayarak key’i çıkarmayı deneyecektim. Ancak apk çalışmadı :(
Bu sefer apps/com.dfwgxc.zimcdwpealgy/r/app_files/oat/arm64 içindeki muquieljmg.vdex dosyasını incelemeye başladım. Vdex nedir derseniz google amcanın sitesinden :

vdex: contains the uncompressed DEX code of the APK, with some additional metadata to speed up verification.

Vdex dosyasını https://github.com/anestisb/vdexExtractor ile önce dex’e sonrada dex2jar ile jar‘a çevirdim. Oluşan muquieljmg.apk_classes-dex2jar.jar‘ı jd-gui ile açtım.

jar

Sonunda okunur şeyler görmeye başlamıştım.

hmm

faweifunhiunfg2uylbh8634gh783ghinegkrjln18hi8123 fonksiyonu sd kart içindeki dosyaları tek tek gezerek, dosyanın ismi “xxx”,”iv” yada “salt” ile bitiyor mu diye kontrol etmekte. Encryption yaptığı dosyaya denk gelirse tekrar encryption yapmamak için bu işlemi yapıyor. faweifunhiunfg2uylbh8734gh778ghinegkrGln18hi8123 fonksiyonu deviceID’sinin md5’ini almak üzere id’yi HIUHuihqfdiuhIUQWHDUIhgfi1278e412y78yDASVBDUYvwq fonksiyonuna yolluyor

md5

Ve dosya ismi ile md5(deviceID)’i agaierughl8y3g98ersiugohserkihgoas8erg89 fonksiyonuna yollanıyor.

wow

Fonksiyona giren paramString1 -> md5(deviceID), paramStrings2 -> dosya ismi. Resimden anlaşılacağı üzere md5(deviceID)’yi key olarak kullanıyor ve dosyayı encrypt ediyor. Pekii .. Biz encryption yapılmış cihazın id’sini nasıl bulucaz ?
Soruda verilen zipten bir de

< Bizone > cat imageinfo.txt 
[Computed Hashes] Image
MD5 checksum: E60E8FA8C64C9FE136E1731F388CF7B0
SHA1 checksum: 687BCAB465DA1631B86A0EC64D92BE45EC7B96EE

[Device Information]
Android version: 8.1.0
Android security patch level: July 1, 2018
Model: Mi A1
Wi-fi MAC: 04:b1:67:18:47:gg
Local time: 2018-07-19 15:48:54 UTC
Android time: 2018-01-01 07:15:37 EST
Shell permissions: shell
Serial Number: 4b26a8969905

IMEI 1: 867562039629283
IMEI 2: 867562039629291

şeklinde bir dosya daha çıkmıştı. Device ID’sini yani IMEI 1 yada IMEI 2’nin md5ini alıp, decrypt işlemini yapıcak bir java programı yazmamız gerekiyor. Soruyu yapan abimiz bizi düşünüp decryption işlemini yapan fonksiyonu da oraya eklemiş UIHiuhLIUHIHFiuhIUWEFHi8uh23l78ry78hfguisdh.İlgili fonksiyonların olduğu class

IMEI 1’in md5’ini alıyoruz

< ~ > echo -n "867562039629283" | md5sum
55bbc19a737d5f93e5ce09424a1b1b8a

Parametrelerle biraz oynayarak çalışcak hale getiriyoruz

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.Key;
import java.util.ArrayList;
import java.util.Iterator;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.KeySpec;

public class hm {

public static void main(String[] args) {
try {
String paramString1 = "55bbc19a737d5f93e5ce09424a1b1b8a";
String paramString2 = "IMG_20180101_071505.jpg";
Object localObject1 = new FileInputStream(paramString2+".salt");
Object localObject2 = new byte[8];
((FileInputStream)localObject1).read((byte[])localObject2);
((FileInputStream)localObject1).close();
Object localObject3 = new FileInputStream(paramString2 + ".iv");
localObject1 = new byte[16];
((FileInputStream)localObject3).read((byte[])localObject1);
((FileInputStream)localObject3).close();
localObject2 = new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(new PBEKeySpec(paramString1.toCharArray(), (byte[])localObject2, 65536, 256)).getEncoded(), "AES");
Cipher cipher1 = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher1.init(2, (Key)localObject2, new IvParameterSpec((byte[])localObject1));
localObject1 = new FileInputStream(paramString2+".xxx");
FileOutputStream p4 = new FileOutputStream(paramString2 + ".decrypted");
localObject2 = new byte[64];
for (;;)
{
int i = ((FileInputStream)localObject1).read((byte[])localObject2);
if (i == -1) {
break;
}
localObject3 = cipher1.update((byte[])localObject2, 0, i);
if (localObject3 != null) {
p4.write((byte[])localObject3);
}
}
byte[] cip = cipher1.doFinal();
if (cip != null) {
p4.write(cip);
}
p4.close();
p4.flush();
p4.close();
}

catch (Exception e) {
e.printStackTrace();
}
}
}

ve

javac hm.java
java hm

diyerek çalıştırıyoruz. Çıktı olarak bize IMG_20180101_071505.jpg.decrypted veriyor. Vee flag karşımızda

final