Wi-Fi ak anpil lòt abrevyasyon. Tankou nan Android Jwenn done sou nœuds Wi-Fi nan aplikasyon an san ou pa santi w akable.

Yon jou mwen te bezwen eskane soti nan Android Aplikasyon rezo Wi-Fi epi jwenn done detaye sou pwen aksè yo.

Isit la nou te gen pou fè fas a plizyè difikilte: dokiman ofisyèl Android anpil nan klas ki dekri yo te demode (nivo API > 26), ki pa t reflete ladan l; deskripsyon kèk bagay nan dokiman an se minim (pa egzanp, domèn kapasite nan klas la ScanResult nan moman ekri a, prèske pa gen anyen ki dekri, byenke li gen anpil done enpòtan). Twazyèm difikilte a ka kouche nan lefèt ke lè ou premye jwenn tou pre Wi-Fi, lòt pase li teyori a ak mete kanpe routeur la atravè localhost, ou dwe fè fas ak yon kantite abrevyasyon ki sanble konprann endividyèlman. Men, li ka pa evidan ki jan yo gen rapò ak estrikti yo (jijman se subjectif epi li depann de eksperyans anvan).

Atik sa a diskite kijan Android kòd pou jwenn done konplè sou anviwònman Wi-Fi a san NDK, piratage, men sèlman avèk èd Android API yo epi konprann kijan pou entèprete yo.

Ann pa pran reta epi kòmanse ekri kòd.

1. Kreye yon pwojè

Nòt sa a fèt pou moun ki te kreye plis pase yon fwa Android pwojè a, kidonk nou pral sote detay seksyon sa a. Kòd ki anba a pral prezante nan Kotlin, minSdkVersion=23.

2. Aksè otorizasyon

Pou travay ak Wi-Fi nan aplikasyon an, w ap bezwen jwenn plizyè otorizasyon nan men itilizatè a. An akò avèk dokimantasyon, yo nan lòd yo eskane rezo a sou aparèy ki gen vèsyon OS apre 8.0, anplis aksè nan gade eta a nan anviwònman rezo a, ou bezwen swa aksè chanje eta a nan modil Wi-Fi aparèy la, oswa aksè nan kowòdone (apeprè oswa egzak). Kòmanse ak vèsyon 9.0, ou dwe mande itilizatè a pou tou de, epi tou li klèman mande itilizatè a limen sèvis lokal yo. Pa bliye esplike itilizatè a avèk galan ke sa a se kapris Google, epi li pa dezi nou al rekonèt li :)

An total, nan AndroidAjoute Manifest.xml:

    <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"/>

Ak nan kòd la ki gen yon lyen nan Aktivite aktyèl la:

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. Kreye yon BroadcastReceiver epi abònman nan evènman aktyalizasyon done sou analiz anviwònman rezo 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
}

Metòd WiFiManager.startScan nan dokiman an make kòm depricate depi vèsyon API 28, men koupe. gide sijere itilize li.

An total, nou te resevwa yon lis objè yo ScanResult.

4. Gade ScanResult epi konprann tèm yo

Ann gade kèk domèn nan klas sa a epi dekri sa yo vle di:

Ssid — Service Set Identifier se non rezo a

BSSID – Idantifyan seri sèvis debaz – adrès MAC adaptè rezo a (pwen Wi-Fi)

nivo — Endikatè Fòs Siyal Resevwa [dBm (Ris dBm) — Desibel, pouvwa referans 1 mW.] — Yon endikatè fòs siyal la resevwa. Pran yon valè ki soti nan 0 a -100, pi lwen soti nan 0, plis pouvwa a siyal te pèdi sou wout la soti nan pwen an Wi-Fi nan aparèy ou an. Ou ka jwenn plis detay, pou egzanp, nan WikipediaMen sa m ap di w kisa pou w fè avèk èd Android klas WifiManager ou ka kalibre nivo siyal la sou yon echèl soti nan ekselan rive terib nan etap ou chwazi a:

        val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val numberOfLevels = 5
        val level = WifiManager.calculateSignalLevel(level, numberOfLevels)

