New Payload/Tool: FICBunny (#471)

* Added FICBunny

* Added disclaimer regarding modifying /dev/nandg

* Add changes from Austin Spraggins + Some cleanup.

* Update readme.md
This commit is contained in:
Hacksawfred3232
2021-12-16 17:50:56 +00:00
committed by GitHub
parent 72d424232a
commit 0414f0cfc7
3 changed files with 286 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
#!/bin/python2
from __future__ import absolute_import
import sys
import datetime
import base64
import binascii
import struct
import time
from io import open
try:
try:
LogFile = open(u"./UIBEX_ExtractionLog.txt", u"x")
except FileExistsError:
LogFile = open(u"./UIBEX_ExtractionLog.txt", u"a")
except NameError:
try:
LogFile = open(u"./UIBEX_ExtractionLog.txt", u"a")
except OSError:
LogFile = open(u"./UIBEX_ExtractionLog.txt", u"w")
if len(sys.argv) != 2:
sys.stdout.write(u"Usage: {a} <Ubootimage/Block device containing image>\n".format(a=sys.argv[0]))
sys.exit(1)
LogFile.write(u"[{a}]: Opening file {b} for reading...\n".format(a=datetime.datetime.utcnow(),b=sys.argv[1]))
try:
InFileHan = open(sys.argv[1],u"rb")
except OSError as E:
LogFile.write(u"[{a}]: Error. {E}\n".format(a=datetime.datetime.utcnow(),E=str(E)))
sys.exit(1)
LogFile.write(u"[{a}]: File open. Loading header....\n".format(a=datetime.datetime.utcnow()))
InHeader = InFileHan.read(64)
LogFile.write(u"[{a}]: Header loaded. Checking Magic.\n".format(a=datetime.datetime.utcnow()))
try:
assert InHeader[0:4:] == "'\x05\x19V"
except AssertionError:
LogFile.write(u"[{a}]: Assertion failed, magic is not correct.\n".format(a=datetime.datetime.utcnow()))
sys.exit(1)
LogFile.write(u"[{a}]: Magic verified.\n".format(a=datetime.datetime.utcnow()))
InHedC = InHeader + "1"
InHedC = InHedC[0:64:]
# Blanking CRC.
InHedC = InHedC[0:4:] + "\x00\x00\x00\x00" + InHedC[8::]
# Verify CRC.
HeaderCRC = struct.pack(">i",binascii.crc32(InHedC))
try:
assert HeaderCRC == InHeader[4:8:]
except AssertionError:
LogFile.write(u"[{a}]: Assertion failed, CRC fail to verify. Calculated CRC: {b} Stored CRC: {c}\n".format(a=datetime.datetime.utcnow(),b=base64.b16encode(HeaderCRC),c=base64.b16encode(InHeader[4:8:])))
sys.exit(1)
LogFile.write(u"[{a}]: Header CRC: {b}\n".format(a=datetime.datetime.utcnow(),b=base64.b16encode(HeaderCRC)))
LogFile.write(u"[{a}]: Searching for uImage data.\n".format(a=datetime.datetime.utcnow()))
# Grab length and verify data.
ImageLength = struct.unpack(">i",InHeader[12:16])[0]
ImageData = InFileHan.read(ImageLength)
LogFile.write(u"[{a}]: uImage data loaded.\n".format(a=datetime.datetime.utcnow()))
# Verify CRC.
DataCRC = struct.pack(">i",binascii.crc32(ImageData))
try:
assert DataCRC == InHeader[24:28:]
except AssertionError:
LogFile.write(u"[{a}]: Assertion failed, CRC fail to verify. Calculated CRC: {b} Stored CRC: {c}\n".format(a=datetime.datetime.utcnow(),b=base64.b16encode(DataCRC),c=base64.b16encode(InHeader[24:28:])))
sys.exit(1)
LogFile.write(u"[{a}]: Data CRC: {b}\n".format(a=datetime.datetime.utcnow(),b=base64.b16encode(DataCRC)))
LogFile.write(u"[{a}]: Both CRC's have been verified. Extraction complete.\n".format(a=datetime.datetime.utcnow()))
LogFile.write(u"[{a}]: Here is header information:\n".format(a=datetime.datetime.utcnow()))
HeaderDataT = [
(u"Image Header Magic Number",base64.b16encode(InHeader[0:4]).decode()),
(u"Image Header CRC Checksum",base64.b16encode(InHeader[4:8]).decode()),
(u"Image Creation Timestamp",base64.b16encode(InHeader[8:12]).decode()),
(u"Image Data Size",base64.b16encode(InHeader[12:16]).decode()),
(u"Data Load Address",base64.b16encode(InHeader[16:20]).decode()),
(u"Entry Point Address",base64.b16encode(InHeader[20:24]).decode()),
(u"Image Data CRC Checksum",base64.b16encode(InHeader[24:28]).decode()),
(u"Operating System",ord(InHeader[28])),
(u"CPU architecture",ord(InHeader[29])),
(u"Image Type",ord(InHeader[30])),
(u"Compression Type",ord(InHeader[31])),
(u"Image Name",InHeader[32::].split("\x00")[0].decode())
]
for x in HeaderDataT:
LogFile.write(u"{x0}: {x1}\n".format(x0=x[0],x1=x[1]))
OutFileName = "./uImage-{a}.img".format(a=int(time.time()//1))
LogFile.write(u"[{a}]: Writing image to {OutFileName}\n".format(a=datetime.datetime.utcnow(),OutFileName=OutFileName))
OutFileHan = open(OutFileName,u"wb")
OutBytes = OutFileHan.write(InHeader + ImageData)
LogFile.write(u"[{a}]: Written {OutBytes} bytes.\n".format(a=datetime.datetime.utcnow(),OutBytes=OutBytes))
LogFile.write(u"[{a}]: -------------------------------------------------------\n".format(a=datetime.datetime.utcnow()))
LogFile.close()
sys.exit(0)

View File

@@ -0,0 +1,156 @@
#!/bin/bash
#
# Title: FICBunny
# Description: Firmware Image Creator for the Bash Bunny
# Author: HSF3232
# Version: 1.0
# Last tested Bunny Firmware version: 1.7
#
# LED STATUS
# Slow blinking Red - Failed to get the script. Please check that "UIBEX.py" exists within the payload directory.
# Solid Magenta - Setup in progress...
# Single blinking Yellow - STAGE 1
# Double blinking Yellow - STAGE 2
# Triple blinking Yellow - STAGE 3
# Quadruple blinking Yellow - STAGE 4
# Solid Red (After STAGE 4) - Firmware image is missing. If WriteToRecovery is on, will copy the missing firmware image to recovery.
# Quadruple blinking Cyan (After STAGE 4) - Firmware image exists. If Overwrite and WriteToRecovery are on, will replace the firmware image.
# Very fast Blinking Magenta - I am writing to the recovery partition, DO NOT UNPLUG!
########
# VARS #
########
# WriteToRecovery - When firmware image extraction is complete, write the firmware image to recovery?
WriteToRecovery=1
# Overwrite - If an existing firmware file is detected within recovery, overwrite it?
Overwrite=0
#################################
# DO NOT TOUCH BELOW THIS LINE! #
#################################
GET SWITCH_POSITION
###############
# SETUP Stage.#
###############
# Setup stage will force turn off ATTACKMODE to allow access to storage, then we will copy the required script and make the necessary directories.
ATTACKMODE OFF # Enforce no access to storage. Once execution is complete, we will turn ATTACKMODE to SERIAL STORAGE.
LED SETUP
mount /dev/nandf /root/udisk # Ensure udisk is avalible to copy our UIBEX script.
switchPOS=$SWITCH_POSITION
if [ ! -e /root/udisk/payloads/$switchPOS/UIBEX.py ]; then # Needed uImage extraction script wasn't found...
LED FAIL
exit 1
fi
mkdir /tmp/rootexfs # Temporary directory for holding blank system folders and the UIBEX.py script.
mkdir /tmp/massdisk # /dev/nandf OR /dev/mmcblk0p1. We will copy our completed firmware image here for later keeping.
# Since we're executing this script from /tmp, we can unmount udisk once we're ready.
mkdir /tmp/recdisk # /dev/nandg. We will be copying our completed firmware image here once done to re-enable recovery.
mkdir /tmp/cachedisk # /dev/nandh. We will need this to store our large temporary files.
cp /root/udisk/payloads/$switchPOS/UIBEX.py /tmp/rootexfs # Copy the required script.
sleep 1 # Safety net, copying the file over.
umount /root/udisk # We're finished here.
cd /tmp/rootexfs # Using CD to change our working directory to rootexfs so we can execute UIBEX.py.
mkdir media mnt proc sys tmp # Make blank directories - We will use this later for creating rootfs.tar
chmod 555 proc sys # dr-xr-xr-x
chmod 777 tmp # drwxrwxrwx
# Mounting required partitions.
if [ -b /dev/mmcblk0p1 ]; then # If we have the SD card available to us, mount it.
mount /dev/mmcblk0p1 /tmp/massdisk
else
mount /dev/nandf /tmp/massdisk
fi
mount /dev/nandg /tmp/recdisk # Make recovery disk mount point.
mount /dev/nandh /tmp/cachedisk # Make cache disk mount point.
mkdir /tmp/cachedisk/upgrade # Make upgrade directory - we will place rootfs and uImage in here.
mkdir -p /tmp/massdisk/loot/recscript # Make storage location for output of all script related content.
###########
# STAGE 1 #
###########
# Extract the uImage file.
LED STAGE1
sleep 1 # Script may be quicker than LED blinking, so let's delay by one second for user interface.
python2 UIBEX.py /dev/nandc # Execute uImage extraction script.
mv uImage*.img /tmp/cachedisk/upgrade/uImage # move uImage to the upgrade folder
md5sum /tmp/cachedisk/upgrade/uImage > /tmp/cachedisk/upgrade/uImage.md5 # Calculate MD5, save to upgrade folder.
mv UIBEX_ExtractionLog.txt /tmp/massdisk/loot/recscript/ # Move the extraction log to output folder.
# UIBEX complete.
###########
# STAGE 2 #
###########
# Copy all system directories into rootfs.tar
LED STAGE2
sleep 1 # Script may be quicker than LED blinking, so let's delay by one second for the user interface.
tar --transform 's,^,/rootfs/,S' -cvf /tmp/cachedisk/upgrade/cherry.rootfs.tar media/ mnt/ proc/ sys/ tmp/ /boot/ /home/ /opt/ /srv/ /dev/pts /dev/shm/ /dev/fd/ /dev/ptmx /dev/stderr /dev/stdin /dev/stdout /dev/full /dev/null /dev/random /dev/urandom /dev/zero /dev/tty /root/ /run/ /etc/ /sbin/ /bin/ /lib/ /var/ /usr/ &> /tmp/massdisk/loot/recscript/RootFS_EX_errors.txt > /tmp/massdisk/loot/recscript/RootFS_EX_output.txt
# Tar all filesystem resources to rootfs.tar in upgrade folder
md5sum /tmp/cachedisk/upgrade/cherry.rootfs.tar > /tmp/cachedisk/upgrade/cherry.rootfs.tar.md5 # Calculate MD5, save to upgrade folder.
# TAR image extraction is complete.
###########
# STAGE 3 #
###########
# Compile firmware file.
LED STAGE3
sleep 1 # Script may be quicker than LED blinking, so let's delay by one second for user interface.
# Now complie the tar.gz to /tmp/massdisk/
cd /tmp/cachedisk/ # Need to move to cache disk, otherwise files would be located at /tmp/cachedisk/upgrade, not what we want!
tar -czvf "/tmp/massdisk/loot/recscript/ch_fw_`cat /root/version.txt`.tar.gz" upgrade &> /tmp/massdisk/loot/recscript/Firmware_Com_errors.txt > /tmp/massdisk/loot/recscript/Firmware_Com_output.txt
cd /tmp/rootexfs # Move back to orignal directory.
# Image compliation completed.
###########
# STAGE 4 #
###########
# Check if firmware file exists in recdisk. If not, copy generated firmware file to recdisk.
LED STAGE4
sleep 1 # Script may be quicker than LED blinking, so let's delay by one second for user interface.
# Let's check if an image already exists in the recdisk.
startString="ch_fw_"
entry=`ls /tmp/recdisk/root/ | while read line; do echo ${line} | grep "^$startString.*.tar.gz$";done | head -n 1`
NeedToWriteFirmWareImage=0
if [ "$entry" = "" ]; then
LED R SOLID # Indicate that a firmware image was missing.
sleep 1
NeedToWriteFirmWareImage=1
else
LED C QUAD # An existing firmware image was found.
sleep 1
if [ $Overwrite -eq 1 ]; then
NeedToWriteFirmWareImage=1
fi
fi
if [ $NeedToWriteFirmWareImage -eq 1 ] && [ $WriteToRecovery -eq 1 ]; then
LED M VERYFAST # Copying firmware image from massdisk to recovery disk.
cp /tmp/massdisk/loot/recscript/ch_fw*.tar.gz /tmp/recdisk/root/
sync # Just in case.
fi
###########
# CLEANUP #
###########
LED CLEANUP
sleep 1 # Script may be quicker than LED blinking, so let's delay by one second for user interface.
# Removing a bunch of directories.
rm -R /tmp/cachedisk/*
sync
umount /tmp/cachedisk
umount /tmp/massdisk
umount /tmp/recdisk
rmdir /tmp/cachedisk
rmdir /tmp/massdisk
rmdir /tmp/recdisk
rm -R /tmp/rootexfs
##########
# FINISH #
##########
LED FINISH
sleep 1
# End of the script will swap to LED BLUE SLOW and activate our storage.
LED B SLOW
ATTACKMODE SERIAL STORAGE
exit 0

View File

@@ -0,0 +1,38 @@
## FICBunny
* Title: FICBunny
* Short Description: Firmware Image Creator for the Bash Bunny
* Author: HSF3232 (@Hacksawfred3232)
* Contributer: Austin Spraggins (@spragginsdesigns)
* Version: 1.0
* Last tested Bunny Firmware version: 1.7
## Long Description
The primary purpose of this script is to create a backup image (in case you want to revert to a known good point). Then replace the missing firmware image within /dev/nandg, should it be missing.
Note: It may be a good idea to disable non-critical services - if any - on the bunny before starting this payload.
**WARNING: /dev/nandg CONTAINS RECOVERY RELATED FILES! WHILE I HAVE TESTED THIS SCRIPT MANY TIMES TO ENSURE IT DOESN'T DO ANYTHING SCREWEY, YOU NORMALLY SHOULD NOT TOUCH /dev/nandg! IF YOU DON'T WANT TO MESS WITH THE RECOVERY PARTITION, TURN OFF "WriteToRecovery"!!**
## Variables
| Name | Description | Default |
| --------------- | --------------------------------------------------------------------------------- | ------- |
| WriteToRecovery | When firmware image extraction is complete, write the firmware image to recovery? | 1 |
| Overwrite | If an existing firmware file is detected within recovery, overwrite it? | 0 |
## STATUS
| LED | Status |
| ----------------------- | ------------------------------------------------------------------------------------------------------------- |
| SETUP | Copying required script file to /tmp, creating needed directories, and mounting partitions |
| FAIL | Couldn't find the file of script needed within payload directory |
| STAGE 1 | Extracting uImage file |
| STAGE 2 | Copying rootFS into rootfs.tar |
| STAGE 3 | Compile the firmware file from rootfs.tar and uImage into a file on MassDisk |
| STAGE 4 | Looking in Recovery partition for backup firmware image |
| R SOLID | Backup firmware image missing! If told to, will copy generated backup firmware image into recovery. |
| C QUAD | Backup firmware image found! If told to, script will overwrite it. |
| M VERYFAST | Writing to recovery partition, **DO NOT UNPLUG!!!!** |
| CLEANUP | Removing temporary directories and unmounting partitions |
| FINISH | Script is finished, starting arming mode (ATTACKMODE SERIAL STORAGE) |