Merge branch 'pwnagotchi-torch-testing' into pwnagotchi-torch-64

This commit is contained in:
Jeroen Oudshoorn
2023-09-24 00:43:50 +02:00
18 changed files with 145 additions and 281 deletions

2
.idea/misc.xml generated
View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (pwnagotchi)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (pwnagotchi)" project-jdk-type="Python SDK" />
</project>

2
.idea/pwnagotchi.iml generated
View File

@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.11 (pwnagotchi)" jdkType="Python SDK" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">

View File

@ -1,6 +1,21 @@
PACKER_VERSION=1.9.4
PWN_HOSTNAME=pwnagotchi
PWN_VERSION:=$(shell cut -d"'" -f2 < pwnagotchi/_version.py)
PACKER_VERSION := 1.9.4
PWN_HOSTNAME := pwnagotchi
PWN_VERSION := $(shell cut -d"'" -f2 < pwnagotchi/_version.py)
PWN_RELEASE := pwnagotchi-raspios-lite-$(PWN_VERSION)
MACHINE_TYPE := $(shell uname -m)
ifneq (,$(filter x86_64,$(MACHINE_TYPE)))
GOARCH := amd64
else ifneq (,$(filter i686,$(MACHINE_TYPE)))
GOARCH := 386
else ifneq (,$(filter arm64% aarch64%,$(MACHINE_TYPE)))
GOARCH := arm64
else ifneq (,$(filter arm%,$(MACHINE_TYPE)))
GOARCH := arm
else
GOARCH := amd64
$(warning Unable to detect CPU arch from machine type $(MACHINE_TYPE), assuming $(GOARCH))
endif
# The Ansible part of the build can inadvertently change the active hostname of
# the build machine while updating the permanent hostname of the build image.
@ -19,9 +34,8 @@ langs:
./scripts/language.sh compile $$(basename $$lang); \
done
install:
PACKER := ~/packer
PACKER_URL := https://releases.hashicorp.com/packer/$(PACKER_VERSION)/packer_$(PACKER_VERSION)_linux_amd64.zip
PACKER := /tmp/pwnagotchi/packer
PACKER_URL := https://releases.hashicorp.com/packer/$(PACKER_VERSION)/packer_$(PACKER_VERSION)_linux_$(GOARCH).zip
$(PACKER):
mkdir -p $(@D)
curl -L "$(PACKER_URL)" -o $(PACKER).zip
@ -38,9 +52,9 @@ $(PWN_RELEASE).img: | $(PACKER)
# If the packer or ansible files are updated, rebuild the image.
$(PWN_RELEASE).img: $(SDIST) builder/pwnagotchi.json builder/pwnagotchi.yml $(shell find builder/data -type f)
$(PACKER) plugins install github.com/solo-io/arm-image
sudo $(PACKER) plugins install github.com/solo-io/arm-image
cd builder && sudo $(UNSHARE) $(PACKER) build -var "pwn_hostname=$(PWN_HOSTNAME)" -var "pwn_version=$(PWN_VERSION)" pwnagotchi.json
sudo chown -R $$USER:$$USER ../builder/output-pwnagotchi
sudo chown -R $$USER:$$USER builder/output-pwnagotchi
mv builder/output-pwnagotchi/image $@
# If any of these files are updated, rebuild the checksums.
@ -57,6 +71,7 @@ image: $(PWN_RELEASE).zip
clean:
- python3 setup.py clean --all
- rm -rf dist pwnagotchi.egg-info
- rm -rf $(PACKER)
- rm -rf $(PWN_RELEASE).*
- rm -f $(PACKER)
- rm -f $(PWN_RELEASE).*
- sudo rm -rf builder/output-pwnagotchi builder/packer_cache

View File