frekans — frekans opere nan pwen an Wi-Fi [Hz]. Anplis de frekans nan tèt li, ou ka enterese nan sa yo rele kanal la. Chak pwen gen pwòp pite opere li yo. Nan moman sa a nan ekri a, seri ki pi popilè nan pwen Wi-Fi se 2.4 GHz. Men, pou yo ka pi egzak, pwen an transmèt enfòmasyon nan telefòn ou nan yon frekans nimewote tou pre youn nan non yo. Kantite chanèl ak frekans korespondan yo estandadize. Sa a se fè pou pwen ki tou pre yo opere nan diferan frekans, kidonk pa entèfere youn ak lòt epi yo pa mityèlman diminye vitès la ak kalite transmisyon. Nan ka sa a, pwen yo opere pa nan yon sèl frekans, men sou yon seri de frekans (paramèt channelWidth), yo rele lajè kanal la. Sa vle di, pwen opere sou adjasan (e pa sèlman adjasan, men menm 3 soti nan tèt yo) chanèl entèfere youn ak lòt. Ou ka jwenn kòd senp sa a itil, ki pèmèt ou kalkile nimewo chanèl la apati valè frekans lan pou pwen ki gen yon frekans 2.4 ak 5 Ghz:


    /* по частоте определяем номер канала */
    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
            }
        }

kapasite - jaden ki pi enteresan pou analiz, travay ak ki te mande anpil tan. Isit la "kapasite yo" nan pwen an yo ekri nan liy lan. Nan ka sa a, ou pa bezwen chèche detay sou entèpretasyon fisèl nan dokiman an. Men kèk egzanp sou sa ki ka nan liy sa a:

[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. Konprann abrevyasyon ak analiz kapasite

Li vo mansyone ke klas yo nan pake android.net.wifi.* yo itilize anba kapo a pa yon sèvis piblik Linux. wpa_supplicant ak rezilta pwodiksyon an nan jaden kapasite yo se yon kopi jaden drapo yo lè optik.

Nou pral aji toujou. Se pou premye konsidere pwodiksyon an nan yon fòma kote eleman ki andedan parantèz yo separe pa yon siy "-":

[WPA-PSK-TKIP+CCMP]
[WPA2-PSK-CCMP]

Premye siyifikasyon an dekri sa yo rele. metòd otantifikasyon. Sa vle di, ki sekans aksyon aparèy la ak pwen aksè a dwe fè pou pwen aksè a pèmèt tèt li sèvi ak kijan pou ankripte chaj la. Nan moman sa a nan ekri pòs sa a, opsyon ki pi komen yo se WPA ak WPA2, nan ki swa chak aparèy konekte dirèkteman oswa atravè sa yo rele. Sèvè RADIUS la (WPA-Enterprice) bay modpas la sou yon chanèl chiffres. Gen plis chans, pwen aksè nan kay ou a bay yon koneksyon dapre konplo sa a. Diferans ki genyen ant dezyèm vèsyon an ak premye a se ke li gen yon chifreman pi fò: AES kont TKIP a ensekirite. WPA3, ki se pi konplèks ak avanse, tou piti piti ke yo te prezante. Teyorikman, ka gen yon opsyon ak solisyon enterprice CCKM (Cisco Centralized Key Management), men mwen pa janm vin jwenn li.

Pwen aksè a ka te configuré pou otantifye pa adrès MAC. Oswa, si pwen aksè a bay done lè l sèvi avèk algorithm WEP demode, Lè sa a, pa gen aktyèlman otantifikasyon (kle sekrè isit la se kle chifreman an). Nou klase opsyon sa yo kòm LÒT.
Genyen tou yon metòd ki popilè nan wi-fi piblik ak kache Captive Portal Deteksyon - yon demann otantifikasyon atravè yon navigatè. Pwen aksè sa yo parèt nan eskanè a kòm ouvè (ki yo soti nan pwen de vi koneksyon fizik la). Se poutèt sa, nou klase yo kòm OUVRI.

Dezyèm valè a ka endike kòm algorithm jesyon kle. Sa a se yon paramèt metòd otantifikasyon ki dekri pi wo a. Pale sou egzakteman ki jan kle chifreman yo echanje. Ann konsidere opsyon posib yo. EAP - itilize nan mansyone WPA-Enterprice, sèvi ak yon baz done pou verifye done otantifikasyon yo antre. SAE - yo itilize nan WPA3 avanse, pi rezistan a fòs brital. PSK - opsyon ki pi komen, enplike nan antre nan yon modpas ak transmèt li nan fòm chiffres. IEEE8021X - dapre yon estanda entènasyonal (diferan de sa ki sipòte pa fanmi WPA). OWE (Opportunistic Wireless Encryption) se yon ekstansyon estanda IEEE 802.11 pou pwen ke nou klase kòm OPEN. OWE asire sekirite done yo transmèt sou yon rezo ki pa an sekirite lè li kode li. Yon opsyon posib tou lè pa gen okenn kle aksè, ann rele opsyon sa a Okenn.

Twazyèm paramèt la se sa yo rele. rapid chifreman — ki jan egzakteman chifre yo itilize pou pwoteje done yo transmèt yo. Ann fè lis opsyon yo. WEP - sèvi ak yon chifreman kouran RC4, kle sekrè a se kle a chifreman, ki konsidere kòm akseptab nan mond lan nan kriptografik modèn. TKIP - itilize nan WPA, CKIP - nan WPA2. TKIP + CKIP - yo ka espesifye nan pwen ki kapab WPA ak WPA2 pou konpatibilite bak.

Olye de twa eleman, ou ka jwenn yon mak WEP poukont:

[WEP]

Kòm nou diskite pi wo a, sa a se ase pa presize algorithm la pou itilize kle, ki pa egziste, ak metòd la chifreman, ki se menm bagay la pa default.

Koulye a, konsidere parantèz sa a:

[ESS]

Li Mòd fonksyone Wi-Fi oswa Topoloji rezo Wi-Fi. Ou ka rankontre mòd BSS (Basic Service Set) - lè gen yon pwen aksè kote aparèy ki konekte yo kominike. Ou ka jwenn sou rezo lokal yo. Kòm yon règ, pwen aksè yo bezwen konekte aparèy ki soti nan diferan rezo lokal yo, kidonk yo fè pati Ansanm Sèvis Pwolonje - ESS. Kalite IBSSs (Independent Basic Service Sets) endike ke aparèy la fè pati yon rezo Peer-to-Peer.

Ou ka wè tou drapo WPS la:

[WPS]

WPS (Wi-Fi Protected Setup) se yon pwotokòl pou inisyalizasyon semi-otomatik yon rezo Wi-Fi. Pou inisyalize, itilizatè a swa antre nan yon modpas 8 karaktè oswa peze yon bouton sou routeur la. Si pwen aksè ou a se nan premye kalite a epi kaz sa a parèt akote non pwen aksè ou a, ou rekòmande fòtman ale nan panèl admin la epi enfim aksè WPS. Reyalite a se ke souvan PIN nan 8 chif ka jwenn soti nan adrès MAC la, oswa li ka klase soti nan yon tan previzib, ki yon moun malonètman ka pran avantaj de.

6. Kreye yon modèl ak fonksyon analiz

Dapre sa nou te jwenn pi wo a, nou pral dekri sa ki te pase lè l sèvi avèk klas done yo:

/* схема аутентификации */
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.
}

