Eräänä päivänä minun piti skannata Wi-Fi-verkkoja Android-sovelluksista ja saada yksityiskohtaisia tietoja tukiasemista.
Tässä meidän oli kohdattava useita vaikeuksia:
Tässä artikkelissa käsitellään kattavan tiedon hankkimista Wi-Fi-ympäristöstä Android-koodista ilman NDK:ta, hakkeroita, mutta vain Android-sovellusliittymän avulla ja miten sitä tulkitaan.
Älä viivyttele ja aloita koodin kirjoittaminen.
1. Luo projekti
Tämä huomautus on tarkoitettu niille, jotka ovat luoneet Android-projektin useammin kuin kerran, joten jätämme pois tämän kohdan yksityiskohdat. Alla oleva koodi esitetään Kotlinissa, minSdkVersion=23.
2. Käyttöoikeudet
Jotta voit työskennellä sovelluksen Wi-Fi-yhteyden kanssa, sinun on hankittava käyttäjältä useita käyttöoikeuksia. Mukaisesti
Joten, AndroidManifest.xml lisäämme:
<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"/>
Ja koodissa, joka sisältää linkin nykyiseen toimintoon:
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. Luo BroadcastReceiver ja tilaa Wi-Fi-verkkoympäristön skannausta koskevat datapäivitystapahtumat
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
}
Dokumentaation WiFiManager.startScan-menetelmä on merkitty poistetuksi API-versiosta 28 lähtien, mutta pois käytöstä.
Yhteensä saimme luettelon esineistä
4. Katso ScanResult ja ymmärrä ehdot
Tarkastellaan joitain tämän luokan kenttiä ja kuvataan, mitä ne tarkoittavat:
SSID — Service Set Identifier on verkon nimi
BSSID – Basic Service Set Identifier – verkkosovittimen MAC-osoite (Wi-Fi-piste)
taso — Vastaanotetun signaalin voimakkuuden ilmaisin [dBm (venäläinen dBm) — Desibeli, vertailuteho 1 mW.] — Vastaanotetun signaalin voimakkuuden ilmaisin. Ottaa arvon väliltä 0–100, mitä kauempana arvosta 0, sitä enemmän signaalitehoa katosi matkalla Wi-Fi-pisteestä laitteeseesi. Tarkempia tietoja löytyy esimerkiksi osoitteesta
val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
val numberOfLevels = 5
val level = WifiManager.calculateSignalLevel(level, numberOfLevels)
taajuus — Wi-Fi-pisteen toimintataajuus [Hz]. Itse taajuuden lisäksi saatat olla kiinnostunut ns. kanavasta. Jokaisella pisteellä on oma toimintapuhtautensa. Kirjoitushetkellä suosituin Wi-Fi-pistealue on 2.4 GHz. Mutta tarkemmin sanottuna piste lähettää tietoja puhelimeesi numeroidulla taajuudella, joka on lähellä nimettyä. Kanavien lukumäärä ja vastaavat taajuudet
/* по частоте определяем номер канала */
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
}
}
kyvyt - mielenkiintoisin analyysiala, jonka kanssa työskentely vaati paljon aikaa. Täällä pisteen "ominaisuudet" on kirjoitettu riville. Tässä tapauksessa sinun ei tarvitse etsiä tietoja merkkijonojen tulkinnasta dokumentaatiosta. Tässä on esimerkkejä siitä, mitä tällä rivillä voi olla:
[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. Lyhenteiden ymmärtäminen ja jäsennysominaisuudet
On syytä mainita, että android.net.wifi.*-paketin luokkia käyttää konepellin alla Linux-apuohjelma
Toimimme johdonmukaisesti. Tarkastellaan ensin sellaisen muodon tulosta, jossa suluissa olevat elementit erotetaan "-"-merkillä:
[WPA-PSK-TKIP+CCMP]
[WPA2-PSK-CCMP]
Ensimmäinen merkitys kuvaa ns. todennus tapa. Eli mikä toimintosarja laitteen ja tukiaseman on suoritettava, jotta tukiasema sallii itsensä käytön ja miten hyötykuorma salataan. Tätä postausta kirjoitettaessa yleisimmät vaihtoehdot ovat WPA ja WPA2, joissa joko kukin kytketty laite suoraan tai ns. RADIUS-palvelin (WPA-Enterprice) tarjoaa salasanan salatun kanavan kautta. Todennäköisesti kotisi tukiasema tarjoaa yhteyden tämän järjestelmän mukaisesti. Ero toisen version ja ensimmäisen välillä on, että siinä on vahvempi salaus: AES vs. turvaton TKIP. Myös WPA3, joka on monimutkaisempi ja edistyneempi, otetaan vähitellen käyttöön. Teoriassa voi olla vaihtoehto yritysratkaisulla CCKM (Cisco Centralised Key Management), mutta en ole koskaan törmännyt siihen.
Tukiasema on ehkä määritetty todentamaan MAC-osoitteen perusteella. Tai jos tukiasema tarjoaa tietoja vanhentuneen WEP-algoritmin avulla, todennusta ei todellisuudessa ole (salainen avain tässä on salausavain). Luokittelemme tällaiset vaihtoehdot MUIHIN.
On olemassa myös menetelmä, joka on suosittu julkisessa wi-fi:ssä piilotetulla Captive Portal Detection -tunnistuksella - todennuspyyntö selaimen kautta. Tällaiset tukiasemat näyttävät skannerille avoimina (mitä ne ovat fyysisen yhteyden kannalta). Siksi luokittelemme ne AVOIN.
Toinen arvo voidaan merkitä nimellä avainten hallintaalgoritmi. Tämä on edellä kuvatun todennusmenetelmän parametri. Puhuu tarkalleen kuinka salausavaimia vaihdetaan. Mietitään mahdollisia vaihtoehtoja. EAP - käytetty mainitussa WPA-Enterpricessä, käyttää tietokantaa syötettyjen todennustietojen tarkistamiseen. SAE - käytetty edistyneessä WPA3:ssa, kestää paremmin raakaa voimaa. PSK - yleisin vaihtoehto, sisältää salasanan syöttämisen ja sen lähettämisen salatussa muodossa. IEEE8021X - kansainvälisen standardin mukainen (erilainen kuin WPA-perheen tukema). OWE (Opportunistic Wireless Encryption) on IEEE 802.11 -standardin laajennus pisteisiin, jotka olemme luokitellut AVOIN. OWE varmistaa suojaamattoman verkon kautta siirrettävien tietojen turvallisuuden salaamalla ne. Vaihtoehto on myös mahdollinen, kun avaimia ei ole, kutsutaan tätä vaihtoehtoa EI MITÄÄN.
Kolmas parametri on ns. salausjärjestelmiä — kuinka tarkasti salausta käytetään siirrettyjen tietojen suojaamiseen. Listataan vaihtoehdot. WEP - käyttää RC4-virtasalausta, salainen avain on salausavain, jota ei pidetä hyväksyttävänä nykyaikaisen kryptografian maailmassa. TKIP - käytössä WPA:ssa, CKIP - WPA2:ssa. TKIP+CKIP - voidaan määrittää WPA- ja WPA2-yhteensopiviin kohtiin taaksepäin yhteensopivuuden takaamiseksi.
Kolmen elementin sijasta löydät yksinäisen WEP-merkin:
[WEP]
Kuten edellä käsittelimme, tämä riittää, jotta ei määritetä avaimien käytön algoritmia, jota ei ole olemassa, ja salausmenetelmää, joka on oletuksena sama.
Harkitse nyt tätä hakasuljetta:
[ESS]
Se Wi-Fi-käyttötila tai Wi-Fi-verkon topologia. Saatat kohdata BSS (Basic Service Set) -tilan - kun on yksi tukiasema, jonka kautta yhdistetyt laitteet kommunikoivat. Löytyy paikallisista verkoista. Pääsääntöisesti liityntäpisteitä tarvitaan eri paikallisten verkkojen laitteiden yhdistämiseen, joten ne ovat osa Extended Service Sets - ESS -palvelua. IBSS-tyyppi (Independent Basic Service Sets) osoittaa, että laite on osa vertaisverkkoa.
Saatat myös nähdä WPS-lipun:
[WPS]
WPS (Wi-Fi Protected Setup) on protokolla Wi-Fi-verkon puoliautomaattiseen alustukseen. Alustaakseen käyttäjä joko syöttää 8-merkkisen salasanan tai paina reitittimen painiketta. Jos tukiasemasi on ensimmäistä tyyppiä ja tämä valintaruutu näkyy tukiasemasi nimen vieressä, sinun on erittäin suositeltavaa siirtyä hallintapaneeliin ja poistaa WPS-käyttö käytöstä. Tosiasia on, että usein 8-numeroinen PIN-koodi voidaan selvittää MAC-osoitteen perusteella tai se voidaan selvittää ennakoitavissa olevassa ajassa, jota joku voi epärehellisesti hyödyntää.
6. Luo malli ja jäsennysfunktio
Sen perusteella, mitä yllä saimme selville, kuvaamme tapahtumia tietoluokkien avulla:
/* схема аутентификации */
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.
}
Kirjoita nyt funktio, joka jäsentää ominaisuuskentän:
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. Katso tulos
Selailen verkon ja näytän mitä löysin. Näytetään yksinkertaisen tulostuksen tulokset Log.d:n kautta:
Capability of Home-Home [WPA2-PSK-CCMP][ESS][WPS]
...
capabilities=[Capability(authScheme=WPA2, keyManagementAlgorithm=PSK, cipherMethod=CCMP)], topologyMode=ESS, availableWps=true
Ongelma verkkoon liittymisestä sovelluskoodista jäi tutkimatta. Sanon vain, että jotta voit lukea tallennettuja salasanoja mobiililaitteen käyttöjärjestelmästä, tarvitset pääkäyttäjän oikeudet ja halukkuuden selata tiedostojärjestelmää lukeaksesi wpa_supplicant.conf. Jos sovelluslogiikka vaatii salasanan syöttämistä ulkopuolelta, yhteys voidaan muodostaa luokan kautta
Kiitos
Jos uskot, että jotain kaipaa lisäystä tai korjausta, kirjoita kommentteihin :)
Lähde: will.com