@ -0,0 +1,26 @@
# /etc/dphys-swapfile - user settings for dphys-swapfile package
# author Neil Franklin, last modification 2010.05.05
# copyright ETH Zuerich Physics Departement
# use under either modified/non-advertising BSD or GPL license
# this file is sourced with . so full normal sh syntax applies
# the default settings are added as commented out CONF_*=* lines
# where we want the swapfile to be, this is the default
#CONF_SWAPFILE=/var/swap
# set size to absolute value, leaving empty (default) then uses computed value
# you most likely don't want this, unless you have an special disk situation
CONF_SWAPSIZE=2048
# set size to computed value, this times RAM size, dynamically adapts,
# guarantees that there is enough swap without wasting disk space on excess
#CONF_SWAPFACTOR=2
# restrict size (computed and absolute!) to maximally this limit
# can be set to empty for no limit, but beware of filled partitions!
# this is/was a (outdated?) 32bit kernel limit (in MBytes), do not overrun it
# but is also sensible on 64bit to prevent filling /var or even / partition
#CONF_MAXSWAP=2048

View File

@ -39,12 +39,17 @@ start_monitor_interface() {
rfkill unblock all
ifconfig wlan0 up
iw dev wlan0 set power_save off
airmon-ng start wlan0
airmon-ng check kill
iw phy "$(iw phy | head -1 | cut -d" " -f2)" interface add wlan0mon type monitor && ifconfig wlan0mon up
# If wlan0 is NOT taken down after bringing up mon0, then when switching to AUTO you will get:
# error 400: error while initializing wlan0mon to channel 1: iw: out=command failed: Device or resource busy (-16) err=exit status 240
ifconfig wlan0 down
}
# stops mon0
stop_monitor_interface() {
airmon-ng stop wlan0mon
ifconfig wlan0mon down && iw dev wlan0mon del
ifconfig wlan0 up
}

View File