Koulye a, ann ekri yon fonksyon ki pral analize jaden kapasite yo:


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. Gade rezilta a

Mwen pral eskane rezo a epi montre w sa mwen jwenn. Yo montre rezilta pwodiksyon senp atravè Log.d:

Capability of Home-Home [WPA2-PSK-CCMP][ESS][WPS]
...
capabilities=[Capability(authScheme=WPA2, keyManagementAlgorithm=PSK, cipherMethod=CCMP)], topologyMode=ESS, availableWps=true

Pwoblèm nan konekte nan rezo a soti nan kòd aplikasyon an rete san egzamine. Mwen pral sèlman di ke yo nan lòd yo li modpas yo sove nan eksplwatasyon an nan yon aparèy mobil, ou bezwen dwa rasin ak yon volonte pou fouye nan sistèm nan dosye li wpa_supplicant.conf. Si lojik aplikasyon an mande pou antre yon modpas soti deyò, koneksyon an ka fèt atravè klas la android.net.wifi.WifiManager.

Mèsi Egor Ponomarev pou ajoute ki gen anpil valè.

Si ou panse yon bagay bezwen ajoute oswa korije, ekri nan kòmantè yo :)

Sous: www.habr.com

Achte hosting serye pou sit ki gen pwoteksyon DDoS, sèvè VPS VDS 🔥 Achte yon hébergement sit entènèt serye ak pwoteksyon DDoS, sèvè VPS VDS | ProHoster