Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Pwnagotchi image buildable #1120

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
exclude *.pyc .DS_Store .gitignore MANIFEST.in
include requirements.txt
include setup.py
include distribute_setup.py
include README.md
include LICENSE
recursive-include bin *
recursive-include builder/data *
recursive-include pwnagotchi *.py
recursive-include pwnagotchi *.yml
recursive-include pwnagotchi *.*
90 changes: 69 additions & 21 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,30 +1,78 @@
PACKER_VERSION=1.7.2
PWN_HOSTNAME=pwnagotchi
PWN_VERSION=master
PACKER_VERSION := 1.8.3
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.
# If the unshare command is available, use it to create a separate namespace
# so hostname changes won't affect the build machine.
UNSHARE := $(shell command -v unshare)
ifneq (,$(UNSHARE))
UNSHARE := $(UNSHARE) --uts
endif

all: clean install image

langs:
@for lang in pwnagotchi/locale/*/; do\
echo "compiling language: $$lang ..."; \
./scripts/language.sh compile $$(basename $$lang); \
done

install:
curl https://releases.hashicorp.com/packer/$(PACKER_VERSION)/packer_$(PACKER_VERSION)_linux_amd64.zip -o /tmp/packer.zip
unzip /tmp/packer.zip -d /tmp
sudo mv /tmp/packer /usr/bin/packer
git clone https://github.com/solo-io/packer-builder-arm-image /tmp/packer-builder-arm-image
cd /tmp/packer-builder-arm-image && go get -d ./... && go build
sudo cp /tmp/packer-builder-arm-image/packer-builder-arm-image /usr/bin

image:
cd builder && sudo /usr/bin/packer build -var "pwn_hostname=$(PWN_HOSTNAME)" -var "pwn_version=$(PWN_VERSION)" pwnagotchi.json
sudo mv builder/output-pwnagotchi/image pwnagotchi-raspbian-lite-$(PWN_VERSION).img
sudo sha256sum pwnagotchi-raspbian-lite-$(PWN_VERSION).img > pwnagotchi-raspbian-lite-$(PWN_VERSION).sha256
sudo zip pwnagotchi-raspbian-lite-$(PWN_VERSION).zip pwnagotchi-raspbian-lite-$(PWN_VERSION).sha256 pwnagotchi-raspbian-lite-$(PWN_VERSION).img
done

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
unzip $(PACKER).zip -d $(@D)
rm $(PACKER).zip
chmod +x $@

SDIST := dist/pwnagotchi-$(PWN_VERSION).tar.gz
$(SDIST): setup.py pwnagotchi
python3 setup.py sdist

# Building the image requires packer, but don't rebuild the image just because packer updated.
$(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)
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
mv builder/output-pwnagotchi/image $@

# If any of these files are updated, rebuild the checksums.
$(PWN_RELEASE).sha256: $(PWN_RELEASE).img
sha256sum $^ > $@

# If any of the input files are updated, rebuild the archive.
$(PWN_RELEASE).zip: $(PWN_RELEASE).img $(PWN_RELEASE).sha256
zip $(PWN_RELEASE).zip $^

.PHONY: image
image: $(PWN_RELEASE).zip

clean:
rm -rf /tmp/packer-builder-arm-image
rm -f pwnagotchi-raspbian-lite-*.zip pwnagotchi-raspbian-lite-*.img pwnagotchi-raspbian-lite-*.sha256
rm -rf builder/output-pwnagotchi builder/packer_cache
- python3 setup.py clean --all
- rm -rf dist pwnagotchi.egg-info
- rm -f $(PACKER)
- rm -f $(PWN_RELEASE).*
- sudo rm -rf builder/output-pwnagotchi builder/packer_cache


4 changes: 3 additions & 1 deletion builder/data/etc/network/interfaces.d/wlan0-cfg
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
allow-hotplug wlan0
iface wlan0 inet static
iface wlan0 inet manual
pre-up ifconfig $IFACE up
post-down ifconfig $IFACE down
2 changes: 1 addition & 1 deletion builder/data/usr/bin/pwnlib
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ reload_brcm() {

# starts mon0
start_monitor_interface() {
iw phy "$(iw phy | head -1 | cut -d" " -f2)" interface add mon0 type monitor && ifconfig mon0 up
ifconfig wlan0 up && iw phy "$(iw phy | head -1 | cut -d" " -f2)" interface add mon0 type monitor && ifconfig mon0 up
}

# stops mon0
Expand Down
89 changes: 14 additions & 75 deletions builder/pwnagotchi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,95 +3,34 @@
{
"name": "pwnagotchi",
"type": "arm-image",
"iso_url": "https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2019-07-12/2019-07-10-raspbian-buster-lite.zip",
"iso_checksum": "9e5cf24ce483bb96e7736ea75ca422e3560e7b455eee63dd28f66fa1825db70e",
"last_partition_extra_size": 3221225472
"iso_url": "https://downloads.raspberrypi.org/raspios_oldstable_lite_armhf/images/raspios_oldstable_lite_armhf-2022-04-07/2022-04-04-raspios-buster-armhf-lite.img.xz",
"iso_checksum": "42fd907a0da36b8a8ce9db9cd1cb77746b6a10c4b77f8d0ae0b8065a3b358a37",
"target_image_size": 6442450944,
"qemu_args": ["-cpu", "arm1176"]
}
],
"provisioners": [
{
"type": "shell",
"inline": [
"sed -i 's/^\\([^#]\\)/#\\1/g' /etc/ld.so.preload",
"mv /etc/ld.so.preload /etc/ld.so.preload.DISABLED",
"uname -a",
"dpkg-architecture",
"apt-get -y update",
"apt-get install -y ansible"
"mkdir -p /usr/local/src/pwnagotchi"
]
},
{
"type": "file",
"source": "data/usr/bin/pwnlib",
"destination": "/usr/bin/pwnlib"
},
{
"type": "file",
"source": "data/usr/bin/bettercap-launcher",
"destination": "/usr/bin/bettercap-launcher"
},
{
"type": "file",
"source": "data/usr/bin/pwnagotchi-launcher",
"destination": "/usr/bin/pwnagotchi-launcher"
},
{
"type": "file",
"source": "data/usr/bin/monstop",
"destination": "/usr/bin/monstop"
},
{
"type": "file",
"source": "data/usr/bin/monstart",
"destination": "/usr/bin/monstart"
},
{
"type": "file",
"source": "data/usr/bin/hdmion",
"destination": "/usr/bin/hdmion"
},
{
"type": "file",
"source": "data/usr/bin/hdmioff",
"destination": "/usr/bin/hdmioff"
},
{
"type": "file",
"source": "data/etc/network/interfaces.d/lo-cfg",
"destination": "/etc/network/interfaces.d/lo-cfg"
},
{
"type": "file",
"source": "data/etc/network/interfaces.d/wlan0-cfg",
"destination": "/etc/network/interfaces.d/wlan0-cfg"
},
{
"type": "file",
"source": "data/etc/network/interfaces.d/usb0-cfg",
"destination": "/etc/network/interfaces.d/usb0-cfg"
},
{
"type": "file",
"source": "data/etc/network/interfaces.d/eth0-cfg",
"destination": "/etc/network/interfaces.d/eth0-cfg"
},
{
"type": "file",
"source": "data/etc/systemd/system/pwngrid-peer.service",
"destination": "/etc/systemd/system/pwngrid-peer.service"
},
{
"type": "file",
"source": "data/etc/systemd/system/pwnagotchi.service",
"destination": "/etc/systemd/system/pwnagotchi.service"
},
{
"type": "file",
"source": "data/etc/systemd/system/bettercap.service",
"destination": "/etc/systemd/system/bettercap.service"
"sources": [
"../dist/pwnagotchi-{{user `pwn_version`}}.tar.gz"
],
"destination": "/usr/local/src/pwnagotchi/"
},
{
"type": "shell",
"inline": [
"chmod +x /usr/bin/*"
"apt-get -y --allow-releaseinfo-change update",
"apt-get install -y --no-install-recommends ansible"
]
},
{
Expand All @@ -103,7 +42,7 @@
{
"type": "shell",
"inline": [
"sed -i 's/^#\\(.+\\)/\\1/g' /etc/ld.so.preload"
"mv /etc/ld.so.preload.DISABLED /etc/ld.so.preload"
]
}
]
Expand Down
86 changes: 32 additions & 54 deletions builder/pwnagotchi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@
- triggerhappy
- wpa_supplicant
- nfs-common
# Remove libraspberrypi so we can reinstall them from the kali-pi repo instead.
# This prevents kalipi-bootloader conflicts with raspberrypi-bootloader.
- libraspberrypi0
- libraspberrypi-dev
- libraspberrypi-doc
- libraspberrypi-bin
install:
- rsync
- vim
Expand All @@ -68,6 +74,7 @@
- libopenmpi-dev
- libatlas-base-dev
- libjasper-dev
- libgtk-3-0
- libqtgui4
- libqt4-test
- libopenjp2-7
Expand Down Expand Up @@ -130,7 +137,8 @@

- name: Add re4son-kernel repo key
apt_key:
url: https://re4son-kernel.com/keys/http/archive-key.asc
id: "11764EE8AC24832F"
keyserver: "keyserver.ubuntu.com"
state: present

- name: Add re4son-kernel repository
Expand Down Expand Up @@ -208,25 +216,22 @@
regexp: "#EPD_SIZE=2.0"
line: "EPD_SIZE=2.0"

- name: collect python pip package list
command: "pip3 list"
register: pip_output

- name: set python pip package facts
set_fact:
pip_packages: >
{{ pip_packages | default({}) | combine( { item.split()[0]: item.split()[1] } ) }}
with_items: "{{ pip_output.stdout_lines }}"

- name: acquire python3 pip target
command: "python3 -c 'import sys;print(sys.path.pop())'"
register: pip_target

- name: clone pwnagotchi repository
git:
repo: https://github.com/evilsocket/pwnagotchi.git
dest: /usr/local/src/pwnagotchi
register: pwnagotchigit
# pip v20.3 uses a newer dependency resolver that better handles our unique situation.
# Specifically, it handles mismatches between direct requirements without extras and
# indirect requirements that do want extras (e.g. gym vs stable-baselines->gym[atari]).
- name: Upgrade pip
pip:
name: "pip"
version: ">=20.3"

# We need the --ignore-installed option so that pip simply overwrites/upgrades existing
# packages instead of trying to uninstall them first. While this sounds dangerous,
# this matches the legacy behavior of pip. This is required to prevent pip from trying
# (and failing) to uninstall python packages that were originally installed via apt.
- name: Install pwnagotchi from source archive
pip:
name: /usr/local/src/pwnagotchi/pwnagotchi-{{ pwnagotchi.version }}.tar.gz
extra_args: --verbose --prefer-binary --ignore-installed

- name: create /usr/local/share/pwnagotchi/ folder
file:
Expand All @@ -238,38 +243,6 @@
repo: https://github.com/evilsocket/pwnagotchi-plugins-contrib.git
dest: /usr/local/share/pwnagotchi/availaible-plugins

- name: fetch pwnagotchi version
set_fact:
pwnagotchi_version: "{{ lookup('file', '/usr/local/src/pwnagotchi/pwnagotchi/_version.py') | regex_replace('.*__version__.*=.*''([0-9]+\\.[0-9]+\\.[0-9]+[A-Za-z0-9]*)''.*', '\\1') }}"

- name: pwnagotchi version found
debug:
msg: "{{ pwnagotchi_version }}"

- name: build pwnagotchi wheel
command: "python3 setup.py sdist bdist_wheel"
args:
chdir: /usr/local/src/pwnagotchi
when: (pwnagotchigit.changed) or (pip_packages['pwnagotchi'] is undefined) or (pip_packages['pwnagotchi'] != pwnagotchi_version)

- name: install opencv-python
pip:
name: "https://www.piwheels.org/simple/opencv-python/opencv_python-3.4.3.18-cp37-cp37m-linux_armv6l.whl"
extra_args: "--no-deps --no-cache-dir --platform=linux_armv6l --only-binary=:all: --target={{ pip_target.stdout }}"
when: (pip_packages['opencv-python'] is undefined) or (pip_packages['opencv-python'] != '3.4.3.18')

- name: install tensorflow
pip:
name: "https://www.piwheels.org/simple/tensorflow/tensorflow-1.13.1-cp37-none-linux_armv6l.whl"
extra_args: "--no-deps --no-cache-dir --platform=linux_armv6l --only-binary=:all: --target={{ pip_target.stdout }}"
when: (pip_packages['tensorflow'] is undefined) or (pip_packages['tensorflow'] != '1.13.1')

- name: install pwnagotchi wheel and dependencies
pip:
name: "{{ lookup('fileglob', '/usr/local/src/pwnagotchi/dist/pwnagotchi*.whl') }}"
extra_args: "--no-cache-dir"
when: (pwnagotchigit.changed) or (pip_packages['pwnagotchi'] is undefined) or (pip_packages['pwnagotchi'] != pwnagotchi_version)

- name: download and install pwngrid
unarchive:
src: "{{ packages.pwngrid.url }}"
Expand Down Expand Up @@ -402,9 +375,14 @@
You learn more about me at https://pwnagotchi.ai/
when: hostname.changed

# Ansible's apt module has an "autoclean" option but it only removes packages
# that can no longer be downloaded. Ansible v2.13 added the "clean" option
# which actually purges the apt cache, but that's newer than what we can
# install from the RasPiOS repos. Instead, we'll manually clean the cache.
- name: clean apt cache
apt:
autoclean: yes
command: "apt-get clean"
args:
warn: false

- name: remove dependencies that are no longer required
apt:
Expand Down
Loading