@ -15,8 +15,7 @@
"type": "shell",
"inline": [
"uname -a",
"dpkg-architecture",
"mkdir -p /usr/local/src/pwnagotchi"
"dpkg-architecture"
]
},
{

View File

@ -204,7 +204,6 @@
git:
repo: https://github.com/DrSchottky/nexmon.git
dest: /usr/local/src/nexmon
# version: bfb3fe90c881498d7ee245b38f16722c1de26fa1
register: nexmongit
- name: make firmware
@ -234,11 +233,17 @@
replace: "KERNEL_RELEASE"
- name: make firmware patch (bcm43436b0)
shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/ && make && make install-firmware"
shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/ && make"
args:
executable: /bin/bash
chdir: /usr/local/src/nexmon/
- name: install new firmware (bcm43436b0)
copy:
src: /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/brcmfmac43436-sdio.bin
dest: /lib/firmware/brcm/brcmfmac43436-sdio.bin
- name: choose the right kernel version (bcm43430a1)
replace:
dest: /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/Makefile
@ -260,11 +265,31 @@
replace: "KERNEL_RELEASE"
- name: make firmware patch (bcm43430a1)
shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/ && make && make install-firmware"
shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/ && make"
args:
executable: /bin/bash
chdir: /usr/local/src/nexmon/
- name: install new firmware (bcm43430a1)
copy:
src: /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/brcmfmac43430-sdio.bin
dest: /lib/firmware/brcm/brcmfmac43430-sdio.bin
- name: Delete the firmware blob to avoid it crashing
file:
state: absent
path: /lib/firmware/brcm/brcmfmac43430-sdio.clm_blob
- name: Delete the RPiZW firmware blob to avoid it crashing
file:
state: absent
path: /lib/firmware/brcm/brcmfmac43430-sdio.raspberrypi,model-zero-w.clm_blob
- name: Delete the RPi3 firmware blob to avoid it crashing
file:
state: absent
path: /lib/firmware/brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.clm_blob
- name: choose the right kernel version (bcm43455c0)
replace:
dest: /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/Makefile
@ -286,15 +311,20 @@
replace: "KERNEL_RELEASE"
- name: make firmware patch (bcm43455c0)
shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/ && make && make install-firmware"
shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/ && make"
args:
executable: /bin/bash
chdir: /usr/local/src/nexmon/
- name: install new firmware (bcm43455c0)
copy:
src: /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/brcmfmac43455-sdio.bin
dest: /lib/firmware/brcm/brcmfmac43455-sdio.bin
- name: copy modified driver (everyone but RPiZW)
copy:
src: /lib/modules/6.1.21-v8+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko
dest: /lib/modules/6.1.21-v8+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko.orig
src: /lib/modules/6.1.21-v8+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko.xz
dest: /lib/modules/6.1.21-v8+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko.xz.orig
- name: copy modified driver (everyone but RPiZW)
copy:
@ -379,24 +409,31 @@
export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin
when: golang.changed
- name: download pwngrid
- name: download pwngrid 1.10.4
git:
repo: https://github.com/jayofelony/pwngrid.git
dest: /usr/local/src/
dest: /usr/local/src/pwngrid
register: pwngrid
- name: install pwngrid
shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && make && sudo make install"
- name: install pwngrid 1.10.4
shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && sudo make && sudo make install"
args:
executables: /bin/bash
chdir: /usr/local/src/pwngrid
when: pwngrid.changed
- name: download bettercap v2.32.1
git:
repo: https://github.com/jayofelony/bettercap.git
dest: /usr/local/src/bettercap
register: bettercap
- name: Install bettercap v2.32.1
shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && go env -w GO111MODULE=off && go get github.com/jayofelony/bettercap && cd $GOPATH/src/github.com/jayofelony/bettercap && make build && make install"
shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && sudo make && sudo make install"
args:
executable: /bin/bash
register: bettercap
chdir: /usr/local/src/bettercap
when: bettercap.changed
- name: clone bettercap caplets
git:
@ -519,10 +556,10 @@
echo "- sudo pwnagotchi --check-update, to see if there is a new version available"
echo
echo "If you want to know if I'm running, you can use"
echo "systemctl status pwnagotchi"
echo "sudo systemctl status pwnagotchi"
echo
echo "You can restart me using"
echo "systemctl restart pwnagotchi"
echo "sudo systemctl restart pwnagotchi"
echo
echo "You learn more about me at https://pwnagotchi.ai/"
when: hostname.changed

View File

@ -1 +1 @@
__version__ = '2.4.2'
__version__ = '2.4.3'

View File

@ -70,7 +70,8 @@ class Client(object):
while True:
logging.info("[bettercap] creating new websocket...")
try:
async with websockets.connect(s, ping_interval=ping_interval, ping_timeout=ping_timeout, max_queue=max_queue) as ws:
async with websockets.connect(s, ping_interval=ping_interval, ping_timeout=ping_timeout,
max_queue=max_queue) as ws:
# listener loop
while True:
try:
@ -78,27 +79,26 @@ class Client(object):
try:
await consumer(msg)
except Exception as ex:
logging.debug("error while parsing event (%s)", ex)
logging.debug("[bettercap] error while parsing event (%s)", ex)
except websockets.ConnectionClosedError:
try:
pong = await ws.ping()
await asyncio.wait_for(pong, timeout=ping_timeout)
logging.warning('ping OK, keeping connection alive...')
logging.warning('[bettercap] ping OK, keeping connection alive...')
continue
except:
sleep_time = min_sleep + max_sleep*random.random()
logging.warning('ping error - retrying connection in {} sec'.format(sleep_time))
logging.warning('[bettercap] ping error - retrying connection in {} sec'.format(sleep_time))
await asyncio.sleep(sleep_time)
break
except ConnectionRefusedError:
sleep_time = min_sleep + max_sleep*random.random()
logging.warning('nobody seems to be listening at the bettercap endpoint...')
logging.warning('retrying connection in {} sec'.format(sleep_time))
logging.warning('[bettercap] nobody seems to be listening at the bettercap endpoint...')
logging.warning('[bettercap] retrying connection in {} sec'.format(sleep_time))
await asyncio.sleep(sleep_time)
continue
except OSError:
sleep_time = min_sleep + max_sleep*random.random()
logging.warning('connection to the bettercap endpoint failed...')
logging.warning('[bettercap] connection to the bettercap endpoint failed...')
pwnagotchi.reboot()
def run(self, command, verbose_errors=True):
@ -107,8 +107,8 @@ class Client(object):
r = requests.post("%s/session" % self.url, auth=self.auth, json={'cmd': command})
except requests.exceptions.ConnectionError as e:
sleep_time = min_sleep + max_sleep*random.random()
logging.warning("can't run my request... connection to the bettercap endpoint failed...")
logging.warning('retrying run in {} sec'.format(sleep_time))
logging.warning("[bettercap] can't run my request... connection to the bettercap endpoint failed...")
logging.warning('[bettercap] retrying run in {} sec'.format(sleep_time))
sleep(sleep_time)
else:
break

View File

@ -2,8 +2,8 @@ main.name = "pwnagotchi"
main.lang = "en"
main.confd = "/etc/pwnagotchi/conf.d/"
main.custom_plugin_repos = [
"https://github.com/jayofelony/pwnagotchi-torch-plugins/archive/master.zip",
"https://github.com/evilsocket/pwnagotchi-plugins-contrib/archive/master.zip",
"https://github.com/PwnPeter/pwnagotchi-plugins/archive/master.zip",
"https://github.com/tisboyo/pwnagotchi-pisugar2-plugin/archive/master.zip",
"https://github.com/nullm0ose/pwnagotchi-plugin-pisugar3/archive/master.zip"
]
@ -40,8 +40,6 @@ main.plugins.pisugar2.enabled = false
main.plugins.pisugar2.shutdown = 5
main.plugins.pisugar2.sync_rtc_on_boot = false
main.plugins.internet-connection.enabled = true
main.plugins.grid.enabled = true
main.plugins.grid.report = true
main.plugins.grid.exclude = [
@ -59,13 +57,6 @@ main.plugins.gps.enabled = false
main.plugins.gps.speed = 19200
main.plugins.gps.device = "/dev/ttyUSB0"
main.plugins.bluetoothsniffer.enabled = false
main.plugins.bluetoothsniffer.timer = 45 # On how may seconds to scan for bluetooth devices
main.plugins.bluetoothsniffer.devices_file = "/root/handshakes/bluetooth_devices.json" # Path to the JSON file with bluetooth devices
main.plugins.bluetoothsniffer.count_interval = 86400 # On how may seconds to update count bluetooth devices
main.plugins.bluetoothsniffer.bt_x_coord = 160
main.plugins.bluetoothsniffer.bt_y_coord = 66
main.plugins.webgpsmap.enabled = false
main.plugins.onlinehashcrack.enabled = false

View File

@ -60,7 +60,7 @@ def closest_peer():
return all[0] if len(all) else None
def update_data(last_session):
def update_data(last_session, plugin_data):
brain = {}
try:
with open('/root/brain.json') as fp:
@ -84,7 +84,8 @@ def update_data(last_session):
'uname': subprocess.getoutput("uname -a"),
'brain': brain,
'version': pwnagotchi.__version__,
'build': "Pwnagotchi-Torch by Jayofelony"
'build': "Pwnagotchi-Torch by Jayofelony",
'plugins': plugin_data
}
logging.debug("updating grid data: %s" % data)

View File

@ -17,8 +17,8 @@ LAST_SESSION_FILE = '/root/.pwnagotchi-last-session'
class LastSession(object):
EPOCH_TOKEN = '[epoch '
EPOCH_PARSER = re.compile(r'^.+\[epoch (\d+)\] (.+)')
EPOCH_DATA_PARSER = re.compile(r'([a-z_]+)=([^\s]+)')
EPOCH_PARSER = re.compile(r'^.+\[epoch (\d+)] (.+)')
EPOCH_DATA_PARSER = re.compile(r'([a-z_]+)=(\S+)')
TRAINING_TOKEN = ' training epoch '
START_TOKEN = 'connecting to http'
DEAUTH_TOKEN = 'deauthing '
@ -46,7 +46,7 @@ class LastSession(object):
self.max_reward = -1000
self.avg_reward = 0
self._peer_parser = re.compile(
'detected unit (.+)@(.+) \(v.+\) on channel \d+ \(([\d\-]+) dBm\) \[sid:(.+) pwnd_tot:(\d+) uptime:(\d+)\]')
'detected unit (.+)@(.+) \(v.+\) on channel \d+ \(([\d\-]+) dBm\) \[sid:(.+) pwnd_tot:(\d+) uptime:(\d+)]')
self.parsed = False
def _get_last_saved_session_id(self):
@ -197,7 +197,7 @@ class LastSession(object):
lines.reverse()
if len(lines) == 0:
lines.append("Initial Session");
lines.append("Initial Session")
ui.on_reading_logs()

