Git Product home page Git Product logo

kali-rpi-luks-crypt's Introduction

Full disk encryption for Kali on Raspberry (or other similar architecture) using LUKS

This HOWTO is dedicated to running Kali on Raspberry (or other similar architecture, e.g. ODROID-C2 using full disk encryption with LUKS. Based on the little bit outdated document here.

Motivation

Deploying Kali on Raspberry Pi (or other similar, small, low-powered hardware) in a LAN environment as a "throw-away-hackbox" is obviously useful. However, keeping the collected data in secret is an essential requirement. Here comes full disk encryption as a mandatory security concept.

Prerequisites

First we should setup an official current Kali image for the Raspberry Pi (without encryption) on an SD card.

The recommended option (now) is using a Raspberry Pi 3 custom build with the nexmon patch (for using the onboard WiFi monitoring and injecting capabilities). There is an automated build script in the official kali-arm-build-scripts repo which sets up the image from scratch (on a Kali distro). And here is a patched version which works on other distros than Kali, too (tested on Gentoo). Currently (2017-08) working build script for ODROID-C2 is also here in that forked repo.

Get the build tools and build the image from scratch as root (it can take couple of hours):

$ git clone https://github.com/tothi/kali-arm-build-scripts
$ cd kali-arm-build-scripts
$ sudo ./rpi3-nexmon.sh 2.0

The resulting image is rpi3-nexmon-2.0/kali-2.0-rpi3-nexmon.img.xz. Copy it on SD card (using pv for displaying progress):

# pixz -d rpi3-nexmon-2.0/kali-2.0-rpi3-nexmon.img.xz - | pv -treb | dd of=/dev/mmcblk0 bs=512k

(The image should work, it can be tested now.)

Preparing the RPi image for encrypted boot

We mount the image from the SD card and prepare an initramfs capable with LUKS features in a chroot environment. For making this work, an x86 (host) qemu-arm-static binary is needed on the SD card filesystem. The above patched rpi3-nexmon.sh build script installs and leaves it on the image, so things should work well. (Otherwise copying the appropriate qemu static binary to the image is needed.)

Initializing the chroot environment (on the host system as root):

# mkdir -p /mnt/chroot/boot
# mount /dev/mmcblk0p2 /mnt/chroot/
# mount /dev/mmcblk0p1 /mnt/chroot/boot/

# mount -t proc none /mnt/chroot/proc
# mount -t sysfs none /mnt/chroot/sys
# mount -o bind /dev /mnt/chroot/dev
# mount -o bind /dev/pts /mnt/chroot/dev/pts

# LANG=C chroot /mnt/chroot/

At first we change the default password for root:

passwd

Install required packages (in the chroot env):

# apt-get update
# apt-get install busybox cryptsetup dropbear

Note, that we have to enter the decryption key on every boot. We do it preferably remotely through SSH, that's why dropbear is needed (in the initramfs).

Now edit /boot/cmdline.txt, change root device to the mapped crypt device (/dev/mapper/crypt_sdcard) and add the appropriate cryptdevice parameter.

So here is an original /boot/cmdline.txt:

dwc_otg.fiq_fix_enable=2 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait rootflags=noload net.ifnames=0

And here is the updated one (differences in root and cryptdevice params):

dwc_otg.fiq_fix_enable=2 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mapper/crypt_sdcard cryptdevice=/dev/mmcblk0p2:crypt_sdcard rootfstype=ext4 rootwait rootflags=noload net.ifnames=0

Now create /boot/config.txt with the following content:

initramfs initramfs.gz followkernel

Note that on other hardware a similar steps are needed (the file containing the boot params on ODROID-C2 is /boot/boot.ini).

Let's set up Dropbear SSH key authentication. Create a (passwordless) keypair on the host machine (outside chroot!) and read the public key:

$ ssh-keygen -N "" -f kali-dropbear
$ cat ./kali-dropbear.pub

Add the public key to /etc/dropbear-initramfs/authorized_keys. Restrict Dropbear SSH access for setting up cryptroot only by prepending the key with this:

command="/scripts/local-top/cryptroot && kill -9 `ps | grep -m 1 'cryptroot' | cut -d ' ' -f 3`"

Fix permissions:

chmod 600 /etc/dropbear-initramfs/authorized_keys

Edit /etc/fstab. Original:

# <file system> <mount point>   <type>  <options>       <dump>  <pass>
proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       2
/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1

Updated / device changed to /dev/mapper/crypt_sdcard:

# <file system>           <mount point>   <type>  <options>       <dump>  <pass>
proc                      /proc           proc    defaults          0       0
/dev/mmcblk0p1            /boot           vfat    defaults          0       2
/dev/mapper/crypt_sdcard  /               ext4    defaults,noatime  0       1

Add this line to /etc/crypttab:

crypt_sdcard /dev/mmcblk0p2 none luks

Modify /etc/cryptsetup-initramfs/conf-hook by setting

CRYPTSETUP=y

to include cryptsetup files in initramfs image.

Finally, make initramfs for the current kernel version and leave chroot (don't bother with errors/warnings during mkinitramfs):

# ls -l /lib/modules/ |awk -F" " '{print $9}'

4.4.50-v7+
# mkinitramfs -o /boot/initramfs.gz 4.4.50-v7+

Note, that we have to be careful when generating the image (especially on other hardware), because uname -r returns the host kernel version, not the chroot one. So e.g. on ODROID-C2 /boot/mkuinitrd does not work out of the box, we should issue the commands in the script manually (adjusting the kernel version FOR OTHER HARDWARE!):

# rm /boot/initrd.img-3.14.79
# update-initramfs -c -k 3.14.79
# mkimage -A arm64 -O linux -T ramdisk -C none -a 0 -e 0 -n "uInitrd" -d /boot/initrd.img-3.14.79 /boot/uInitrd
#

Exit chroot environment

exit

Unmount filesystems and backup rootfs before creating encrypted volume (and deleting everything) on SD card:

# umount /mnt/chroot/boot
# umount /mnt/chroot/sys
# umount /mnt/chroot/proc
# mkdir -p /mnt/backup
# rsync -avh /mnt/chroot/* /mnt/backup/

Unmount the full chroot:

# umount /mnt/chroot/dev/pts
# umount /mnt/chroot/dev
# umount /mnt/chroot

Delete unencrypted root partition (num. 2) and create an empty one (fulfilling the SD card):

# echo -e "d\n2\nw" | fdisk /dev/mmcblk0
# echo -e "n\np\n2\n\n\nw" | fdisk /dev/mmcblk0

Now (probably) unplugging and inserting the SD card is needed in order to register the new partitions.

Create encrypted volume with a strong passphrase (this step destroys the original rootfs!):

# cryptsetup -v -y --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/mmcblk0p2
# cryptsetup -v luksOpen /dev/mmcblk0p2 crypt_sdcard
# mkfs.ext4 /dev/mapper/crypt_sdcard

Restore rootfs to the encrypted volume and close the disk:

# mkdir -p /mnt/encrypted
# mount /dev/mapper/crypt_sdcard /mnt/encrypted/
# rsync -avh /mnt/backup/* /mnt/encrypted/
# umount /mnt/encrypted/
# cryptsetup luksClose /dev/mapper/crypt_sdcard
# sync

Eject SD card and test it on the Raspberry.

Boot the device

The first boot process will fail und fallback into busybox. Enter the following commands:

# cryptsetup luksOpen /dev/mmcblk0p2 crypt_sdcard
## provide password
# exit

Your device should boot now. Login with the password you've chosen earlier and run:

mkinitramfs -o /boot/initramfs.gz
reboot

You will be asked for passphrase now with a nicer prompt, furthermore you should be able to ssh to the busybox and enter the passphrase (you may use a custom known_hosts file if you wish):

$ ssh -o "UserKnownHostsFile=~/.ssh/known_hosts.initramfs" -i ~/.ssh/kali-dropbear [email protected]

Once it is working, do not forget to clean up backup files on the host:

# rm -fr /mnt/backup
# rm -fr /mnt/chroot

Trouble shooting

To get full debug output during boot you can add debug=1 in cmdline.txt

kali-rpi-luks-crypt's People

Contributors

timmalich avatar tothi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

kali-rpi-luks-crypt's Issues

weird output when trying to get kernel version

hi, on the current version when running
ls -l /lib/modules/ |awk -F" " '{print $9}'
you get the following output:

5.4.83-Re4son+
5.4.83-Re4son-v7+
5.4.83-Re4son-v7l+
5.4.83-Re4son-v8+
5.4.83-Re4son-v8l+

I wasnt sure which one to choose, and I guess many others in the future won't be either. It would be great if you could add something about this to your guide.

Boot hang after "random: crng init done"

After following those steps with the newest kali version (2019.01) my raspberry hangs during boot. It takes about 95 seconds until the last message:
"random: crng init done"
appears.

Updates to tutorial

Hey, I just tried your tutorial yesterday and there are some changes that I needed to do in order to make it work. Perhaps you could update it so other people can benefit from this info (yours is the only guide thats relatively updated). I used this with a default kali arm img.xz file, on a raspberry py b+.

  1. If you use the already build kali arm img.xz from offensive security, the qemu-arm-static package is already built, no need to worry about that.

  2. writing "initramfs initramfs.gz 0x00f00000" to /boot/config.txt left my raspberry pi 3 stuck in booting everytime. I read in a forum post that just using "initramfs initramfs.gz" solved this issue and it did

  3. After following every step I was able to log in to dropbear, but it just dropped me into a busybox shell, no asking to decrypt the second partition of the sd card. Looking into it, I saw that for some reason the /scripts/local-top/cryptroot binary was not present on the system. My solution was to manually generate a dropbear hook following these instructions:
    https://stinkyparkia.wordpress.com/2014/10/14/remote-unlocking-luks-encrypted-lvm-using-dropbear-ssh-in-ubuntu-server-14-04-1-with-static-ipst/
    After getting dropped into busybox, you just type "unlock" and it asks for the password.

  4. After updating kali, the new dropbox version would try to start ssh before the interfaces were able to get an ip from dhcp. Looking into it I saw this bug report:
    https://bugs.launchpad.net/ubuntu/+source/dropbear/+bug/363958

The solution of adding a 10 second timeout in scripts/init-premount/dropbear just after "starting dropbear" worked perfectly for me.

Hope this helps

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.