wirelessxpl 1.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wirelessxpl/__init__.py +6 -0
- wirelessxpl/__main__.py +18 -0
- wirelessxpl/core/__init__.py +0 -0
- wirelessxpl/core/bluetooth/__init__.py +0 -0
- wirelessxpl/core/bluetooth/btle/__init__.py +14 -0
- wirelessxpl/core/bluetooth/btle/btle_device.py +393 -0
- wirelessxpl/core/bluetooth/btle/btle_scanner.py +75 -0
- wirelessxpl/core/bluetooth/btle_client.py +52 -0
- wirelessxpl/core/bt_crypto.py +382 -0
- wirelessxpl/core/cve/__init__.py +1 -0
- wirelessxpl/core/cve/cve_db.py +409 -0
- wirelessxpl/core/exploit/__init__.py +49 -0
- wirelessxpl/core/exploit/char_by_char.py +27 -0
- wirelessxpl/core/exploit/exceptions.py +11 -0
- wirelessxpl/core/exploit/exploit.py +225 -0
- wirelessxpl/core/exploit/module_target_scope.py +112 -0
- wirelessxpl/core/exploit/option.py +195 -0
- wirelessxpl/core/exploit/printer.py +211 -0
- wirelessxpl/core/exploit/utils.py +338 -0
- wirelessxpl/core/ftp/__init__.py +0 -0
- wirelessxpl/core/ftp/ftp_client.py +138 -0
- wirelessxpl/core/gpu/__init__.py +6 -0
- wirelessxpl/core/gpu/backend.py +176 -0
- wirelessxpl/core/gpu/cpu_backend.py +44 -0
- wirelessxpl/core/gpu/cuda_backend.py +96 -0
- wirelessxpl/core/gpu/opencl_backend.py +71 -0
- wirelessxpl/core/http/__init__.py +0 -0
- wirelessxpl/core/http/http_client.py +95 -0
- wirelessxpl/core/hw_profiler.py +290 -0
- wirelessxpl/core/integrations/__init__.py +13 -0
- wirelessxpl/core/integrations/msf_cli.py +121 -0
- wirelessxpl/core/ml/__init__.py +42 -0
- wirelessxpl/core/ml/advisor.py +217 -0
- wirelessxpl/core/ml/ap_fingerprinter.py +334 -0
- wirelessxpl/core/ml/channel_optimizer.py +239 -0
- wirelessxpl/core/ml/gpu.py +74 -0
- wirelessxpl/core/ml/handshake_scorer.py +349 -0
- wirelessxpl/core/ml/portal_optimizer.py +205 -0
- wirelessxpl/core/ml/wps_pin_predictor.py +273 -0
- wirelessxpl/core/pcap/__init__.py +1 -0
- wirelessxpl/core/pcap/pcap_parser.py +583 -0
- wirelessxpl/core/pcap/wifi_offline.py +932 -0
- wirelessxpl/core/pool.py +203 -0
- wirelessxpl/core/tcp/__init__.py +0 -0
- wirelessxpl/core/tcp/tcp_client.py +147 -0
- wirelessxpl/core/telnet/__init__.py +0 -0
- wirelessxpl/core/telnet/telnet_client.py +173 -0
- wirelessxpl/core/udp/__init__.py +0 -0
- wirelessxpl/core/udp/udp_client.py +107 -0
- wirelessxpl/core/wordlist/__init__.py +1 -0
- wirelessxpl/core/wordlist/generator.py +403 -0
- wirelessxpl/interpreter.py +784 -0
- wirelessxpl/libs/__init__.py +0 -0
- wirelessxpl/libs/apiros/__init__.py +0 -0
- wirelessxpl/libs/apiros/apiros_client.py +268 -0
- wirelessxpl/libs/lzs/__init__.py +0 -0
- wirelessxpl/libs/lzs/lzs.py +135 -0
- wirelessxpl/modules/__init__.py +0 -0
- wirelessxpl/modules/generic/__init__.py +0 -0
- wirelessxpl/modules/generic/bluetooth/__init__.py +0 -0
- wirelessxpl/modules/generic/bluetooth/ble_btlejack.py +134 -0
- wirelessxpl/modules/generic/bluetooth/ble_crackle.py +442 -0
- wirelessxpl/modules/generic/bluetooth/ble_phishing.py +252 -0
- wirelessxpl/modules/generic/bluetooth/blueborne_attack.py +395 -0
- wirelessxpl/modules/generic/bluetooth/bt_baseband_attack.py +346 -0
- wirelessxpl/modules/generic/bluetooth/bt_hid_injection.py +601 -0
- wirelessxpl/modules/generic/bluetooth/bt_session_attack.py +419 -0
- wirelessxpl/modules/generic/bluetooth/btle_enumerate.py +26 -0
- wirelessxpl/modules/generic/bluetooth/btle_scan.py +28 -0
- wirelessxpl/modules/generic/bluetooth/btle_write.py +33 -0
- wirelessxpl/modules/generic/cve/__init__.py +1 -0
- wirelessxpl/modules/generic/cve/cve_lookup.py +144 -0
- wirelessxpl/modules/generic/cve/zigbee_attack.py +441 -0
- wirelessxpl/modules/generic/external/__init__.py +4 -0
- wirelessxpl/modules/generic/external/airgeddon_bridge.py +118 -0
- wirelessxpl/modules/generic/external/bettercap_bridge.py +296 -0
- wirelessxpl/modules/generic/external/bruce_esp32_lab_notes.py +55 -0
- wirelessxpl/modules/generic/external/bruce_serial_bridge.py +446 -0
- wirelessxpl/modules/generic/external/bruce_upstream_tracker.py +178 -0
- wirelessxpl/modules/generic/external/eaphammer_bridge.py +409 -0
- wirelessxpl/modules/generic/external/fluxion_bridge.py +146 -0
- wirelessxpl/modules/generic/external/hcx_toolchain_bridge.py +109 -0
- wirelessxpl/modules/generic/external/mdk4_bridge.py +178 -0
- wirelessxpl/modules/generic/external/oneshot_bridge.py +173 -0
- wirelessxpl/modules/generic/external/ot_protocol_bridge.py +310 -0
- wirelessxpl/modules/generic/external/reaver_bridge.py +246 -0
- wirelessxpl/modules/generic/external/rogue_bridge.py +196 -0
- wirelessxpl/modules/generic/external/router_firmware_bridge.py +268 -0
- wirelessxpl/modules/generic/external/social_recon_bridge.py +363 -0
- wirelessxpl/modules/generic/external/wifiphisher_bridge.py +255 -0
- wirelessxpl/modules/generic/external/wifipumpkin3_bridge.py +192 -0
- wirelessxpl/modules/generic/external/wifite2_bridge.py +200 -0
- wirelessxpl/modules/generic/external/wireless_tool_prereq_audit.py +64 -0
- wirelessxpl/modules/generic/pcap/__init__.py +1 -0
- wirelessxpl/modules/generic/pcap/pcap_ap_station_mapper.py +98 -0
- wirelessxpl/modules/generic/pcap/pcap_ble_advertising_survey.py +77 -0
- wirelessxpl/modules/generic/pcap/pcap_credential_sniffer.py +93 -0
- wirelessxpl/modules/generic/pcap/pcap_dragonblood.py +161 -0
- wirelessxpl/modules/generic/pcap/pcap_eapol_survey.py +76 -0
- wirelessxpl/modules/generic/pcap/pcap_handshake_extractor.py +124 -0
- wirelessxpl/modules/generic/pcap/pcap_offline_wpa_crack.py +217 -0
- wirelessxpl/modules/generic/pcap/pcap_pmkid_attack.py +118 -0
- wirelessxpl/modules/generic/pcap/pcap_sql_workspace.py +94 -0
- wirelessxpl/modules/generic/pcap/pcap_tkip_downgrade.py +113 -0
- wirelessxpl/modules/generic/pcap/pcap_wep_crack.py +124 -0
- wirelessxpl/modules/generic/pcap/pcap_wpe_harvest.py +124 -0
- wirelessxpl/modules/generic/wifi_lab/__init__.py +4 -0
- wirelessxpl/modules/generic/wifi_lab/_disclaimer.py +29 -0
- wirelessxpl/modules/generic/wifi_lab/_i18n_service.py +315 -0
- wirelessxpl/modules/generic/wifi_lab/adaptive_harvest.py +81 -0
- wirelessxpl/modules/generic/wifi_lab/aireplay_deauth_barrage.py +145 -0
- wirelessxpl/modules/generic/wifi_lab/auth_flood.py +179 -0
- wirelessxpl/modules/generic/wifi_lab/awdl_attack.py +127 -0
- wirelessxpl/modules/generic/wifi_lab/beacon_flood_advanced.py +199 -0
- wirelessxpl/modules/generic/wifi_lab/captive_portal_modern_lab.py +220 -0
- wirelessxpl/modules/generic/wifi_lab/connectivity_portal.py +159 -0
- wirelessxpl/modules/generic/wifi_lab/deauth_csa_suite.py +411 -0
- wirelessxpl/modules/generic/wifi_lab/deauth_multimode.py +202 -0
- wirelessxpl/modules/generic/wifi_lab/dualband_evil_twin.py +201 -0
- wirelessxpl/modules/generic/wifi_lab/evil_qr_attack.py +158 -0
- wirelessxpl/modules/generic/wifi_lab/evil_twin_advanced.py +284 -0
- wirelessxpl/modules/generic/wifi_lab/evil_twin_hostapd_templates.py +157 -0
- wirelessxpl/modules/generic/wifi_lab/evil_twin_workflow.py +136 -0
- wirelessxpl/modules/generic/wifi_lab/evilginx_prereq_pointer.py +41 -0
- wirelessxpl/modules/generic/wifi_lab/fragattacks.py +449 -0
- wirelessxpl/modules/generic/wifi_lab/gps_wardriving_ndjson.py +102 -0
- wirelessxpl/modules/generic/wifi_lab/handshake_snooper.py +250 -0
- wirelessxpl/modules/generic/wifi_lab/hashcat_gpu_orchestrator.py +131 -0
- wirelessxpl/modules/generic/wifi_lab/karma_mana_attack.py +204 -0
- wirelessxpl/modules/generic/wifi_lab/kr00k_attack.py +296 -0
- wirelessxpl/modules/generic/wifi_lab/krack_attack.py +498 -0
- wirelessxpl/modules/generic/wifi_lab/mdk3_bridge.py +55 -0
- wirelessxpl/modules/generic/wifi_lab/mdk4_bridge.py +66 -0
- wirelessxpl/modules/generic/wifi_lab/mfa_phishing_portal.py +222 -0
- wirelessxpl/modules/generic/wifi_lab/mitm_wifi_bridge.py +153 -0
- wirelessxpl/modules/generic/wifi_lab/momo_integrated_attack.py +105 -0
- wirelessxpl/modules/generic/wifi_lab/pcap_rf_anomaly_ml.py +165 -0
- wirelessxpl/modules/generic/wifi_lab/pcap_wpa_handshake_validate.py +124 -0
- wirelessxpl/modules/generic/wifi_lab/replay_attack.py +186 -0
- wirelessxpl/modules/generic/wifi_lab/research_ecosystem_status.py +116 -0
- wirelessxpl/modules/generic/wifi_lab/responder_wifi.py +126 -0
- wirelessxpl/modules/generic/wifi_lab/rogue_ap_hostapd_bridge.py +115 -0
- wirelessxpl/modules/generic/wifi_lab/selective_jammer.py +141 -0
- wirelessxpl/modules/generic/wifi_lab/ssid_confusion.py +278 -0
- wirelessxpl/modules/generic/wifi_lab/transparent_proxy.py +151 -0
- wirelessxpl/modules/generic/wifi_lab/wardriving_deauth_loop.py +93 -0
- wirelessxpl/modules/generic/wifi_lab/wifi_sniffer.py +200 -0
- wirelessxpl/modules/generic/wifi_lab/wireless_ids.py +86 -0
- wirelessxpl/modules/generic/wifi_lab/wordlist_orchestrator.py +702 -0
- wirelessxpl/modules/generic/wifi_lab/wpa3_attack_suite.py +745 -0
- wirelessxpl/modules/generic/wifi_lab/wps_multimode.py +252 -0
- wirelessxpl/modules/generic/wordlist/__init__.py +1 -0
- wirelessxpl/modules/generic/wordlist/wordlist_generator.py +227 -0
- wirelessxpl/resources/__init__.py +0 -0
- wirelessxpl/resources/arsenal/binaries/.gitkeep +1 -0
- wirelessxpl/resources/arsenal/binaries/external_binary_catalog.json +21 -0
- wirelessxpl/resources/arsenal/credentials/.gitkeep +1 -0
- wirelessxpl/resources/arsenal/firmware/.gitkeep +1 -0
- wirelessxpl/resources/arsenal/firmware/external_firmware_catalog.json +21 -0
- wirelessxpl/resources/arsenal/intel/.gitkeep +1 -0
- wirelessxpl/resources/arsenal/intel/external_intel_live_snapshot.json +102 -0
- wirelessxpl/resources/arsenal/intel/honeypot_candidates_public.json +62 -0
- wirelessxpl/resources/arsenal/intel/honeypot_shodan_defensive_probe.json +230 -0
- wirelessxpl/resources/arsenal/intel/honeypot_shodan_live_candidates.json +370 -0
- wirelessxpl/resources/arsenal/intel/honeypot_validation_campaign.json +189 -0
- wirelessxpl/resources/arsenal/mibs/.gitkeep +1 -0
- wirelessxpl/resources/arsenal/pocs/.gitkeep +1 -0
- wirelessxpl/resources/arsenal/pocs/external_poc_pov_pof_catalog.json +29 -0
- wirelessxpl/resources/arsenal/wordlists/.gitkeep +1 -0
- wirelessxpl/resources/catalogs/all_known_wireless_attacks.json +564 -0
- wirelessxpl/resources/catalogs/arsenal_index.json +57255 -0
- wirelessxpl/resources/catalogs/arsenal_layout.json +61 -0
- wirelessxpl/resources/catalogs/brucedevices_firmware_issues_prs.json +29371 -0
- wirelessxpl/resources/catalogs/brucedevices_firmware_useful_map.json +9240 -0
- wirelessxpl/resources/catalogs/cve_extended_catalog.json +2626 -0
- wirelessxpl/resources/catalogs/deep_intel_backlog.json +233 -0
- wirelessxpl/resources/catalogs/discord_requested_devices.json +137 -0
- wirelessxpl/resources/catalogs/embedded_third_party_poc_intel.json +10782 -0
- wirelessxpl/resources/catalogs/exploitdb_wireless_catalog.json +586 -0
- wirelessxpl/resources/catalogs/external_framework_clones.json +415 -0
- wirelessxpl/resources/catalogs/external_tool_intel_sources.json +2032 -0
- wirelessxpl/resources/catalogs/market_priority_devices_2010_2026.json +2744 -0
- wirelessxpl/resources/catalogs/module_target_scope.json +37 -0
- wirelessxpl/resources/catalogs/osi_tcpip_priority_matrix.json +301 -0
- wirelessxpl/resources/catalogs/post2018_network_devices.json +40 -0
- wirelessxpl/resources/catalogs/superproject_submodule_integration_matrix.json +159 -0
- wirelessxpl/resources/catalogs/third_party_router_exploit_repos.json +5910 -0
- wirelessxpl/resources/catalogs/third_party_upstream_open_work.json +8074 -0
- wirelessxpl/resources/catalogs/upstream_issues_prs.json +185 -0
- wirelessxpl/resources/catalogs/wifi6_80211ax_threat_vectors.json +172 -0
- wirelessxpl/resources/catalogs/wifi7_80211be_threat_vectors.json +170 -0
- wirelessxpl/resources/catalogs/wireless_research_submodules.json +36 -0
- wirelessxpl/resources/catalogs/workspace_reuse_inventory.json +459560 -0
- wirelessxpl/resources/ml/__init__.py +4 -0
- wirelessxpl/resources/ml/default_advisor.json +25 -0
- wirelessxpl/resources/phishing_pages/asus_generic/strings.json +90 -0
- wirelessxpl/resources/phishing_pages/ble_pair_spoof/strings.json +82 -0
- wirelessxpl/resources/phishing_pages/captive_hotel/strings.json +82 -0
- wirelessxpl/resources/phishing_pages/corporate_vpn/strings.json +82 -0
- wirelessxpl/resources/phishing_pages/dlink_generic/strings.json +94 -0
- wirelessxpl/resources/phishing_pages/firmware_update/strings.json +94 -0
- wirelessxpl/resources/phishing_pages/fritzbox_generic/strings.json +86 -0
- wirelessxpl/resources/phishing_pages/huawei_generic/strings.json +78 -0
- wirelessxpl/resources/phishing_pages/isp_login/strings.json +74 -0
- wirelessxpl/resources/phishing_pages/linksys_generic/strings.json +82 -0
- wirelessxpl/resources/phishing_pages/netgear_generic/strings.json +74 -0
- wirelessxpl/resources/phishing_pages/oauth_social/strings.json +82 -0
- wirelessxpl/resources/phishing_pages/tplink_generic/strings.json +82 -0
- wirelessxpl/resources/phishing_pages/vodafone_generic/strings.json +86 -0
- wirelessxpl/resources/phishing_pages/wifi_connect/strings.json +66 -0
- wirelessxpl/resources/phishing_pages/xfinity_login/strings.json +82 -0
- wirelessxpl/resources/ssh_keys/array-networks-vapv-vxag.json +4 -0
- wirelessxpl/resources/ssh_keys/array-networks-vapv-vxag.key +12 -0
- wirelessxpl/resources/ssh_keys/barracuda_load_balancer_vm.json +4 -0
- wirelessxpl/resources/ssh_keys/barracuda_load_balancer_vm.key +12 -0
- wirelessxpl/resources/ssh_keys/ceragon-fibeair-cve-2015-0936.json +4 -0
- wirelessxpl/resources/ssh_keys/ceragon-fibeair-cve-2015-0936.key +15 -0
- wirelessxpl/resources/ssh_keys/exagrid-cve-2016-1561.json +4 -0
- wirelessxpl/resources/ssh_keys/exagrid-cve-2016-1561.key +15 -0
- wirelessxpl/resources/ssh_keys/f5-bigip-cve-2012-1493.json +4 -0
- wirelessxpl/resources/ssh_keys/f5-bigip-cve-2012-1493.key +15 -0
- wirelessxpl/resources/ssh_keys/loadbalancer.org-enterprise-va.json +4 -0
- wirelessxpl/resources/ssh_keys/loadbalancer.org-enterprise-va.key +12 -0
- wirelessxpl/resources/ssh_keys/monroe-dasdec-cve-2013-0137.json +4 -0
- wirelessxpl/resources/ssh_keys/monroe-dasdec-cve-2013-0137.key +12 -0
- wirelessxpl/resources/ssh_keys/quantum-dxi-v1000.json +4 -0
- wirelessxpl/resources/ssh_keys/quantum-dxi-v1000.key +12 -0
- wirelessxpl/resources/vendors/oui.dat +39395 -0
- wirelessxpl/resources/vendors/oui_enriched.csv +39396 -0
- wirelessxpl/resources/wordlists/__init__.py +114 -0
- wirelessxpl/resources/wordlists/defaults.txt +653 -0
- wirelessxpl/resources/wordlists/mikrotik_api_defaults.txt +32 -0
- wirelessxpl/resources/wordlists/passwords.txt +716 -0
- wirelessxpl/resources/wordlists/router_scope_defaults.txt +652 -0
- wirelessxpl/resources/wordlists/router_scope_passwords.txt +714 -0
- wirelessxpl/resources/wordlists/router_scope_snmp.txt +119 -0
- wirelessxpl/resources/wordlists/router_scope_usernames.txt +354 -0
- wirelessxpl/resources/wordlists/snmp.txt +120 -0
- wirelessxpl/resources/wordlists/snmpv3_defaults.txt +8 -0
- wirelessxpl/resources/wordlists/usernames.txt +354 -0
- wirelessxpl-1.1.1.dist-info/METADATA +316 -0
- wirelessxpl-1.1.1.dist-info/RECORD +246 -0
- wirelessxpl-1.1.1.dist-info/WHEEL +5 -0
- wirelessxpl-1.1.1.dist-info/entry_points.txt +2 -0
- wirelessxpl-1.1.1.dist-info/licenses/LICENSE +16 -0
- wirelessxpl-1.1.1.dist-info/top_level.txt +1 -0
wirelessxpl/__init__.py
ADDED
wirelessxpl/__main__.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Author: André Henrique (@mrhenrike) | União Geek — https://github.com/Uniao-Geek
|
|
2
|
+
"""WirelessXPL-Forge entry point for `python -m wirelessxpl` and `wxf` CLI."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main() -> None:
|
|
10
|
+
"""Launch the WXF interactive shell."""
|
|
11
|
+
from wirelessxpl.interpreter import WirelessXPLInterpreter # type: ignore[import]
|
|
12
|
+
|
|
13
|
+
interpreter = WirelessXPLInterpreter()
|
|
14
|
+
interpreter.start()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
sys.exit(main())
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import struct
|
|
2
|
+
from bluepy.btle import (
|
|
3
|
+
Peripheral,
|
|
4
|
+
ScanEntry,
|
|
5
|
+
AssignedNumbers
|
|
6
|
+
)
|
|
7
|
+
from wirelessxpl.core.exploit.printer import (
|
|
8
|
+
print_table,
|
|
9
|
+
print_success,
|
|
10
|
+
print_status,
|
|
11
|
+
print_error,
|
|
12
|
+
color_blue,
|
|
13
|
+
color_green,
|
|
14
|
+
color_red
|
|
15
|
+
)
|
|
16
|
+
from wirelessxpl.core.exploit.utils import (
|
|
17
|
+
lookup_vendor
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Device(ScanEntry):
|
|
22
|
+
""" Single discovered Bluetooth Low Energy device """
|
|
23
|
+
|
|
24
|
+
def __init__(self, addr, iface):
|
|
25
|
+
ScanEntry.__init__(self, addr, iface)
|
|
26
|
+
|
|
27
|
+
self.vendor = None
|
|
28
|
+
self.data = []
|
|
29
|
+
|
|
30
|
+
def _update(self, resp):
|
|
31
|
+
ScanEntry._update(self, resp)
|
|
32
|
+
|
|
33
|
+
if self.addrType == "random":
|
|
34
|
+
self.vendor = "None (Random MAC address)"
|
|
35
|
+
else:
|
|
36
|
+
self.vendor = lookup_vendor(self.addr)
|
|
37
|
+
|
|
38
|
+
if self.scanData:
|
|
39
|
+
self.data = self._get_data(self.getScanData())
|
|
40
|
+
|
|
41
|
+
def print_info(self):
|
|
42
|
+
headers = (color_blue("{} ({} dBm)").format(self.addr, self.rssi), "")
|
|
43
|
+
if self.connectable:
|
|
44
|
+
allow_connection = color_green(str(self.connectable))
|
|
45
|
+
else:
|
|
46
|
+
allow_connection = color_red(str(self.connectable))
|
|
47
|
+
|
|
48
|
+
data = [
|
|
49
|
+
("Vendor", self.vendor),
|
|
50
|
+
("Allow Connections", allow_connection),
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
for d in self.data:
|
|
54
|
+
data.append((d[0], d[1]))
|
|
55
|
+
|
|
56
|
+
print_table(headers, *data, max_column_length=70, extra_fill=3)
|
|
57
|
+
|
|
58
|
+
def print_services(self):
|
|
59
|
+
headers = ("Handles", "Service > Characteristics", "Properties", "Data")
|
|
60
|
+
services = self.enumerate_services()
|
|
61
|
+
|
|
62
|
+
if services:
|
|
63
|
+
print_table(headers, *services, max_column_length=70, extra_fill=3)
|
|
64
|
+
|
|
65
|
+
def enumerate_services(self):
|
|
66
|
+
print_status("Starting enumerating {} ({} dBm) ...".format(self.addr, self.rssi))
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
dev = Peripheral(self, self.addrType)
|
|
70
|
+
|
|
71
|
+
services = sorted(dev.services, key=lambda s: s.hndStart)
|
|
72
|
+
|
|
73
|
+
data = []
|
|
74
|
+
for service in services:
|
|
75
|
+
if service.hndStart == service.hndEnd:
|
|
76
|
+
continue
|
|
77
|
+
|
|
78
|
+
data.append([
|
|
79
|
+
"{:04x} -> {:04x}".format(service.hndStart, service.hndEnd),
|
|
80
|
+
self._get_svc_description(service),
|
|
81
|
+
"",
|
|
82
|
+
"",
|
|
83
|
+
])
|
|
84
|
+
|
|
85
|
+
for _, char in enumerate(service.getCharacteristics()):
|
|
86
|
+
desc = self._get_char_description(char)
|
|
87
|
+
props = char.propertiesToString()
|
|
88
|
+
hnd = char.getHandle()
|
|
89
|
+
value = self._get_char(char, props)
|
|
90
|
+
|
|
91
|
+
data.append([
|
|
92
|
+
"{:04x}".format(hnd), desc, props, value
|
|
93
|
+
])
|
|
94
|
+
|
|
95
|
+
dev.disconnect()
|
|
96
|
+
|
|
97
|
+
return data
|
|
98
|
+
|
|
99
|
+
except Exception as err:
|
|
100
|
+
print_error(err)
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
dev.disconnect()
|
|
104
|
+
except Exception as err:
|
|
105
|
+
print_error(err)
|
|
106
|
+
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
def write(self, characteristic, data):
|
|
110
|
+
try:
|
|
111
|
+
dev = Peripheral(self, self.addrType)
|
|
112
|
+
|
|
113
|
+
services = sorted(dev.services, key=lambda s: s.hndStart)
|
|
114
|
+
|
|
115
|
+
print_status("Searching for characteristic {}".format(characteristic))
|
|
116
|
+
char = None
|
|
117
|
+
for service in services:
|
|
118
|
+
if char is not None:
|
|
119
|
+
break
|
|
120
|
+
|
|
121
|
+
for _, c in enumerate(service.getCharacteristics()):
|
|
122
|
+
if str(c.uuid) == characteristic:
|
|
123
|
+
char = c
|
|
124
|
+
break
|
|
125
|
+
|
|
126
|
+
if char:
|
|
127
|
+
if "WRITE" in char.propertiesToString():
|
|
128
|
+
print_success("Sending {} bytes...".format(len(data)))
|
|
129
|
+
|
|
130
|
+
wwrflag = False
|
|
131
|
+
|
|
132
|
+
if "NO RESPONSE" in char.propertiesToString():
|
|
133
|
+
wwrflag = True
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
char.write(data, wwrflag)
|
|
137
|
+
print_success("Data sent")
|
|
138
|
+
except Exception as err:
|
|
139
|
+
print_error("Error: {}".format(err))
|
|
140
|
+
|
|
141
|
+
else:
|
|
142
|
+
print_error("Not writable")
|
|
143
|
+
|
|
144
|
+
dev.disconnect()
|
|
145
|
+
|
|
146
|
+
except Exception as err:
|
|
147
|
+
print_error(err)
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
dev.disconnect()
|
|
151
|
+
except Exception:
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
def _get_data(self, scan_data):
|
|
157
|
+
data = []
|
|
158
|
+
for (tag, desc, val) in scan_data:
|
|
159
|
+
if desc == "Flags":
|
|
160
|
+
data.append(("Flags", self._get_flags(val)))
|
|
161
|
+
|
|
162
|
+
elif tag in [8, 9]:
|
|
163
|
+
try:
|
|
164
|
+
data.append((desc, val))
|
|
165
|
+
except UnicodeEncodeError:
|
|
166
|
+
data.append((desc, repr(val)))
|
|
167
|
+
|
|
168
|
+
else:
|
|
169
|
+
data.append((desc, val))
|
|
170
|
+
|
|
171
|
+
return data
|
|
172
|
+
|
|
173
|
+
def _get_flags(self, data):
|
|
174
|
+
bits = []
|
|
175
|
+
flags = int(data, 16)
|
|
176
|
+
|
|
177
|
+
if self._is_bit_set(flags, 0):
|
|
178
|
+
bits.append("LE Limited Discoverable")
|
|
179
|
+
|
|
180
|
+
if self._is_bit_set(flags, 1):
|
|
181
|
+
bits.append("LE General Discoverable")
|
|
182
|
+
|
|
183
|
+
if self._is_bit_set(flags, 2):
|
|
184
|
+
bits.append("BR/EDR")
|
|
185
|
+
|
|
186
|
+
if self._is_bit_set(flags, 3):
|
|
187
|
+
bits.append("LE + BR/EDR Controller Mode")
|
|
188
|
+
|
|
189
|
+
if self._is_bit_set(flags, 4):
|
|
190
|
+
bits.append("LE + BR/EDR Host Mode")
|
|
191
|
+
|
|
192
|
+
return ", ".join(bits)
|
|
193
|
+
|
|
194
|
+
def _is_bit_set(self, byteval, idx):
|
|
195
|
+
return ((byteval & (1 << idx)) != 0)
|
|
196
|
+
|
|
197
|
+
def _get_svc_description(self, service):
|
|
198
|
+
uuid_name = service.uuid.getCommonName()
|
|
199
|
+
|
|
200
|
+
if uuid_name and uuid_name != str(service.uuid):
|
|
201
|
+
return "{} ({})".format(color_green(uuid_name), service.uuid)
|
|
202
|
+
|
|
203
|
+
return str(service.uuid)
|
|
204
|
+
|
|
205
|
+
def _get_char_description(self, char):
|
|
206
|
+
char_name = char.uuid.getCommonName()
|
|
207
|
+
if char_name and char_name != str(char.uuid):
|
|
208
|
+
return " {} ({})".format(color_green(char_name), char.uuid)
|
|
209
|
+
|
|
210
|
+
return " {}".format(char.uuid)
|
|
211
|
+
|
|
212
|
+
def _get_char(self, char, props):
|
|
213
|
+
string = ""
|
|
214
|
+
if "READ" in props and "INDICATE" not in props:
|
|
215
|
+
try:
|
|
216
|
+
data = char.read()
|
|
217
|
+
|
|
218
|
+
if char.uuid == AssignedNumbers.appearance:
|
|
219
|
+
string = self._get_appearance(data)
|
|
220
|
+
else:
|
|
221
|
+
try:
|
|
222
|
+
string = color_blue(repr(data.decode("utf-8")))
|
|
223
|
+
except Exception:
|
|
224
|
+
string = repr(data)
|
|
225
|
+
|
|
226
|
+
except Exception:
|
|
227
|
+
pass
|
|
228
|
+
|
|
229
|
+
return string
|
|
230
|
+
|
|
231
|
+
def _get_appearance(self, data):
|
|
232
|
+
appearance = {
|
|
233
|
+
0: "Unknown",
|
|
234
|
+
64: "Generic Phone",
|
|
235
|
+
128: "Generic Computer",
|
|
236
|
+
192: "Generic Watch",
|
|
237
|
+
193: "Watch: Sports Watch",
|
|
238
|
+
256: "Generic Clock",
|
|
239
|
+
320: "Generic Display",
|
|
240
|
+
384: "Generic Remote Control",
|
|
241
|
+
448: "Generic Eye-glasses",
|
|
242
|
+
512: "Generic Tag",
|
|
243
|
+
576: "Generic Keyring",
|
|
244
|
+
640: "Generic Media Player",
|
|
245
|
+
704: "Generic Barcode Scanner",
|
|
246
|
+
768: "Generic Thermometer",
|
|
247
|
+
769: "Thermometer: Ear",
|
|
248
|
+
832: "Generic Heart rate Sensor",
|
|
249
|
+
833: "Heart Rate Sensor: Heart Rate Belt",
|
|
250
|
+
896: "Generic Blood Pressure",
|
|
251
|
+
897: "Blood Pressure: Arm",
|
|
252
|
+
898: "Blood Pressure: Wrist",
|
|
253
|
+
960: "Human Interface Device (HID)",
|
|
254
|
+
961: "Keyboard",
|
|
255
|
+
962: "Mouse",
|
|
256
|
+
963: "Joystick",
|
|
257
|
+
964: "Gamepad",
|
|
258
|
+
965: "Digitizer Tablet",
|
|
259
|
+
966: "Card Reader",
|
|
260
|
+
967: "Digital Pen",
|
|
261
|
+
968: "Barcode Scanner",
|
|
262
|
+
1024: "Generic Glucose Meter",
|
|
263
|
+
1088: "Generic: Running Walking Sensor",
|
|
264
|
+
1089: "Running Walking Sensor: In-Shoe",
|
|
265
|
+
1090: "Running Walking Sensor: On-Shoe",
|
|
266
|
+
1091: "Running Walking Sensor: On-Hip",
|
|
267
|
+
1152: "Generic: Cycling",
|
|
268
|
+
1153: "Cycling: Cycling Computer",
|
|
269
|
+
1154: "Cycling: Speed Sensor",
|
|
270
|
+
1155: "Cycling: Cadence Sensor",
|
|
271
|
+
1156: "Cycling: Power Sensor",
|
|
272
|
+
1157: "Cycling: Speed and Cadence Sensor",
|
|
273
|
+
1216: "Generic Control Device",
|
|
274
|
+
1217: "Switch",
|
|
275
|
+
1218: "Multi-switch",
|
|
276
|
+
1219: "Button",
|
|
277
|
+
1220: "Slider",
|
|
278
|
+
1221: "Rotary",
|
|
279
|
+
1222: "Touch-panel",
|
|
280
|
+
1280: "Generic Network Device",
|
|
281
|
+
1281: "Access Point",
|
|
282
|
+
1344: "Generic Sensor",
|
|
283
|
+
1345: "Motion Sensor",
|
|
284
|
+
1346: "Air Quality Sensor",
|
|
285
|
+
1347: "Temperature Sensor",
|
|
286
|
+
1348: "Humidity Sensor",
|
|
287
|
+
1349: "Leak Sensor",
|
|
288
|
+
1350: "Smoke Sensor",
|
|
289
|
+
1351: "Occupancy Sensor",
|
|
290
|
+
1352: "Contact Sensor",
|
|
291
|
+
1353: "Carbon Monoxide Sensor",
|
|
292
|
+
1354: "Carbon Dioxide Sensor",
|
|
293
|
+
1355: "Ambient Light Sensor",
|
|
294
|
+
1356: "Energy Sensor",
|
|
295
|
+
1357: "Color Light Sensor",
|
|
296
|
+
1358: "Rain Sensor",
|
|
297
|
+
1359: "Fire Sensor",
|
|
298
|
+
1360: "Wind Sensor",
|
|
299
|
+
1361: "Proximity Sensor",
|
|
300
|
+
1362: "Multi-Sensor",
|
|
301
|
+
1408: "Generic Light Fixtures",
|
|
302
|
+
1409: "Wall Light",
|
|
303
|
+
1410: "Ceiling Light",
|
|
304
|
+
1411: "Floor Light",
|
|
305
|
+
1412: "Cabinet Light",
|
|
306
|
+
1413: "Desk Light",
|
|
307
|
+
1414: "Troffer Light",
|
|
308
|
+
1415: "Pendant Light",
|
|
309
|
+
1416: "In-ground Light",
|
|
310
|
+
1417: "Flood Light",
|
|
311
|
+
1418: "Underwater Light",
|
|
312
|
+
1419: "Bollard with Light",
|
|
313
|
+
1420: "Pathway Light",
|
|
314
|
+
1421: "Garden Light",
|
|
315
|
+
1422: "Pole-top Light",
|
|
316
|
+
1423: "Spotlight",
|
|
317
|
+
1424: "Linear Light",
|
|
318
|
+
1425: "Street Light",
|
|
319
|
+
1426: "Shelves Light",
|
|
320
|
+
1427: "High-bay / Low-bay Light",
|
|
321
|
+
1428: "Emergency Exit Light",
|
|
322
|
+
1472: "Generic Fan",
|
|
323
|
+
1473: "Ceiling Fan",
|
|
324
|
+
1474: "Axial Fan",
|
|
325
|
+
1475: "Exhaust Fan",
|
|
326
|
+
1476: "Pedestal Fan",
|
|
327
|
+
1477: "Desk Fan",
|
|
328
|
+
1478: "Wall Fan",
|
|
329
|
+
1536: "Generic HVAC",
|
|
330
|
+
1537: "Thermostat",
|
|
331
|
+
1600: "Generic Air Conditioning",
|
|
332
|
+
1664: "Generic Humidifier",
|
|
333
|
+
1728: "Generic Heating",
|
|
334
|
+
1729: "Radiator",
|
|
335
|
+
1730: "Boiler",
|
|
336
|
+
1731: "Heat Pump",
|
|
337
|
+
1732: "Infrared Heater",
|
|
338
|
+
1733: "Radiant Panel Heater",
|
|
339
|
+
1734: "Fan Heater",
|
|
340
|
+
1735: "Air Curtain",
|
|
341
|
+
1792: "Generic Access Control",
|
|
342
|
+
1793: "Access Door",
|
|
343
|
+
1794: "Garage Door",
|
|
344
|
+
1795: "Emergency Exit Door",
|
|
345
|
+
1796: "Access Lock",
|
|
346
|
+
1797: "Elevator",
|
|
347
|
+
1798: "Window",
|
|
348
|
+
1799: "Entrance Gate",
|
|
349
|
+
1856: "Generic Motorized Device",
|
|
350
|
+
1857: "Motorized Gate",
|
|
351
|
+
1858: "Awning",
|
|
352
|
+
1859: "Blinds or Shades",
|
|
353
|
+
1860: "Curtains",
|
|
354
|
+
1861: "Screen",
|
|
355
|
+
1920: "Generic Power Device",
|
|
356
|
+
1921: "Power Outlet",
|
|
357
|
+
1922: "Power Strip",
|
|
358
|
+
1923: "Plug",
|
|
359
|
+
1924: "Power Supply",
|
|
360
|
+
1925: "LED Driver",
|
|
361
|
+
1926: "Fluorescent Lamp Gear",
|
|
362
|
+
1927: "HID Lamp Gear",
|
|
363
|
+
1984: "Generic Light Source",
|
|
364
|
+
1985: "Incandescent Light Bulb",
|
|
365
|
+
1986: "LED Bulb",
|
|
366
|
+
1987: "HID Lamp",
|
|
367
|
+
1988: "Fluorescent Lamp",
|
|
368
|
+
1989: "LED Array",
|
|
369
|
+
1990: "Multi-Color LED Array",
|
|
370
|
+
3136: "Generic: Pulse Oximeter",
|
|
371
|
+
3137: "Fingertip",
|
|
372
|
+
3138: "Wrist Worn",
|
|
373
|
+
3200: "Generic: Weight Scale",
|
|
374
|
+
3264: "Generic",
|
|
375
|
+
3265: "Powered Wheelchair",
|
|
376
|
+
3266: "Mobility Scooter",
|
|
377
|
+
3328: "Generic",
|
|
378
|
+
5184: "Generic: Outdoor Sports Activity",
|
|
379
|
+
5185: "Location Display Device",
|
|
380
|
+
5186: "Location and Navigation Display Device",
|
|
381
|
+
5187: "Location Pod",
|
|
382
|
+
5188: "Location and Navigation Pod",
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
try:
|
|
386
|
+
code = struct.unpack("h", data)[0]
|
|
387
|
+
|
|
388
|
+
if code in appearance.keys():
|
|
389
|
+
return color_green(appearance[code])
|
|
390
|
+
except Exception:
|
|
391
|
+
pass
|
|
392
|
+
|
|
393
|
+
return repr(data)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import binascii
|
|
3
|
+
from bluepy.btle import Scanner, DefaultDelegate
|
|
4
|
+
from .btle_device import Device
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BTLEScanner(Scanner):
|
|
8
|
+
""" Bluetooth Low Energy Scanner """
|
|
9
|
+
|
|
10
|
+
def __init__(self, mac=None, iface=0):
|
|
11
|
+
Scanner.__init__(self, iface)
|
|
12
|
+
self.mac = mac
|
|
13
|
+
|
|
14
|
+
def _decode_address(self, resp):
|
|
15
|
+
addr = binascii.b2a_hex(resp["addr"][0]).decode("utf-8")
|
|
16
|
+
return ":".join([addr[i: i + 2] for i in range(0, 12, 2)])
|
|
17
|
+
|
|
18
|
+
def _find_or_create(self, addr):
|
|
19
|
+
if addr in self.scanned:
|
|
20
|
+
dev = self.scanned[addr]
|
|
21
|
+
else:
|
|
22
|
+
dev = Device(addr, self.iface)
|
|
23
|
+
self.scanned[addr] = dev
|
|
24
|
+
|
|
25
|
+
return dev
|
|
26
|
+
|
|
27
|
+
def process(self, timeout=10.0):
|
|
28
|
+
start = time.time()
|
|
29
|
+
|
|
30
|
+
while True:
|
|
31
|
+
if timeout:
|
|
32
|
+
remain = start + timeout - time.time()
|
|
33
|
+
if remain <= 0.0:
|
|
34
|
+
break
|
|
35
|
+
else:
|
|
36
|
+
remain = None
|
|
37
|
+
|
|
38
|
+
resp = self._waitResp(["scan", "stat"], remain)
|
|
39
|
+
if resp is None:
|
|
40
|
+
break
|
|
41
|
+
|
|
42
|
+
respType = resp["rsp"][0]
|
|
43
|
+
|
|
44
|
+
if respType == "stat":
|
|
45
|
+
if resp["state"][0] == "disc":
|
|
46
|
+
self._mgmtCmd("scan")
|
|
47
|
+
|
|
48
|
+
elif respType == "scan":
|
|
49
|
+
addr = self._decode_address(resp)
|
|
50
|
+
|
|
51
|
+
if not self.mac or addr == self.mac:
|
|
52
|
+
dev = self._find_or_create(addr)
|
|
53
|
+
|
|
54
|
+
newData = dev._update(resp)
|
|
55
|
+
|
|
56
|
+
if self.delegate:
|
|
57
|
+
self.delegate.handleDiscovery(dev, (dev.updateCount <= 1), newData)
|
|
58
|
+
|
|
59
|
+
if self.mac and dev.addr == self.mac:
|
|
60
|
+
break
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ScanDelegate(DefaultDelegate):
|
|
64
|
+
def __init__(self, options):
|
|
65
|
+
DefaultDelegate.__init__(self)
|
|
66
|
+
self.options = options
|
|
67
|
+
|
|
68
|
+
def handleDiscovery(self, dev, isNewDev, isNewData):
|
|
69
|
+
if not isNewDev:
|
|
70
|
+
return
|
|
71
|
+
elif self.options.mac and dev.addr != self.options.mac:
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
if self.options.buffering:
|
|
75
|
+
dev.print_info()
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from wirelessxpl.core.exploit.exploit import Exploit
|
|
2
|
+
from wirelessxpl.core.exploit.option import OptInteger
|
|
3
|
+
from wirelessxpl.core.exploit.printer import (
|
|
4
|
+
print_error,
|
|
5
|
+
print_status
|
|
6
|
+
)
|
|
7
|
+
from wirelessxpl.core.bluetooth.btle import (
|
|
8
|
+
ScanDelegate,
|
|
9
|
+
BTLEScanner
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Options:
|
|
14
|
+
""" Options used by the scanner """
|
|
15
|
+
|
|
16
|
+
def __init__(self, buffering, mac, enum_services):
|
|
17
|
+
self.buffering = buffering
|
|
18
|
+
self.mac = mac
|
|
19
|
+
self.enum_services = enum_services
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BTLEClient(Exploit):
|
|
23
|
+
""" Bluetooth Low Energy Client implementation """
|
|
24
|
+
|
|
25
|
+
scan_time = OptInteger(10, "Number of seconds to scan for")
|
|
26
|
+
buffering = False
|
|
27
|
+
enum_services = False
|
|
28
|
+
|
|
29
|
+
def btle_scan(self, mac=None):
|
|
30
|
+
""" Scans for Bluetooth Low Energy devices """
|
|
31
|
+
|
|
32
|
+
options = Options(
|
|
33
|
+
self.buffering,
|
|
34
|
+
mac,
|
|
35
|
+
self.enum_services
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
scanner = BTLEScanner(options.mac).withDelegate(ScanDelegate(options))
|
|
39
|
+
|
|
40
|
+
if options.mac:
|
|
41
|
+
print_status("Scanning BTLE device...")
|
|
42
|
+
else:
|
|
43
|
+
print_status("Scanning for BTLE devices...")
|
|
44
|
+
|
|
45
|
+
devices = []
|
|
46
|
+
try:
|
|
47
|
+
devices = [res for res in scanner.scan(self.scan_time)]
|
|
48
|
+
except Exception as err:
|
|
49
|
+
print_error("Error: {}".format(err))
|
|
50
|
+
print_error("Check if your bluetooth hardware is connected")
|
|
51
|
+
|
|
52
|
+
return devices
|