Filter Paket Android

Android Packet Filter (APF) memungkinkan framework mengontrol logika pemfilteran paket perangkat keras saat runtime. Hal ini memungkinkan sistem menghemat daya dengan menghapus paket di perangkat keras, sekaligus memungkinkan framework Android mengubah aturan pemfilteran saat runtime berdasarkan kondisi jaringan.

Ikhtisar APF

APF terdiri dari dua komponen utama:

  • Penerjemah APF berjalan pada perangkat keras jaringan (biasanya, chipset Wi-Fi). Penerjemah APF menjalankan bytecode APF pada paket yang diterima oleh perangkat keras dan memutuskan apakah akan menerima atau membuangnya.
  • Kode pembuatan program APF berjalan pada CPU utama. Kode ini membuat dan memperbarui program APF sesuai dengan status jaringan dan perangkat.

Metode Wi-Fi HAL memungkinkan kerangka Android menginstal bytecode program APF dan membaca penghitung saat ini. Modul Network Stack Mainline dapat memperbarui bytecode program APF kapan saja saat APF sedang berjalan.

Ada beberapa filter APF yang diterapkan. Misalnya, APF menyertakan filter untuk menghapus ethertype yang tidak diizinkan, memfilter paket iklan router IPv6 (RA), memfilter lalu lintas multicast dan siaran jika kunci multicast tidak ditahan, menghapus paket DHCP untuk host lain, dan menghapus protokol resolusi alamat yang tidak diminta (ARP) dan (penemuan tetangga) paket ND. Daftar lengkap filter ditentukan di ApfFilter .

Karena kode pembuatan program APF adalah bagian dari modul Network Stack, logika pemfilteran dapat diperbarui, dan filter baru dapat ditambahkan, melalui pembaruan Mainline bulanan.

Integrasi APF

API APF didefinisikan dalam apf_interpreter.h . Kode firmware Wi-Fi memanggil int accept_packet() untuk menentukan apakah paket harus dibuang (nilai pengembalian nol) atau diteruskan (nilai pengembalian bukan nol). Instruksi APF memiliki panjang yang bervariasi. Setiap instruksi panjangnya setidaknya satu byte. Kode instruksi APF didefinisikan dalam apf.h .

APF mengandalkan memori khusus. Memori digunakan baik untuk program APF itu sendiri maupun untuk penyimpanan data, dan memori tidak boleh dihapus atau ditulis oleh chipset kecuali melalui metode APF HAL. Bytecode APF menggunakan penyimpanan data untuk menyimpan penghitung paket yang diterima dan dijatuhkan. Wilayah data dapat dibaca dari kerangka Android. Jumlah minimum memori yang tersedia untuk APF harus 1024 byte.

Men-debug APF

Untuk memeriksa apakah APF diaktifkan pada perangkat, menampilkan program saat ini, dan menampilkan penghitung saat ini, jalankan perintah adb shell dumpsys network_stack . Berikut ini adalah contoh dari perintah ini:

adb shell dumpsys network_stack
......
IpClient.wlan0 APF dump:
    Capabilities: ApfCapabilities{version: 4, maxSize: 4096, format: 1}
......
    Last program:
      6bfcb03a01b8120c6b9494026506006b907c025e88a27c025988a47c025488b87c024f88cd7c024a88e17c024588e384004408066a0e6bdca4022b000600010800060412147a1e016bd884021f00021a1c6b8c7c021c0000686bd4a402080006ffffffffffff6a266bbca402010004c0a801eb6bf87401f6120c84005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506c2fc393057dd6bf47401cb0a1e52f06bac7c01c600e06bb41a1e7e000001b9ffffffff6bb07e000001aec0a801ff6be868a4019a0006ffffffffffff6bb874019b6bf07401907c001386dd686bd0a4017d0006ffffffffffff6bc874017e0a147a0e3a6b980a267c017000ff6be07401650a366ba87c016200858219886a26a2050fff02000000000000000000000000006ba4740146aa0e84013700e6aa0f8c0130006068a4011b000f33330000000184c9b26aed4c86dd606a12a2f02600b03afffe8000000000000086c9b2fffe6aed4cff02000000000000000000000000000186006a3aa2e9024000123c92e4606a3ea2d70800000000000000006a56a2ce04030440c01a5a92c9601a5e92c4606a62a2bb04000000006a66a2a6102401fa00049c048400000000000000006a76a29d04030440c01a7a9298601a7e9293606c0082a28904000000006c0086a27310fdfd9ed67950000400000000000000006c0096a2690418033c001a9a9264606c009ea24e102401fa00049c048000000000000000006c00aea24404180330001ab2923f606c00b6a22910fdfd9ed67950000000000000000000006c00c6a21f04190300001aca921a606c00cea20410fdfd9ed67950000400000000000000016bc472086be4b03a01b87206b03a01b87201
    APF packet counters:
      TOTAL_PACKETS: 469
      PASSED_DHCP: 4
      PASSED_IPV4: 65
      PASSED_IPV6_NON_ICMP: 64
      PASSED_IPV4_UNICAST: 64
      PASSED_IPV6_ICMP: 223
      PASSED_IPV6_UNICAST_NON_ICMP: 6
      PASSED_ARP_UNICAST_REPLY: 4
      PASSED_NON_IP_UNICAST: 1
      DROPPED_RA: 4
      DROPPED_IPV4_BROADCAST_ADDR: 7
      DROPPED_IPV4_BROADCAST_NET: 27