View File

@ -1,10 +1,11 @@
import os
import glob
import _thread
import threading
import importlib, importlib.util
import glob
import importlib
import importlib.util
import logging
import os
import threading
import pwnagotchi.grid
default_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "default")
loaded = {}
@ -43,7 +44,7 @@ def toggle_plugin(name, enable=True):
global loaded, database
if pwnagotchi.config:
if not name in pwnagotchi.config['main']['plugins']:
if name not in pwnagotchi.config['main']['plugins']:
pwnagotchi.config['main']['plugins'][name] = dict()
pwnagotchi.config['main']['plugins'][name]['enabled'] = enable
save_config(pwnagotchi.config, '/etc/pwnagotchi/config.toml')
@ -130,6 +131,8 @@ def load(config):
enabled = [name for name, options in config['main']['plugins'].items() if
'enabled' in options and options['enabled']]
pwnagotchi.grid.update_data(None, enabled)
# load default plugins
load_from_path(default_path, enabled=enabled)

View File

@ -1,177 +0,0 @@
import logging
import os
import subprocess
import json
import time
import pwnagotchi.plugins as plugins
import pwnagotchi.ui.fonts as fonts
from pwnagotchi.ui.components import LabeledValue
from pwnagotchi.ui.view import BLACK
from datetime import datetime
class BluetoothSniffer(plugins.Plugin):
__author__ = 'diytechtinker'
__version__ = '0.1.3'
__license__ = 'GPL3'
__description__ = 'A plugin that sniffs Bluetooth devices and saves their MAC addresses, name and counts to a JSON file'
def __init__(self):
# Defining the instance variables
self.options = {
'timer': 45,
'devices_file': '/root/handshakes/bluetooth_devices.json',
'count_interval': 86400,
'bt_x_coord': 160,
'bt_y_coord': 66
}
self.data = {}
self.last_scan_time = 0
def on_loaded(self):
logging.info("[BtS] bluetoothsniffer plugin loaded.")
logging.info("[BtS] Bluetooth devices file location: %s", self.options['devices_file'])
# Creating the device file path if it does not exist
if not os.path.exists(os.path.dirname(self.options['devices_file'])):
os.makedirs(os.path.dirname(self.options['devices_file']))
# Creating the device file if it does not exist
if not os.path.exists(self.options['devices_file']):
with open(self.options['devices_file'], 'w') as f:
json.dump({}, f)
# Loading the data from the device file
with open(self.options['devices_file'], 'r') as f:
self.data = json.load(f)
def on_ui_setup(self, ui):
with ui._lock:
ui.add_element('BtS', LabeledValue(color=BLACK,
label='BT SNFD',
value=" ",
position=(int(self.options["bt_x_coord"]),
int(self.options["bt_y_coord"])),
label_font=fonts.Small,
text_font=fonts.Small))
def on_unload(self, ui):
with ui._lock:
ui.remove_element('BtS')
def on_ui_update(self, ui):
current_time = time.time()
# Checking the time elapsed since last scan
if current_time - self.last_scan_time >= self.options['timer']:
self.last_scan_time = current_time
# logging.info("[BtS] Bluetooth sniffed: %s", str(self.bt_sniff_info()))
ui.set('BtS', str(self.bt_sniff_info()))
self.scan(ui)
# Method for scanning the nearby bluetooth devices
def scan(self, display):
logging.info("[BtS] Scanning for bluetooths...")
current_time = time.time()
changed = False
# Running the system command hcitool to scan nearby bluetooth devices
cmd_inq = "hcitool inq --flush"
try:
inq_output = subprocess.check_output(cmd_inq.split())
except subprocess.CalledProcessError as e:
logging.error("[BtS] Error running command: %s", e)
for line in inq_output.splitlines()[1:]:
fields = line.split()
mac_address = fields[0].decode()
for i in range(len(fields)):
if fields[i].decode() == "class:" and i+1 < len(fields):
device_class = fields[i+1].decode()
logging.info("[BtS] Found bluetooth %s", mac_address)
# Update the count, first_seen, and last_seen time of the device
if mac_address in self.data and len(self.data) > 0:
if 'Unknown' == self.data[mac_address]['name']:
name = self.get_device_name(mac_address)
self.data[mac_address]['name'] = name
self.data[mac_address]['new_info'] = 2
logging.info("[BtS] Updated bluetooth name: %s", name)
changed = True
if 'Unknown' == self.data[mac_address]['manufacturer']:
manufacturer = self.get_device_manufacturer(mac_address)
self.data[mac_address]['manufacturer'] = manufacturer
self.data[mac_address]['new_info'] = 2
logging.info("[BtS] Updated bluetooth manufacturer: %s", manufacturer)
changed = True
if device_class != self.data[mac_address]['class']:
self.data[mac_address]['class'] = device_class
self.data[mac_address]['new_info'] = 2
logging.info("[BtS] Updated bluetooth class: %s", device_class)
changed = True
last_seen_time = int(datetime.strptime(self.data[mac_address]['last_seen'], '%H:%M:%S %d-%m-%Y').timestamp())
if current_time - last_seen_time >= self.options['count_interval']:
self.data[mac_address]['count'] += 1
self.data[mac_address]['last_seen'] = time.strftime('%H:%M:%S %d-%m-%Y', time.localtime(current_time))
self.data[mac_address]['new_info'] = 2
logging.info("[BtS] Updated bluetooth count.")
changed = True
else:
name = self.get_device_name(mac_address)
manufacturer = self.get_device_manufacturer(mac_address)
self.data[mac_address] = {'name': name, 'count': 1, 'class': device_class, 'manufacturer': manufacturer, 'first_seen': time.strftime('%H:%M:%S %d-%m-%Y', time.localtime(current_time)), 'last_seen': time.strftime('%H:%M:%S %d-%m-%Y', time.localtime(current_time)), 'new_info': True}
logging.info("[BtS] Added new bluetooth device %s with MAC: %s", name, mac_address)
changed = True
# Save the updated devices to the JSON file
if changed:
with open(self.options['devices_file'], 'w') as f:
logging.info("[BtS] Saving bluetooths %s into json.", name)
json.dump(self.data, f)
display.set('status', 'Bluetooth sniffed and stored!')
display.update(force=True)
# Method to get the device name
def get_device_name(self, mac_address):
logging.info("[BtS] Trying to get name for %s", mac_address)
name = 'Unknown'
hcitool_process = subprocess.Popen(["hcitool", "name", mac_address], stdout=subprocess.PIPE)
output, error = hcitool_process.communicate()
if output.decode().strip() != '':
name = output.decode().strip()
logging.info("[BtS] Got name %s for %s", name, mac_address)
return name
# Method to get the device manufacturer
def get_device_manufacturer(self, mac_address):
manufacturer = 'Unknown'
cmd_info = f"hcitool info {mac_address} | grep 'Manufacturer:' | cut -d ' ' -f 2-"
try:
logging.info("[BtS] Trying to get manufacturer for %s", mac_address)
start_time = time.time()
process = subprocess.Popen(cmd_info, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
while process.poll() is None:
time.sleep(0.1)
if time.time() - start_time > 7:
logging.info("[BtS] Timeout while trying to get manufacturer for %s", mac_address)
process.kill()
return manufacturer
output, error = process.communicate(timeout=1)
if output.decode().strip() != '':
manufacturer = output.decode().strip()
logging.info("[BtS] Got manufacturer %s for %s", manufacturer, mac_address)
except Exception as e:
logging.info("[BtS] Error while trying to get manufacturer for %s: %s", mac_address, str(e))
return manufacturer
def bt_sniff_info(self):
num_devices = len(self.data)
if num_devices > 0:
num_unknown = sum(1 for device in self.data.values() if device['name'] == 'Unknown' or device['manufacturer'] == 'Unknown')
num_known = num_devices - num_unknown
return_text = "%s|%s" % (num_devices, num_known)
else:
return_text = "0|0"
return return_text

View File

@ -473,7 +473,7 @@ class BTTether(plugins.Plugin):
devices_to_try = list()
connected_priorities = list()
any_device_connected = False # if this is true, last status on screen should be C
any_device_connected = False # if this is true, last status on screen should be C
for _, device in self.devices.items():
if device.connected():
@ -579,7 +579,7 @@ class BTTether(plugins.Plugin):
def on_ui_setup(self, ui):
with ui._lock:
ui.add_element('bluetooth', LabeledValue(color=BLACK, label='BT', value='-',
position=(ui.width() / 2 - 10, 0),
position=(ui.width() / 2 - 5, 0),
label_font=fonts.Bold, text_font=fonts.Medium))
def on_ui_update(self, ui):

View File

@ -5,6 +5,7 @@ import glob
import re
import pwnagotchi.grid as grid
import pwnagotchi.plugins
import pwnagotchi.plugins as plugins
from pwnagotchi.utils import StatusFile, WifiInfo, extract_from_pcap
from threading import Lock
@ -129,7 +130,7 @@ class Grid(plugins.Plugin):
with self.lock:
try:
grid.update_data(agent.last_session)
grid.update_data(agent.last_session, None)
except Exception as e:
logging.error("error connecting to the pwngrid-peer service: %s" % e)
logging.debug(e, exc_info=True)

View File

@ -1,36 +0,0 @@
import os
import logging
import re
import subprocess
from io import TextIOWrapper
from pwnagotchi import plugins
class Watchdog(plugins.Plugin):
__author__ = '33197631+dadav@users.noreply.github.com'
__version__ = '0.1.0'
__license__ = 'GPL3'
__description__ = 'Restart pwnagotchi when blindbug is detected.'
def __init__(self):
self.options = dict()
self.pattern = re.compile(r'brcmf_cfg80211_nexmon_set_channel.*?Set Channel failed')
def on_loaded(self):
"""
Gets called when the plugin gets loaded
"""
logging.info("Watchdog plugin loaded.")
def on_epoch(self, agent, epoch, epoch_data):
# get last 10 lines
last_lines = ''.join(list(TextIOWrapper(subprocess.Popen(['journalctl','-n10','-k', '--since', '-5m'],
stdout=subprocess.PIPE).stdout))[-10:])
if len(self.pattern.findall(last_lines)) >= 5:
display = agent.view()
display.set('status', 'Blind-Bug detected. Restarting.')
display.update(force=True)
logging.info('[WATCHDOG] Blind-Bug detected. Restarting.')
mode = 'MANU' if agent.mode == 'manual' else 'AUTO'
import pwnagotchi
pwnagotchi.reboot(mode=mode)

View File

@ -58,8 +58,7 @@ class DottedTomlEncoder(TomlEncoder):
if not retstr.endswith('\n\n'):
retstr += '\n'
else:
retstr += (pre + qsection + " = " +
str(self.dump_value(value)) + '\n')
retstr += (pre + qsection + " = " + str(self.dump_value(value)) + '\n')
return retstr, self._dict()