Hiji poé kuring diperlukeun pikeun nyeken jaringan Wi-Fi tina aplikasi Android sarta meunangkeun data lengkep ngeunaan titik aksés.
Di dieu urang kedah nyanghareupan sababaraha kasusah:
Tulisan ieu ngabahas kumaha carana kéngingkeun data komprehensif ngeunaan lingkungan Wi-Fi tina kode Android tanpa NDK, hacks, tapi ngan ukur nganggo API Android sareng ngartos kumaha napsirkeunana.
Hayu urang teu reureuh tur mimitian nulis kode.
1. Jieun proyék
Catetan ieu dimaksudkeun pikeun jalma anu parantos nyiptakeun proyék Android langkung ti sakali, janten urang ngaleungitkeun detil barang ieu. Kodeu di handap bakal dibere dina Kotlin, minSdkVersion = 23.
2. Idin aksés
Pikeun damel sareng Wi-Fi tina aplikasi, anjeun kedah nampi sababaraha idin ti pangguna. Dumasarkeun kana
Janten, dina AndroidManifest.xml kami bakal nambihan:
<uses-permission android_name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android_name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android_name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android_name="android.permission.ACCESS_FINE_LOCATION"/>
Sareng dina kode anu ngandung tautan kana Kagiatan ayeuna:
import android.app.Activity
import android.content.Context
import android.location.LocationManager
import androidx.core.app.ActivityCompat
....
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
ActivityCompat.requestPermissions(
activity,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE),
1
)
makeEnableLocationServices(activity.applicationContext)
} else {
ActivityCompat.requestPermissions(
activity,
arrayOf(Manifest.permission.CHANGE_WIFI_STATE),
1
)
}
/* включает экран включения службы по определению местоположения */
fun makeEnableLocationServices(context: Context) {
// TODO: перед вызовом этой функции надо рассказать пользователю, зачем Вам доступ к местоположению
val lm: LocationManager =
context.applicationContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val gpsEnabled: Boolean = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
val networkEnabled: Boolean = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!gpsEnabled && !networkEnabled) {
context.startActivity(Intent(ACTION_LOCATION_SOURCE_SETTINGS));
}
}
3. Jieun BroadcastReceiver sarta ngalanggan acara update data ngeunaan scanning lingkungan jaringan Wi-Fi
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiScanReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
if (success) {
scanSuccess()
}
}
}
val intentFilter = IntentFilter()
/* подписываемся на сообщения о получении новых результатов сканирования */
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
context.registerReceiver(wifiScanReceiver, intentFilter)
val success = wifiManager.startScan()
if (!success) {
/* что-то не получилось при запуске сканирования, проверьте выданые разрешения */
}
....
private fun scanSuccess() {
/* вот они, результаты сканирования */
val results: List<ScanResult> = wifiManager.scanResults
}
Metodeu WiFiManager.startScan dina dokuméntasi ditandaan salaku depricated saprak versi API 28, tapi pareum.
Dina total, kami nampi daptar objék
4. Tingali di ScanResult tur ngartos istilah
Hayu urang tingali sababaraha widang kelas ieu sareng ngajelaskeun naon hartosna:
SSID — Service Set Identifier nyaéta ngaran jaringan
BSSID - Identifier Set Layanan Dasar - Alamat MAC tina adaptor jaringan (titik Wi-Fi)
tingkat - Indikator Kakuatan Sinyal Ditampi [dBm (dBm Rusia) - Decibel, kakuatan rujukan 1 mW.] - Indikator kakuatan sinyal anu ditampi. Butuh nilai ti 0 nepi ka -100, beuki jauh ti 0, kakuatan sinyal beuki leungit sapanjang jalan ti titik Wi-Fi ka alat Anjeun. Leuwih rinci bisa kapanggih, contona, di
val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
val numberOfLevels = 5
val level = WifiManager.calculateSignalLevel(level, numberOfLevels)
prekuensi — frékuénsi operasi titik Wi-Fi [Hz]. Salian frékuénsi sorangan, Anjeun bisa jadi kabetot dina disebut saluran. Unggal titik boga purity operasi sorangan. Dina waktos nyerat, rentang titik Wi-Fi anu paling populér nyaéta 2.4 GHz. Tapi, langkung tepatna, titik ngirimkeun inpormasi ka telepon anjeun dina frékuénsi wilangan anu caket sareng anu namina. Jumlah saluran jeung frékuénsi pakait
/* по частоте определяем номер канала */
val channel: Int
get() {
return if (frequency in 2412..2484) {
(frequency - 2412) / 5 + 1
} else if (frequency in 5170..5825) {
(frequency - 5170) / 5 + 34
} else {
-1
}
}
kamampuhan - widang paling metot pikeun analisis, gawé bareng nu diperlukeun loba waktu. Di dieu "kamampuan" titik ditulis dina garis. Dina hal ieu, anjeun teu kudu néangan wincik interpretasi string dina dokuméntasi. Ieu sababaraha conto naon anu aya dina garis ieu:
[WPA-PSK-TKIP+CCMP][WPA2-PSK-TKIP+CCMP][WPS][ESS]
[WPA2-PSK-CCMP][ESS]
[WPA2-PSK-CCMP+TKIP][ESS]
[WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS]
[ESS][WPS]
5. Ngartos singketan sareng kamampuan parsing
Perlu disebatkeun yén kelas tina pakét android.net.wifi.* dianggo di handapeun tiung ku utilitas Linux.
Urang bakal meta konsistén. Hayu urang mimiti nganggap kaluaran format dimana elemen dina jero kurung dipisahkeun ku tanda "-":
[WPA-PSK-TKIP+CCMP]
[WPA2-PSK-CCMP]
Harti kahiji nerangkeun nu disebut. métode auténtikasi. Nyaéta, naon urutan tindakan anu kedah dilakukeun ku alat sareng titik aksés supados titik aksés tiasa dianggo sareng kumaha cara énkripsi payload. Dina waktos nyerat tulisan ieu, pilihan anu paling umum nyaéta WPA sareng WPA2, dimana unggal alat anu disambungkeun langsung atanapi ngalangkungan anu disebut. Server RADIUS (WPA-Enterprice) nyadiakeun kecap akses dina saluran énkripsi. Paling dipikaresep, titik aksés di imah anjeun nyadiakeun sambungan nurutkeun skéma ieu. Beda antara versi kadua sareng anu kahiji nyaéta yén éta gaduh cipher anu langkung kuat: AES versus TKIP anu teu aman. WPA3, anu langkung kompleks sareng canggih, ogé laun-laun diwanohkeun. Sacara téoritis, meureun aya pilihan sareng solusi enterprice CCKM (Cisco Centralized Key Management), tapi kuring henteu pernah mendakan éta.
Titik aksés meureun geus ngonpigurasi pikeun auténtikasi ku alamat MAC. Atawa, lamun titik aksés nyadiakeun data ngagunakeun algoritma WEP luntur, lajeng aya sabenerna euweuh auténtikasi (konci rusiah didieu nyaeta konci enkripsi). Urang mengklasifikasikan pilihan sapertos LAIN.
Aya ogé metode anu populer di wi-fi umum sareng Deteksi Portal Captive disumputkeun - pamundut auténtikasi ngalangkungan browser. Titik aksés sapertos kitu muncul dina scanner salaku muka (anu aranjeunna tina sudut pandang sambungan fisik). Ku alatan éta, urang mengklasifikasikan aranjeunna salaku OPEN.
Nilai kadua bisa dilambangkeun salaku algoritma manajemén konci. Ieu mangrupikeun parameter tina metodeu auténtikasi anu dijelaskeun di luhur. Talks ngeunaan persis kumaha konci enkripsi disilihtukeurkeun. Hayu urang nganggap pilihan mungkin. EAP - dipaké dina WPA-Enterprice disebutkeun, ngagunakeun database pikeun pariksa data auténtikasi diasupkeun. SAE - dipaké dina WPA3 canggih, leuwih tahan ka gaya BRUTE. PSK - pilihan anu paling umum, kalebet ngalebetkeun kecap konci sareng ngirimkeunana dina bentuk énkripsi. IEEE8021X - numutkeun standar internasional (béda sareng anu dirojong ku kulawarga WPA). OWE (Opportunistic Wireless Encryption) mangrupikeun penyuluhan standar IEEE 802.11 pikeun titik anu kami digolongkeun kana OPEN. OWE mastikeun kaamanan data anu dikirimkeun kana jaringan anu teu aman ku cara énkripsi. Hiji pilihan oge mungkin lamun euweuh kenop aksés, hayu urang nelepon pilihan ieu NONE.
Parameter katilu anu disebut. skéma énkripsi — kumaha kahayang cipher dipaké pikeun ngajaga data dikirimkeun. Hayu urang daptar pilihan. WEP - ngagunakeun cipher stream RC4, konci rusiah nyaéta konci enkripsi, nu dianggap unacceptable di dunya kriptografi modern. TKIP - dipaké dina WPA, CKIP - dina WPA2. TKIP+CKIP - tiasa disaluyukeun dina titik anu tiasa WPA sareng WPA2 pikeun kasaluyuan mundur.
Gantina tilu elemen, anjeun tiasa mendakan tanda WEP anu sepi:
[WEP]
Salaku urang bahas di luhur, ieu cukup teu nangtukeun algoritma pikeun pamakéan konci, nu teu aya, sarta metoda enkripsi, nu sarua sacara standar.
Ayeuna mertimbangkeun bracket ieu:
[ESS]
ieu Modeu operasi Wi-Fi atawa Topologi jaringan Wi-Fi. Anjeun tiasa sapatemon mode BSS (Basic Service Set) - lamun aya hiji titik aksés ngaliwatan alat nu disambungkeun komunikasi. Bisa kapanggih dina jaringan lokal. Sakumaha aturan, titik aksés diperlukeun pikeun nyambungkeun alat ti jaringan lokal béda, jadi aranjeunna bagian tina Extended Service Sets - ESS. Jinis IBSSs (Set Layanan Dasar Independen) nunjukkeun yén alat éta bagian tina jaringan Peer-to-Peer.
Anjeun ogé tiasa ningali bandéra WPS:
[WPS]
WPS (Wi-Fi Protected Setup) nyaéta protokol pikeun inisialisasi semi-otomatis jaringan Wi-Fi. Pikeun initialize, pamaké boh ngasupkeun sandi 8 karakter atawa mencét hiji tombol dina router dina. Upami titik aksés anjeun tina jinis anu munggaran sareng kotak centang ieu nembongan di gigireun nami titik aksés anjeun, anjeun disarankeun pisan pikeun muka panel admin sareng nganonaktipkeun aksés WPS. Kanyataan yén PIN 8-angka sering tiasa dipendakan ku alamat MAC, atanapi tiasa diurutkeun dina waktos anu tiasa diramalkeun, anu tiasa dimanfaatkeun ku jalma anu teu jujur.
6. Jieun model jeung fungsi parsing
Dumasar naon anu urang mendakan di luhur, urang bakal ngajelaskeun naon anu kajantenan nganggo kelas data:
/* схема аутентификации */
enum class AuthMethod {
WPA3,
WPA2,
WPA, // Wi-Fi Protected Access
OTHER, // включает в себя Shared Key Authentication и др. использующие mac-address-based и WEP
CCKM, // Cisco
OPEN // Open Authentication. Может быть со скрытым Captive Portal Detection - запрос аутентификации через браузер
}
/* алгоритм ввода ключей */
enum class KeyManagementAlgorithm {
IEEE8021X, // по стандарту
EAP, // Extensible Authentication Protocol, расширяемый протокол аутентификации
PSK, // Pre-Shared Key — каждый узел вводит пароль для доступа к сети
WEP, // в WEP пароль является ключом шифрования (No auth key)
SAE, // Simultaneous Authentication of Equals - может быть в WPA3
OWE, // Opportunistic Wireless Encryption - в роутерах новых поколений, публичных сетях типа OPEN
NONE // может быть без шифрования в OPEN, OTHER
}
/* метод шифрования */
enum class CipherMethod {
WEP, // Wired Equivalent Privacy, Аналог шифрования трафика в проводных сетях
TKIP, // Temporal Key Integrity Protocol
CCMP, // Counter Mode with Cipher Block Chaining Message Authentication Code Protocol,
// протокол блочного шифрования с кодом аутентичности сообщения и режимом сцепления блоков и счетчика
// на основе AES
NONE // может быть без шифрования в OPEN, OTHER
}
/* набор методов шифрования и протоколов, по которым может работать точка */
data class Capability(
var authScheme: AuthMethod? = null,
var keyManagementAlgorithm: KeyManagementAlgorithm? = null,
var cipherMethod: CipherMethod? = null
)
/* Режим работы WiFi (или топология сетей WiFi) */
enum class TopologyMode {
IBSS, // Эпизодическая сеть (Ad-Hoc или IBSS – Independent Basic Service Set).
BSS, // Основная зона обслуживания Basic Service Set (BSS) или Infrastructure Mode.
ESS // Расширенная зона обслуживания ESS – Extended Service Set.
}
Ayeuna hayu urang nulis hiji fungsi anu bakal parse widang kamampuhan:
private fun parseCapabilities(capabilitiesString: String): List < Capability > {
val capabilities: List < Capability > = capabilitiesString
.splitByBrackets()
.filter {
!it.isTopology() && !it.isWps()
}
.flatMap {
parseCapability(it)
}
return
if (!capabilities.isEmpty()) {
capabilities
} else {
listOf(Capability(AuthMethod.OPEN, KeyManagementAlgorithm.NONE, CipherMethod.NONE))
}
}
private fun parseCapability(part: String): List < Capability > {
if (part.contains("WEP")) {
return listOf(Capability(
AuthMethod.OTHER,
KeyManagementAlgorithm.WEP,
CipherMethod.WEP
))
}
val authScheme = when {
part.contains("WPA3") - > AuthMethod.WPA3
part.contains("WPA2") - > AuthMethod.WPA2
part.contains("WPA") - > AuthMethod.WPA
else - > null
}
val keyManagementAlgorithm = when {
part.contains("OWE") - > KeyManagementAlgorithm.OWE
part.contains("SAE") - > KeyManagementAlgorithm.SAE
part.contains("IEEE802.1X") - > KeyManagementAlgorithm.IEEE8021X
part.contains("EAP") - > KeyManagementAlgorithm.EAP
part.contains("PSK") - > KeyManagementAlgorithm.PSK
else - > null
}
val capabilities = ArrayList < Capability > ()
if (part.contains("TKIP") || part.contains("CCMP")) {
if (part.contains("TKIP")) {
capabilities.add(Capability(
authScheme ? : AuthMethod.OPEN,
keyManagementAlgorithm ? : KeyManagementAlgorithm.NONE,
CipherMethod.TKIP
))
}
if (part.contains("CCMP")) {
capabilities.add(Capability(
authScheme ? : AuthMethod.OPEN,
keyManagementAlgorithm ? : KeyManagementAlgorithm.NONE,
CipherMethod.CCMP
))
}
} else if (authScheme != null || keyManagementAlgorithm != null) {
capabilities.add(Capability(
authScheme ? : AuthMethod.OPEN,
keyManagementAlgorithm ? : KeyManagementAlgorithm.NONE,
CipherMethod.NONE
))
}
return capabilities
}
private fun parseTopologyMode(capabilitiesString: String): TopologyMode ? {
return capabilitiesString
.splitByBrackets()
.mapNotNull {
when {
it.contains("ESS") - > TopologyMode.ESS
it.contains("BSS") - > TopologyMode.BSS
it.contains("IBSS") - > TopologyMode.IBSS
else - > null
}
}
.firstOrNull()
}
private fun parseWPSAvailable(capabilitiesString: String): Boolean {
return capabilitiesString
.splitByBrackets()
.any {
it.isWps()
}
}
private fun String.splitByBrackets(): List < String > {
val m = Pattern.compile("[(.*?)]").matcher(this)
val parts = ArrayList < String > ()
while (m.find()) {
parts.add(m.group().replace("[", "").replace("]", ""))
}
return parts
}
private fun String.isTopology(): Boolean {
return TopologyMode.values().any {
this == it.name
}
}
private fun String.isWps(): Boolean {
return this == "WPS"
}
8. Tempo hasilna
Kuring bakal nyeken jaringan sareng nunjukkeun ka anjeun naon anu kuring mendakan. Ditémbongkeun mangrupa hasil kaluaran basajan via Log.d:
Capability of Home-Home [WPA2-PSK-CCMP][ESS][WPS]
...
capabilities=[Capability(authScheme=WPA2, keyManagementAlgorithm=PSK, cipherMethod=CCMP)], topologyMode=ESS, availableWps=true
Isu nyambungkeun ka jaringan tina kode aplikasi tetep unexamined. Kuring ngan bakal nyebutkeun yén dina urutan maca sandi disimpen tina OS tina alat mobile, anjeun peryogi hak root na kahayang rummage ngaliwatan sistem file maca wpa_supplicant.conf. Lamun logika aplikasi merlukeun ngasupkeun sandi ti luar, sambungan bisa dijieun ngaliwatan kelas
Спасибо
Upami anjeun nyangka aya anu kedah ditambihan atanapi dilereskeun, tulis dina koméntar :)
sumber: www.habr.com