Output untuk contoh perintah adb shell dumpsys network_stack ini meliputi:

  • ApfCapabilities{version: 4, maxSize: 4096, format: 1} : Ini berarti chip Wi-Fi mendukung APF (versi 4).
  • Last program : Bagian ini adalah program biner APF yang terakhir diinstal dalam format string hex.
  • APF packet counters : Bagian ini menunjukkan berapa banyak paket yang diteruskan atau dijatuhkan oleh APF dan alasan spesifiknya.

Untuk memecahkan kode dan membongkar kode ke dalam bahasa assembler yang dapat dibaca manusia, gunakan alat apf_disassembler . Untuk mengkompilasi biner yang dapat dieksekusi, jalankan perintah m apf_disassembler . Berikut ini adalah contoh cara menggunakan alat apf_disassembler .

echo "6bfcb03a01b8120c6b949401e906006b907c01e288a27c01dd88a47c01d888b87c01d388cd7c01ce88e17c01c988e384004008066a0e6bdca401af000600010800060412147a1e016bd88401a300021a1c6b8c7c01a00000686bd4a4018c0006ffffffffffff1a266bc07c018900006bf874017e120c84005408000a17821f1112149c00181fffab0d2a108211446a3239a205065a56483ac3146bf47401530a1e52f06bac7c014e00e06bb41a1e7e00000141ffffffff6be868a4012d0006ffffffffffff6bb874012e6bf07401237c001386dd686bd0a401100006ffffffffffff6bc87401110a147a0d3a6b980a267c010300ff6be072f90a366ba87af8858218886a26a2040fff02000000000000000000000000006ba472ddaa0e82d0aeaa0f8c00c9025868a2b60f5a56483ac3140c8126f3895186dd606a12a28b2600783afffe8000000000000002005efffe00026fff02000000000000000000000000000186006a3aa284024000123c94007d02586a3ea2700800000000000000006a56a26704190500001a5a94006002586a5ea23b2020014860486000000000000000006464200148604860000000000000000000646a7ea23204030440c01a8294002b02581a8694002402586c008aa21a04000000006c008ea204102a0079e10abcf60500000000000000006bc472086be4b03a01b87206b03a01b87201" | out/host/linux-x86/bin/apf_disassembler
       0: li    r1, -4
       2: lddw  r0, [r1+0]
       3: add   r0, 1
       5: stdw  r0, [r1+0]
       6: ldh   r0, [12]
       8: li    r1, -108
      10: jlt   r0, 0x600, 504
      15: li    r1, -112
      17: jeq   r0, 0x88a2, 504
      22: jeq   r0, 0x88a4, 504
      27: jeq   r0, 0x88b8, 504
      32: jeq   r0, 0x88cd, 504
      37: jeq   r0, 0x88e1, 504
      42: jeq   r0, 0x88e3, 504
      47: jne   r0, 0x806, 116
......

Untuk memeriksa hasil APF secara offline, gunakan alat apf_run . Untuk mengkompilasi biner yang dapat dieksekusi, jalankan perintah m apf_run . Berikut ini adalah contoh cara memeriksa satu paket menggunakan perintah apf_run .

Untuk memberikan presentasi string biner hex dari paket mentah, gunakan opsi --packet . Untuk menyediakan string biner hex dari wilayah data, yang digunakan untuk menyimpan penghitung APF , gunakan --data option . Karena setiap counter panjangnya 4 byte, wilayah data harus cukup panjang untuk memastikan tidak terjadi buffer overflow.

out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001

Untuk memeriksa hasil APF terhadap file pcap yang diambil oleh tcpdump, gunakan perintah apf_run sebagai berikut:

out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b989401df06006b947c01d888a27c01d388a47c01ce88b87c01c988cd7c01c488e17c01bf88e384004408066a0e6bdca401a5000600010800060412147a1e016bd884019900021a1c6b907c01960000686bd4a401820006ffffffffffff6a266bc0a4017b0004c0a82b056bf874017084005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506fabe589435936bf47401470a1e52f06bb07c014200e06bb81a1e7e00000135ffffffff6bb47e0000012ac0a82bff6be868a401160006ffffffffffff6bbc7401176bf074010c7c001086dd686bd0a2fb06ffffffffffff6bcc72fd0a147a0b3a6b9c0a267af1ff6be072e70a366bac7ae6858218886a26a2040fff02000000000000000000000000006ba872cbaa0e82be8eaa0f8c00b7025868a2a40ffabe5894359352a9874d08aa86dd606a12a2792600583afffe80000000000000f7d4e8ccd81ddb43fe80000000000000f8be58fffe94359386006a3aa272024108123c94006b02586a3ea25e0800000000000000006a56a25504030440c01a5a94004e02581a5e94004702586a62a23e04000000006a66a229102409891f9a26ae6d00000000000000006a76a22004190300001a7a94001902586a7ea204102409891f9a26ae6dba98e781ca9ef9ba6bc872086be4b03a01b87206b03a01b87201 --pcap apf.pcap --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
37 packets dropped
1733 packets passed
Data: 00000000000000000000000000000000000000000200000005000000000000000000000002000000000000001b000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000689000000000000003c00000000000000000000000000000000000006ea