Всем привет,
решил написать стать по тому что можно достать из android устройства. Ну или по крайней мере всё то что приходит мне в голову. В статье буду использовать JAVA в качестве инструмента для получения данных и буду приводить мелкие но рабочие примеры кода с пояснением как и что использовать. Постараюсь идти максимально плавно. Начать с того что не требует дополнительных разрешений и не считается системой android опасным разрешение и буду продвигаться к более сложно получаемым но в теории более полезным для тех или иных сфер.
В статье будут:
Данные об устройстве
Данные об устройстве можно сказать наименее полезные так как их сложно как-то самостоятельно использовать в зловредных целях. Но и бесполезными их назвать нельзя. Так-как в любом адекватном рат на android есть версия adnroid, имя устройства и подобное.
Версия android:
Тут всё банально и просто. Никаких дополнительных разрешений. Достаточно просто вызвать:
Build.VERSION.RELEASE
Имя устройства:
Точно так-же, просто вызываем:
Build.MODEL
Данные сети к которой подключено устройство
Данные о сети нужны можно применять в различных целях. Таких как:
Определять страну откуда устройство
Если крупный то город
определять есть-ли подключение к сети чтобы не слать запросы в пустоту
имя сети для дальнейших атак
Тип и статус сети
Наименее полезное из раздела это тип и статус сети а именно подключено ли устройство к сети и если да то к wifi или мобильной сети . Какое-то прям сильное применение кроме того как смотреть подключено устройство к сети для того чтоб не слать данные в пустую если их надо отправить один раз мне в голову не приходит. Но может у вас будет нужда в этом.
Так что вот функция которая проверяет если ли подключение и если да то к какому типу оно относится:
Тут во второй строке получается состояние сети и далее с помощью многочисленных проверок выясняется что да как.
Как применять:
SSID
Для того чтобы получить ssid(Имя сети ) уже нужно разрешения. А именно надо добавить внутрь манифеста:
и потом запрашиваем их внутри activity:
и потом вызываем getWifiSSID(getApplicationContext()); например внутрь какой-нибудь переменой. Например:
IP
Наверное самое полезное и часто используемое это IP (Internet Protocol address).
Его можно использовать для получения приёмной геолокации устройства. Точного получения страны. Или ещё довольно большого количества других применений.
К сожалению прямое его получение из adrodiAPI было ограниченно в последних версия андроида и получить его напрямую нельзя во избежание утечки данных и слежки . Но это легко обходит прямым http запросом на любой сайт который возвращает твой API адрес. Например https://api.ipify.org/ .
пример запроса:
Таким же методом можно вычислить страну и примерно город.
Геолокация
её проще у точнее всего получить с помощью Google Location Services (FusedLocationProviderClient). Его встроенным в андроид изначально нету и надо добавлять отдельную зависимость.
А именно в файл build.gradle
Далее необходимо добавить и запросить в обязательном порядке разрешение ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION
Код запроса внутри activity модно взять выше просто заменить разрешение
Далее нам надо понять как будет выглядеть геолокация. С помощью Google Location Services можно получить широту и долготу (Пример: 55.75371657187264, 37.61993133146647) .
код:
Как это работает:
FusedLocationProviderClient - Класс, через который Google даёт геолокацию,
getLastLocation() - Получает последнюю известную точку,
if (location != null) - Проверка: есть ли данные
location.getLatitude() - Получаем широту
location.getLongitude() - Получаем долготу
Номера телефона
Номера с sim-карт хранятся в поле MSIISDN на самой sim-карте, если оно есть.
Но оно не читается из файлов — это нечто вроде системной метаинформации, к которой даёт доступ Android через SubscriptionManager.
Чтобы его/их получить надо вызвать subscriptionInfoList.getNumber() . getNumber запрашивает их у системы. Но важно учесть что требуется разрешение READ_PHONE_STATE иначе getNumber вернёт null.
В манифест:
Готовое решение в виде кода:
В данном коде проверяется не является ли subscriptionInfoList пустым, если нет то запрашивает getNumber для sim1. Точно так-же можно получать номер для sim2 и т.д. заменяя sim1 на sim2.
Для более гибкого использования можно добавить получения второго номера не прям точно так-же а сначала проверять количество элементов в subscriptionInfoList и если их больше чем 1 то запрашивать второй номер.
код для получения второго номера:
и в конце возвращаем sim1, sim2 .
дальше можно легко использовать в других функциях:
String[] simNumbers = getSimNumbers();
String sim1 = simNumbers[0];
String sim2 = simNumbers[1];
Список установленных приложений
В Android список установленных приложений можно получить через PackageManager. Но начиная с версии Android 11 появились ограничения и теперь для получения списка установленных приложений надо QUERY_ALL_PACKAGES
Далее всё просто надо получить объект PackageManager он позволяет нам работать с установленными приложениями, разрешениями, компонентами и т.д. Это как менеджер программ.
Второй шаг это получить List ApplicationInfo и поставить флаг GET_META_DATA - это флаг, говорящий системе: «дай мне ещё и метаинформацию, если она есть.
Пробегаемся по всем найденным приложениям.
Остается просто получить человеческое имя приложения. То есть: "YouTube", "WhatsApp"
и получить уникальное имя пакета - например
Тут по факту всё, Вот полный код для этого:
Но тут нету никакого вывода, можно добавить например вывод в логи или то что вам нужно
Список контактов
Как по мне то самое то для офисников. Так-как с помощью этого можно узнавать номера друзей или родственников жертвы, короче говоря работать по всем фронтам.
И к сожалению или к счастью получить их как и всё выше не составляет особой проблемы. Тут тоже надо просто получить одно разрешение: READ_CONTACTS
В манифест:
Далее делаем его запрос и с помощью ContentResolver, который позволяет читать данные из системных источников запрашиваем CONTENT_URI где Android хранит телефоны контактов. Для с помощью Cursor перебираем записи. И остаётся только извлечь параметры, например: DISPLAY_NAME и NUMBER.
Код:
Для вывода я просто добавил вывод в логи с помощью Log.d(
И ещё для работы важно учесть что:
И завиральной часть в этой статье я бы хотел сделать журнал вызовов. Прям какое-то конкретное применение мне придумать сложно но думаю для конкретное спецификации подойдёт отлично.
Для доступа к журналу вызовов необходимо указать разрешение в AndroidManifest.xml:
и конечно-же запросить его в рантайме,
После чего используя ContentResolver для доступа к CallLog.Calls.CONTENT_URI перебираем записи журнала вызовов и от туда можно извлечь:
В данном примере я перебираю тип звонка чтоб удобно вывести текстом и далее вывожу всё просто в логи ну или вы можете поменять на то как вам удобно.
На этом всё, надеюсь был полезен. если про что-то не рассказал пишите в кометы может сделаю 2ю часть.
Всем хорошего времени суток и пока!
решил написать стать по тому что можно достать из android устройства. Ну или по крайней мере всё то что приходит мне в голову. В статье буду использовать JAVA в качестве инструмента для получения данных и буду приводить мелкие но рабочие примеры кода с пояснением как и что использовать. Постараюсь идти максимально плавно. Начать с того что не требует дополнительных разрешений и не считается системой android опасным разрешение и буду продвигаться к более сложно получаемым но в теории более полезным для тех или иных сфер.
В статье будут:
- Данные об устройстве
- Модель и производитель устройства
- Версия Android
- Данные сети к которой подключено устройство
- Тип сети
- Имя Wi-Fi сети
- IP-адрес
- Геолокация
- Данные о пользователе
- номера телефонов
- Список установленных приложений
- список контактов
- журнал вызовов
Данные об устройстве
Данные об устройстве можно сказать наименее полезные так как их сложно как-то самостоятельно использовать в зловредных целях. Но и бесполезными их назвать нельзя. Так-как в любом адекватном рат на android есть версия adnroid, имя устройства и подобное.
Версия android:
Тут всё банально и просто. Никаких дополнительных разрешений. Достаточно просто вызвать:
Build.VERSION.RELEASE
Имя устройства:
Точно так-же, просто вызываем:
Build.MODEL
Данные сети к которой подключено устройство
Данные о сети нужны можно применять в различных целях. Таких как:
Определять страну откуда устройство
Если крупный то город
определять есть-ли подключение к сети чтобы не слать запросы в пустоту
имя сети для дальнейших атак
Тип и статус сети
Наименее полезное из раздела это тип и статус сети а именно подключено ли устройство к сети и если да то к wifi или мобильной сети . Какое-то прям сильное применение кроме того как смотреть подключено устройство к сети для того чтоб не слать данные в пустую если их надо отправить один раз мне в голову не приходит. Но может у вас будет нужда в этом.
Так что вот функция которая проверяет если ли подключение и если да то к какому типу оно относится:
Java:
public String getConnectionType(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm == null) return "Неизвестно";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Network network = cm.getActiveNetwork();
if (network == null) return "Нет подключения";
NetworkCapabilities caps = cm.getNetworkCapabilities(network);
if (caps == null) return "Нет подключения";
if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return "Wi-Fi";
} else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return "Мобильная сеть";
} else {
return "Другое подключение";
}
}
Тут во второй строке получается состояние сети и далее с помощью многочисленных проверок выясняется что да как.
Как применять:
Java:
String status = getConnectionType(getApplicationContext());
Log.d("Сеть", "Тип подключения: " + status);
SSID
Для того чтобы получить ssid(Имя сети ) уже нужно разрешения. А именно надо добавить внутрь манифеста:
XML:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
и потом запрашиваем их внутри activity:
Java:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
и потом вызываем getWifiSSID(getApplicationContext()); например внутрь какой-нибудь переменой. Например:
Java:
String wifiName = getWifiSSID(getApplicationContext());
IP
Наверное самое полезное и часто используемое это IP (Internet Protocol address).
Его можно использовать для получения приёмной геолокации устройства. Точного получения страны. Или ещё довольно большого количества других применений.
К сожалению прямое его получение из adrodiAPI было ограниченно в последних версия андроида и получить его напрямую нельзя во избежание утечки данных и слежки . Но это легко обходит прямым http запросом на любой сайт который возвращает твой API адрес. Например https://api.ipify.org/ .
пример запроса:
Java:
URL url = new URL("https://api.ipify.org?format=json");
HttpURLConnection conn = (HttpURLConnection) url.openConnection()
Таким же методом можно вычислить страну и примерно город.
Геолокация
её проще у точнее всего получить с помощью Google Location Services (FusedLocationProviderClient). Его встроенным в андроид изначально нету и надо добавлять отдельную зависимость.
А именно в файл build.gradle
Код:
implementation ("com.google.android.gms:play-services-location:21.0.1")
Далее необходимо добавить и запросить в обязательном порядке разрешение ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION
XML:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Код запроса внутри activity модно взять выше просто заменить разрешение
Далее нам надо понять как будет выглядеть геолокация. С помощью Google Location Services можно получить широту и долготу (Пример: 55.75371657187264, 37.61993133146647) .
код:
Java:
FusedLocationProviderClient fusedClient = LocationServices.getFusedLocationProviderClient(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
return;
}
fusedClient.getLastLocation()
.addOnSuccessListener(location -> {
if (location != null) {
double lat = location.getLatitude();
double lon = location.getLongitude();
Log.d("Geo", "Широта: " + lat + ", Долгота: " + lon);
} else {
Log.d("Geo", "Нет данных. Возможно GPS выключен.");
}
});
Как это работает:
FusedLocationProviderClient - Класс, через который Google даёт геолокацию,
getLastLocation() - Получает последнюю известную точку,
if (location != null) - Проверка: есть ли данные
location.getLatitude() - Получаем широту
location.getLongitude() - Получаем долготу
Номера телефона
Номера с sim-карт хранятся в поле MSIISDN на самой sim-карте, если оно есть.
Но оно не читается из файлов — это нечто вроде системной метаинформации, к которой даёт доступ Android через SubscriptionManager.
Чтобы его/их получить надо вызвать subscriptionInfoList.getNumber() . getNumber запрашивает их у системы. Но важно учесть что требуется разрешение READ_PHONE_STATE иначе getNumber вернёт null.
В манифест:
XML:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Готовое решение в виде кода:
Java:
if (subscriptionInfoList != null && !subscriptionInfoList.isEmpty()) {
if (subscriptionInfoList.size() > 0) {
sim1 = subscriptionInfoList.get(0).getNumber();
if (sim1 == null || sim1.isEmpty()) {
sim1 = "SIM-карта отсутствует";
}
}
В данном коде проверяется не является ли subscriptionInfoList пустым, если нет то запрашивает getNumber для sim1. Точно так-же можно получать номер для sim2 и т.д. заменяя sim1 на sim2.
Для более гибкого использования можно добавить получения второго номера не прям точно так-же а сначала проверять количество элементов в subscriptionInfoList и если их больше чем 1 то запрашивать второй номер.
код для получения второго номера:
Java:
if (subscriptionInfoList.size() > 1) {
sim2 = subscriptionInfoList.get(1).getNumber();
if (sim2 == null || sim2.isEmpty()) {
sim2 = "SIM-карта отсутствует";
}
}
и в конце возвращаем sim1, sim2 .
Java:
return new String[]{sim1, sim2};
дальше можно легко использовать в других функциях:
String[] simNumbers = getSimNumbers();
String sim1 = simNumbers[0];
String sim2 = simNumbers[1];
Список установленных приложений
В Android список установленных приложений можно получить через PackageManager. Но начиная с версии Android 11 появились ограничения и теперь для получения списка установленных приложений надо QUERY_ALL_PACKAGES
Java:
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
Далее всё просто надо получить объект PackageManager он позволяет нам работать с установленными приложениями, разрешениями, компонентами и т.д. Это как менеджер программ.
PackageManager pm = getPackageManager();Второй шаг это получить List ApplicationInfo и поставить флаг GET_META_DATA - это флаг, говорящий системе: «дай мне ещё и метаинформацию, если она есть.
List<ApplicationInfo> apps = pm.getInstalledApplications(PackageManager.GET_META_DATA);Пробегаемся по всем найденным приложениям.
for (ApplicationInfo app : apps) { ... }Остается просто получить человеческое имя приложения. То есть: "YouTube", "WhatsApp"
String appName = pm.getApplicationLabel(app).toString();и получить уникальное имя пакета - например
- com.google.android.youtube
- com.whatsapp
Тут по факту всё, Вот полный код для этого:
Java:
PackageManager pm = getPackageManager();
List<ApplicationInfo> apps = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo app : apps) {
String appName = pm.getApplicationLabel(app).toString();
String packageName = app.packageName;
}
Но тут нету никакого вывода, можно добавить например вывод в логи или то что вам нужно
Java:
Log.d("AppList", appName + " - " + packageName);
Список контактов
Как по мне то самое то для офисников. Так-как с помощью этого можно узнавать номера друзей или родственников жертвы, короче говоря работать по всем фронтам.
И к сожалению или к счастью получить их как и всё выше не составляет особой проблемы. Тут тоже надо просто получить одно разрешение: READ_CONTACTS
В манифест:
XML:
<uses-permission android:name="android.permission.READ_CONTACTS" />
Далее делаем его запрос и с помощью ContentResolver, который позволяет читать данные из системных источников запрашиваем CONTENT_URI где Android хранит телефоны контактов. Для с помощью Cursor перебираем записи. И остаётся только извлечь параметры, например: DISPLAY_NAME и NUMBER.
Код:
Java:
public void getContacts(Context context) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CONTACTS}, 1);
return;
}
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
String name = cursor.getString(
cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = cursor.getString(
cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.d("Contact", name + ": " + number);
}
cursor.close();
}
}
Для вывода я просто добавил вывод в логи с помощью Log.d(
Log.d("Contact", name + ": " + number);
И ещё для работы важно учесть что:
- Не все контакты могут содержать номера телефонов.
- Контактов может быть много, поэтому всегда закрывайте Cursor
И завиральной часть в этой статье я бы хотел сделать журнал вызовов. Прям какое-то конкретное применение мне придумать сложно но думаю для конкретное спецификации подойдёт отлично.
Для доступа к журналу вызовов необходимо указать разрешение в AndroidManifest.xml:
Java:
<uses-permission android:name="android.permission.READ_CALL_LOG" />
и конечно-же запросить его в рантайме,
После чего используя ContentResolver для доступа к CallLog.Calls.CONTENT_URI перебираем записи журнала вызовов и от туда можно извлечь:
- имя - если оно было сохранено
- номер телефона
- дату звонка
- тип - входящий/исходящий
- длительность звонка
Java:
public void getCallLogs(Context context) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CALL_LOG}, 100);
return;
}
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + " DESC");
if (cursor != null) {
while (cursor.moveToNext()) {
String number = cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls.NUMBER));
String name = cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls.CACHED_NAME));
long dateMillis = cursor.getLong(cursor.getColumnIndexOrThrow(CallLog.Calls.DATE));
int type = cursor.getInt(cursor.getColumnIndexOrThrow(CallLog.Calls.TYPE));
int duration = cursor.getInt(cursor.getColumnIndexOrThrow(CallLog.Calls.DURATION));
String callType = "";
switch (type) {
case CallLog.Calls.INCOMING_TYPE:
callType = "Входящий";
break;
case CallLog.Calls.OUTGOING_TYPE:
callType = "Исходящий";
break;
case CallLog.Calls.MISSED_TYPE:
callType = "Пропущенный";
break;
case CallLog.Calls.REJECTED_TYPE:
callType = "Отклонённый";
break;
default:
callType = "Неизвестный";
break;
}
String date = DateFormat.format("dd.MM.yyyy HH:mm", new Date(dateMillis)).toString();
Log.d("CallLog", "Имя: " + (name != null ? name : "Неизвестно") +
", Номер: " + number +
", Тип: " + callType +
", Дата: " + date +
", Длительность: " + duration + " сек");
}
cursor.close();
}
}
На этом всё, надеюсь был полезен. если про что-то не рассказал пишите в кометы может сделаю 2ю часть.
Всем хорошего времени суток и пока!