diff --git a/Makefile b/Makefile index af3fa619..15e0e152 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ $(SDIST): setup.py pwnagotchi $(PWN_RELEASE).img: | $(PACKER) # If the packer or ansible files are updated, rebuild the image. -$(PWN_RELEASE).img: $(SDIST) builder/pwnagotchi.json.pkr.hcl builder/raspberrypi.yml $(shell find builder/data -type f) +$(PWN_RELEASE).img: $(SDIST) builder/pwnagotchi.json.pkr.hcl $(shell find builder/data -type f) # sudo $(PACKER) plugins install github.com/solo-io/arm-image # sudo $(PACKER) plugins install github.com/hashicorp/ansible diff --git a/builder/pwnagotchi.json.pkr.hcl b/builder/pwnagotchi.json.pkr.hcl index 213b0a39..9f6466b3 100644 --- a/builder/pwnagotchi.json.pkr.hcl +++ b/builder/pwnagotchi.json.pkr.hcl @@ -17,7 +17,7 @@ variable "pwn_version" { type = string } -source "arm" "rpi-pwnagotchi" { +source "arm" "rpi64-pwnagotchi" { file_checksum_url = "https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2023-05-03/2023-05-03-raspios-bullseye-arm64-lite.img.xz.sha256" file_urls = ["https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2023-05-03/2023-05-03-raspios-bullseye-arm64-lite.img.xz"] file_checksum_type = "sha256" @@ -46,6 +46,35 @@ source "arm" "rpi-pwnagotchi" { mountpoint = "/" } } +source "arm" "rpi32-pwnagotchi" { + file_checksum_url = "https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2023-05-03/2023-05-03-raspios-bullseye-armhf-lite.img.xz.sha256" + file_urls = ["https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2023-05-03/2023-05-03-raspios-bullseye-armhf-lite.img.xz"] + file_checksum_type = "sha256" + file_target_extension = "xz" + file_unarchive_cmd = ["unxz", "$ARCHIVE_PATH"] + image_path = "../../pwnagotchi-rpi-bullseye-${var.pwn_version}-armhf.img" + qemu_binary_source_path = "/usr/bin/qemu-arm-static" + qemu_binary_destination_path = "/usr/bin/qemu-arm-static" + image_build_method = "resize" + image_size = "9G" + image_type = "dos" + image_partitions { + name = "boot" + type = "c" + start_sector = "8192" + filesystem = "fat" + size = "256M" + mountpoint = "/boot" + } + image_partitions { + name = "root" + type = "83" + start_sector = "532480" + filesystem = "ext4" + size = "0" + mountpoint = "/" + } +} source "arm" "opi-pwnagotchi" { file_checksum_url = "../../images/pwnagotchi-orangepi-raspios.img.xz.sha256" file_urls = ["../../images/pwnagotchi-orangepi-raspios.img.xz"] @@ -72,8 +101,8 @@ source "arm" "opi-pwnagotchi" { # documentation for build blocks can be found here: # https://www.packer.io/docs/from-1.5/blocks/build build { - name = "Raspberry Pi Pwnagotchi" - sources = ["source.arm.rpi-pwnagotchi"] + name = "Raspberry Pi 64 Pwnagotchi" + sources = ["source.arm.rpi64-pwnagotchi"] provisioner "file" { destination = "/usr/bin/" @@ -112,7 +141,52 @@ build { provisioner "ansible-local" { command = "ANSIBLE_FORCE_COLOR=1 PYTHONUNBUFFERED=1 PWN_VERSION=${var.pwn_version} PWN_HOSTNAME=${var.pwn_hostname} ansible-playbook" extra_arguments = ["--extra-vars \"ansible_python_interpreter=/usr/bin/python3\""] - playbook_file = "../builder/raspberrypi.yml" + playbook_file = "../builder/raspberrypi64.yml" + } +} + +build { + name = "Raspberry Pi 32 Pwnagotchi" + # sources = ["source.arm.rpi32-pwnagotchi"] + + provisioner "file" { + destination = "/usr/bin/" + sources = [ + "../builder/data/usr/bin/pwnlib", + "../builder/data/usr/bin/bettercap-launcher", + "../builder/data/usr/bin/pwnagotchi-launcher", + "../builder/data/usr/bin/monstop", + "../builder/data/usr/bin/monstart", + "../builder/data/usr/bin/hdmion", + "../builder/data/usr/bin/hdmioff", + ] + } + provisioner "shell" { + inline = ["chmod +x /usr/bin/*"] + } + + provisioner "file" { + destination = "/etc/systemd/system/" + sources = [ + "../builder/data/etc/systemd/system/pwngrid-peer.service", + "../builder/data/etc/systemd/system/pwnagotchi.service", + "../builder/data/etc/systemd/system/bettercap.service", + ] + } + provisioner "file" { + destination = "/etc/update-motd.d/01-motd" + source = "../builder/data/etc/update-motd.d/01-motd" + } + provisioner "shell" { + inline = ["chmod +x /etc/update-motd.d/*"] + } + provisioner "shell" { + inline = ["apt-get -y --allow-releaseinfo-change update", "apt-get -y dist-upgrade", "apt-get install -y --no-install-recommends ansible"] + } + provisioner "ansible-local" { + command = "ANSIBLE_FORCE_COLOR=1 PYTHONUNBUFFERED=1 PWN_VERSION=${var.pwn_version} PWN_HOSTNAME=${var.pwn_hostname} ansible-playbook" + extra_arguments = ["--extra-vars \"ansible_python_interpreter=/usr/bin/python3\""] + playbook_file = "../builder/raspberrypi32.yml" } } diff --git a/builder/raspberrypi64.yml b/builder/raspberrypi64.yml new file mode 100644 index 00000000..d964dfef --- /dev/null +++ b/builder/raspberrypi64.yml @@ -0,0 +1,580 @@ +--- +- hosts: + - 127.0.0.1 + gather_facts: true + become: true + vars: + kernel: + min: "6.1" + full: "6.1.21-v8+" + pwnagotchi: + hostname: "{{ lookup('env', 'PWN_HOSTNAME') | default('pwnagotchi', true) }}" + version: "{{ lookup('env', 'PWN_VERSION') | default('pwnagotchi-torch', true) }}" + system: + boot_options: + - "dtoverlay=dwc2" + - "dtoverlay=spi1-3cs" + - "dtparam=i2c1=on" + - "dtparam=i2c_arm=on" + - "dtparam=spi=on" + - "gpu_mem=16" + modules: + - "i2c-dev" + services: + enable: + - bettercap.service + - dphys-swapfile.service + - fstrim.timer + - pwnagotchi.service + - pwngrid-peer.service + disable: + - apt-daily-upgrade.service + - apt-daily-upgrade.timer + - apt-daily.service + - apt-daily.timer + - avahi-daemon.service + - avahi-daemon.socket + - bluetooth.service + - ifup@wlan0.service + - triggerhappy.service + - wpa_supplicant.service + packages: + bettercap: + # We will install bettercap from source + # url: "https://github.com/jayofelony/bettercap/releases/download/2.32.1/bettercap-2.32.1.zip" + ui: "https://github.com/bettercap/ui/releases/download/v1.3.0/ui.zip" + pwngrid: + # url: "https://github.com/evilsocket/pwngrid/releases/download/v1.10.3/pwngrid_linux_aarch64_v1.10.3.zip" + apt: + downgrade: + - libpcap-dev_1.9.1-4_arm64.deb + - libpcap0.8-dev_1.9.1-4_arm64.deb + - libpcap0.8_1.9.1-4_arm64.deb + hold: + - firmware-atheros + - firmware-brcm80211 + - firmware-libertas + - firmware-misc-nonfree + - firmware-realtek + - libpcap-dev + - libpcap0.8 + - libpcap0.8-dev + remove: + - avahi-daemon + - nfs-common + - triggerhappy + - wpasupplicant + install: + - aircrack-ng + - autoconf + - bc + - bison + - bluez + - build-essential + - curl + - dkms + - dphys-swapfile + - fbi + - flex + - fonts-dejavu + - fonts-dejavu-core + - fonts-dejavu-extra + - fonts-freefont-ttf + - g++ + - gawk + - gcc-arm-none-eabi + - git + - libatlas-base-dev + - libavcodec58 + - libavformat58 + - libblas-dev + - libbz2-dev + - libc-ares-dev + - libc6-dev + - libcap-dev + - libdbus-1-dev + - libdbus-glib-1-dev + - libeigen3-dev + - libelf-dev + - libffi-dev + - libfl-dev + - libfuse-dev + - libgdbm-dev + - libgl1-mesa-glx + - libgmp3-dev + - libgstreamer1.0-0 + - libhdf5-dev + - liblapack-dev + - libncursesw5-dev + - libnetfilter-queue-dev + - libopenblas-dev + - libopenjp2-7 + - libopenmpi-dev + - libopenmpi3 + - libpcap-dev + - libraspberrypi-bin + - libraspberrypi-dev + - libraspberrypi-doc + - libraspberrypi0 + - libsqlite3-dev + - libssl-dev + - libswscale5 + - libtiff5 + - libtool + - libusb-1.0-0-dev + - lsof + - make + - python3-dbus + - python3-flask + - python3-flask-cors + - python3-flaskext.wtf + - python3-pil + - python3-pip + - python3-smbus + - qpdf + - raspberrypi-kernel-headers + - rsync + - screen + - tcpdump + - texinfo + - time + - tk-dev + - unzip + - vim + - wget + - wl + - xxd + - zlib1g-dev + environment: + ARCHFLAGS: "-arch aarch64" + QEMU_UNAME: "{{ kernel.full }}" + + tasks: + - name: Create pi user + copy: + dest: /boot/userconf + content: | + pi:$6$3jNr0GA9KIyt4hmM$efeVIopdMQ8DGgEPCWWlbx3mJJNAYci1lEXGdlky0xPyjqwKNbwTL5SrCcpb4144C4IvzWjn7Iv.QjqmU7iyT/ + + - name: change hostname + lineinfile: + dest: /etc/hostname + regexp: '^raspberrypi' + line: "{{pwnagotchi.hostname}}" + state: present + when: lookup('file', '/etc/hostname') == "raspberrypi" + register: hostname + + - name: add hostname to /etc/hosts + lineinfile: + dest: /etc/hosts + regexp: '^127\.0\.1\.1[ \t]+raspberrypi' + line: "127.0.1.1\t{{pwnagotchi.hostname}}" + state: present + when: hostname.changed + + - name: disable sap plugin for bluetooth.service + lineinfile: + dest: /lib/systemd/system/bluetooth.service + regexp: '^ExecStart=/usr/lib/bluetooth/bluetoothd$' + line: 'ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=sap' + state: present + + - name: configure dphys-swapfile + lineinfile: + path: /etc/dphys-swapfile + regexp: "^CONF_SWAPSIZE=.*$" + line: "CONF_SWAPSIZE=2048" + + - name: install packages + apt: + name: "{{ packages.apt.install }}" + state: present + update_cache: yes + install_recommends: false + + # Install nexmon to fix wireless scanning (takes 2.5G of space) + - name: clone nexmon repository + git: + repo: https://github.com/DrSchottky/nexmon.git + dest: /usr/local/src/nexmon + + - name: make firmware + shell: "source ./setup_env.sh && make" + args: + executable: /bin/bash + chdir: /usr/local/src/nexmon/ + + - name: make firmware patch (bcm43455c0) + 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: /usr/lib/firmware/brcm/brcmfmac43455-sdio.bin + follow: true + + - name: make firmware patch (bcm43436b0) + 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: /usr/lib/firmware/brcm/brcmfmac43436-sdio.bin + follow: true + + - name: make firmware patch (bcm43430a1) + 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: /usr/lib/firmware/brcm/brcmfmac43430-sdio.bin + follow: true + + - name: copy 43430-sdio as 43436s-sdio for the special 43430/1 /2 + copy: + src: /usr/lib/firmware/brcm/brcmfmac43430-sdio.bin + dest: /usr/lib/firmware/brcm/brcmfmac43436s-sdio.bin + follow: true + + - name: Delete the firmware blob to avoid it crashing + file: + state: absent + path: /usr/lib/firmware/brcm/brcmfmac43430-sdio.clm_blob + + - name: Delete the RPiZW firmware blob to avoid it crashing + file: + state: absent + path: /usr/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: /usr/lib/firmware/brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.clm_blob + + - name: Delete the RPi02w firmware blob to avoid it crashing + file: + state: absent + path: /usr/lib/firmware/brcm/brcmfmac43430b0-sdio.raspberrypi,model-zero-2-w.clm_blob + + - name: Delete the RPi02w firmware blob to avoid it crashing + file: + state: absent + path: /usr/lib/firmware/brcm/brcmfmac43436-sdio.clm_blob + + - name: Delete the RPi302w firmware blob to avoid it crashing + file: + state: absent + path: /usr/lib/firmware/brcm/brcmfmac43436-sdio.raspberrypi,model-zero-2-w.clm_blob + + - name: Delete the RPi02w firmware blob to avoid it crashing + file: + state: absent + path: /usr/lib/firmware/brcm/brcmfmac43455-sdio.clm_blo + + - name: backup original driver + command: "mv /usr/lib/modules/{{ kernel.full }}/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko.xz /usr/lib/modules/{{ kernel.full }}/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko.xz.orig" + + - name: copy modified driver + copy: + src: "/usr/local/src/nexmon/patches/driver/brcmfmac_{{ kernel.min }}.y-nexmon/brcmfmac.ko" + dest: "/usr/lib/modules/{{ kernel.full }}/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko" + + - name : load brcmfmac drivers + command: "/sbin/depmod -a" + + # To shrink the final image, remove the nexmon directory (takes 2.5G of space) post build and installation + - name: Delete nexmon content & directory + file: + state: absent + path: /usr/local/src/nexmon/ + + - name: Create custom plugin directory + file: + path: /usr/local/share/pwnagotchi/custom-plugins/ + state: directory + + - name: Create custom config directory + file: + path: /etc/pwnagotchi/conf.d/ + state: directory + + - name: clone pwnagotchi repository + git: + repo: https://github.com/jayofelony/pwnagotchi.git + dest: /usr/local/src/pwnagotchi + register: pwnagotchigit + + - 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 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: remove pwnagotchi folder + file: + state: absent + path: /usr/local/src/pwnagotchi + + - name: create /usr/local/share/pwnagotchi/ folder + file: + path: /usr/local/share/pwnagotchi/ + state: directory + + #- name: Install go-1.21 + # unarchive: + # src: https://go.dev/dl/go1.21.3.linux-arm64.tar.gz + # dest: /usr/local + # remote_src: yes + # register: golang + + #- name: Update .bashrc for go-1.21 + # blockinfile: + # dest: /home/pi/.bashrc + # state: present + # block: | + # export GOPATH=$HOME/go + # export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin + # when: golang.changed + + #- name: download pwngrid 1.10.4 + # git: + # repo: https://github.com/jayofelony/pwngrid.git + # dest: /usr/local/src/pwngrid + # register: pwngrid + + #- name: install pwngrid 1.10.4 + # shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && go mod tidy && make && make install" + # args: + # executable: /bin/bash + # chdir: /usr/local/src/pwngrid + # when: pwngrid.changed + + #- name: remove pwngrid folder + # file: + # state: absent + # path: /usr/local/src/pwngrid + + #- 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 mod tidy && make && make install" + # args: + # executable: /bin/bash + # chdir: /usr/local/src/bettercap + # when: bettercap.changed + + #- name: remove bettercap folder + # file: + # state: absent + # path: /usr/local/src/bettercap + + - name: clone bettercap caplets + git: + repo: https://github.com/jayofelony/caplets.git + dest: /tmp/caplets + register: capletsgit + + - name: install bettercap caplets + make: + chdir: /tmp/caplets + target: install + when: capletsgit.changed + + - name: download and install bettercap ui + unarchive: + src: "{{ packages.bettercap.ui }}" + dest: /usr/local/share/bettercap/ + remote_src: yes + mode: 0755 + + - name: add HDMI powersave to rc.local + blockinfile: + path: /etc/rc.local + insertbefore: "exit 0" + block: | + if ! /opt/vc/bin/tvservice -s | egrep 'HDMI|DVI'; then + /opt/vc/bin/tvservice -o + fi + + - name: create /etc/pwnagotchi folder + file: + path: /etc/pwnagotchi + state: directory + + - name: check if user configuration exists + stat: + path: /etc/pwnagotchi/config.toml + register: user_config + + - name: create /etc/pwnagotchi/config.toml + copy: + dest: /etc/pwnagotchi/config.toml + content: | + # Add your configuration overrides on this file any configuration changes done to default.toml will be lost! + # Example: + # ui.display.enabled = true + # ui.display.type = "waveshare_2" + when: not user_config.stat.exists + + - name: Delete motd + file: + state: absent + path: /etc/motd + + - name: Delete motd 10-uname + file: + state: absent + path: /etc/update-motd.d/10-uname + + - name: enable ssh on boot + file: + path: /boot/ssh + state: touch + + - name: adjust /boot/config.txt + lineinfile: + dest: /boot/config.txt + insertafter: EOF + line: '{{ item }}' + with_items: "{{system.boot_options}}" + + - name: adjust /etc/modules + lineinfile: + dest: /etc/modules + insertafter: EOF + line: '{{ item }}' + with_items: "{{system.modules}}" + + - name: change root partition + replace: + dest: /boot/cmdline.txt + backup: no + regexp: "root=PARTUUID=[a-zA-Z0-9\\-]+" + replace: "root=/dev/mmcblk0p2" + + - name: configure /boot/cmdline.txt + lineinfile: + path: /boot/cmdline.txt + backrefs: True + state: present + backup: no + regexp: '(.*)$' + line: '\1 modules-load=dwc2,g_ether' + + - name: Add pwnlog alias + lineinfile: + dest: /home/pi/.bashrc + line: "\nalias pwnlog='tail -f -n300 /var/log/pwn*.log | sed --unbuffered \"s/,[[:digit:]]\\{3\\}\\]//g\" | cut -d \" \" -f 2-'" + insertafter: EOF + + - name: Add pwnver alias + lineinfile: + dest: /home/pi/.bashrc + line: "\nalias pwnver='python3 -c \"import pwnagotchi as p; print(p.__version__)\"'" + insertafter: EOF + + - name: download old libpcap packages + get_url: + url: "https://old.kali.org/kali/pool/main/libp/libpcap/{{ item }}" + dest: /usr/local/src/ + with_items: "{{ packages.apt.downgrade }}" + + - name: install old libpcap packages + apt: + force: True + state: present + deb: "/usr/local/src/{{ item }}" + with_items: "{{ packages.apt.downgrade }}" + register: libpcap + + - name: remove old libpcap files + file: + path: "/usr/local/src/{{ item }}" + state: absent + with_items: "{{ packages.apt.downgrade }}" + + - name: add firmware packages to hold + dpkg_selections: + name: "{{ item }}" + selection: hold + with_items: "{{ packages.apt.hold }}" + when: libpcap.changed + + - name: disable unnecessary services + systemd: + name: "{{ item }}" + state: stopped + enabled: no + with_items: "{{ services.disable }}" + + - name: enable services + systemd: + name: "{{ item }}" + enabled: true + state: stopped + with_items: "{{ services.enable }}" + register: enabled + + - name: remove unnecessary apt packages + apt: + name: "{{ packages.apt.remove }}" + state: absent + purge: yes + register: removed + + - name: clean apt cache + apt: + autoclean: true + when: removed.changed + + - name: apt clean + shell: "apt-get clean" + args: + executable: /bin/bash + + - name: remove /root/go folder + file: + state: absent + path: /root/go + + - name: remove /usr/local/go folder + file: + state: absent + path: /usr/local/go + + - name: remove pip cache + file: + state: absent + path: /root/.cache/pip + + - name: remove dependencies that are no longer required + apt: + autoremove: yes + when: removed.changed + + handlers: + - name: reload systemd services + systemd: + daemon_reload: yes + when: enabled.changed \ No newline at end of file