I’ve been studying penetration testing and general infosec for the last few years off and on, and recently I decided to sign up for Offensive Security’s OSCP training and certification. There’s a lot of debate about the worth of security certifications, and I think there’s a lot of truth to the idea that they aren’t good indicators of someone’s skills and abilities. But since I’m interested in getting into professional pentesting and don’t have anything security-related on my resume, I thought it wouldn’t hurt.

Students doing the OSCP training (as well as many security professionals) use the Kali Linux distribution (formerly called BackTrack), which is, not surprisingly, made by Offensive Security. I decided I’d replace the current Linux distro on my spare laptop, a Toshiba Portege R835-P81, with Kali. I booted up the laptop from a USB stick with a live version of Kali on it, and was greeted with the familiar GRUB loading screen. However, upon choosing a boot option from the menu, the laptop beeped a couple times and dumped me at a blank screen with a blinking cursor. Nothing else. I couldn’t type anything, and couldn’t even open another virtual terminal (Ctrl-Alt-F1). No error messages or anything. It was effectively a black box that I couldn’t get any information from.

Having had problems in years past installing various flavors of Linux on this laptop, I immediately suspected the intel i915 graphics driver was to blame. After some googling, I was validated in my suspicions. I tried every recommendation I found online for modifying the GRUB entries with different combinations of driver blacklist, modelist, and various graphics settings, all without any effect. So much for using Kali’s graphic installer.

My next idea was to build a Kali live image from source, thinking perhaps the images I downloaded from their website had some sort of problem or misconfigured software. After building new images from within a Kali VM, I still ended up at the Blinking Cursor of Death (BCOD).

My last idea was to boot into a vanilla Debian live distro from USB, which I knew would work on the laptop, and install the Kali OS manually. But how do we do this? Well, we can begin by looking at the source for the Kali live images:

$ git clone git://git.kali.org/live-build-config.git
$ cd live-build-config
$ tree
├── auto
│   ├── build
│   ├── clean
│   └── config
├── build_all.sh
├── config
│   ├── hooks
│   │   ├── accessibility-menu.binary
│   │   ├── forensic-menu.binary
│   │   ├── persistence-menu.binary
│   │   └── sleep.chroot
│   ├── includes.binary
│   │   └── isolinux
│   │       ├── splash.png
│   │       └── stdmenu.cfg
│   ├── includes.chroot
│   │   ├── lib
│   │   │   └── live
│   │   │       └── config
│   │   │           └── 0031-root-password
│   │   ├── root
│   │   └── usr
│   │       └── share
│   │           └── debian-installer-launcher
│   │               └── hooks
│   │                   ├── 10_nautilus
│   │                   └── 10_network_manager
│   └── package-lists
│       ├── kali.list.chroot
│       └── standard.list.chroot

15 directories, 16 files

There are two files of particular interest here. First, config/package-lists/kali.list.chroot gives us a list of default packages installed with Kali from the Kali package repositories. Second, auto/config gives us the URLs for the Kali package repositories, as well as the flags used when calling lb config, used as part of the Debian live build system. One particular line to take note of in this file is the cdebootstrap options:

--cdebootstrap-options "--keyring=/usr/share/keyrings/kali-archive-keyring.gpg --suite-config=wheezy"

So let’s begin the installation. Boot up the computer with the working Debian live USB, and open a root terminal. Determine the disk on the computer you want to install Kali onto (in my case it was /dev/sda – you can check with fdisk -l). I wanted to set up the hard drive to be LUKS-encrypted with LVM, so we can start with that:

$ fdisk /dev/sda
Command (m for help): p

Disk /dev/sda: 240.1 GB, 240057409536 bytes
255 heads, 63 sectors/track, 29185 cylinders, total 468862128 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0ffb067c

  Device Boot      Start         End      Blocks   Id  System

Command (m for help): n
Partition type:
  p   primary (0 primary, 0 extended, 4 free)
  e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-468862127, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-468862127, default 468862127): +250M

Command (m for help): n
Partition type:
  p   primary (1 primary, 0 extended, 3 free)
  e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (514048-468862127, default 514048): 
Using default value 514048
Last sector, +sectors or +size{K,M,G} (514048-468862127, default 468862127): 
Using default value 468862127

Command (m for help): t

Partition number (1-4): 2
Hex code (type L to list codes): 8e

Command (m for help): a
Partition number (1-4): 1

Command (m for help): p

Disk /dev/sda: 240.1 GB, 240057409536 bytes
255 heads, 63 sectors/track, 29185 cylinders, total 468862128 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0ffb067c

  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      514047      256000   83  Linux
/dev/sda2          514048   468862127   234174040   8e  Linux LVM

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Here I created a new partition table on my hard drive, with the first parition being a 250MB boot partition and the rest being an LVM partition. Now we create the encrypted LUKS container and logical volumes, and then add the filesystems:

$ apt-get update && apt-get install -y cryptsetup lvm2
$ cryptsetup -v --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-urandom --verify-passphrase luksFormat /dev/sda2
$ cryptsetup luksOpen /dev/sda2 lvm
$ pvcreate /dev/mapper/lvm
$ vgcreate kali /dev/mapper/lvm
$ lvcreate -L 6G kali -n swapvol
$ lvcreate -l +100%FREE kali -n rootvol
$ mkfs.ext4 /dev/mapper/kali-rootvol
$ mkswap /dev/mapper/kali-swapvol

Next, we’ll set up the boot partition and mount the new system so we can chroot into it:

$ mkfs.ext2 /dev/sda1
$ mount /dev/kali/rootvol /mnt
$ mkdir /mnt/boot
$ mount /dev/sda1 /mnt/boot
$ swapon /dev/kali/swapvol

Before we can install the operating system, however, we’ll need to fetch and install the Kali package signing keyring:

$ wget http://repo.kali.org/kali/pool/main/k/kali-archive-keyring/kali-archive-keyring_2013.1_all.deb
$ dpkg -i kali-archive-keyring_2013.1_all.deb

Now comes the fun part…installing the operating system! Remember those cdebootstrap options we saw before? Here’s where we’ll put those to use. Assuming the machine you’re installing to is amd64 architecture:

$ cdebootstrap --arch=amd64 --keyring=/usr/share/keyrings/kali-archive-keyring.gpg --suite-config=wheezy kali /mnt/ http://archive.kali.org/kali

This will take a while to install a bare-bones Kali/Debian OS. Once that’s finished, we’ll be able to chroot into the new OS we just built and install the actual packages:

$ mount -o bind /dev /mnt/dev
$ mount -o bind /proc /mnt/proc
$ cp /etc/mtab /mnt/etc/mtab
$ cp /etc/network/interfaces /mnt/etc/network/interfaces
$ chroot /mnt /bin/bash

From our chroot environment, we’ll need to edit the package repositories and modify our fstab and crypttab files:

# cat > /etc/apt/sources.list << EOF
deb http://http.kali.org/kali kali main non-free contrib
deb-src http://http.kali.org/kali kali main non-free contrib
deb http://security.kali.org/kali-security kali/updates main contrib non-free
# cat > /etc/fstab << EOF
/dev/mapper/kali-rootvol / ext4 errors=remount-ro 0 1
UUID=$(blkid |grep /dev/sda1 |grep -o "[a-f0-9-]\{36\}") /boot ext2 defaults 0 2
/dev/mapper/kali-swapvol none swap sw 0 0
# echo "lvm /dev/disk/by-uuid/$(blkid |grep /dev/sda2 |grep -o "[a-f0-9-]\{36\}") none luks" > /etc/crypttab

After this, check /etc/fstab and /etc/crypttab to make sure the right UUIDs made it in there from the subshells above (you can compare with the output of blkid).

Now it’s time to install the packages! Be warned, this will take quite a long time depending on the speed of your internet connection. We’ll get the list of packages from the config/package-lists/kali.list.chroot file in the Kali live build source we saw before. You may want to modify the following list if you want a different desktop environment besides GNOME.

# apt-get update && apt-get install linux-image-amd64 kali-linux-full \
  kali-root-login kali-defaults kali-menu kali-debtags kali-archive-keyring \
  debian-installer-launcher alsa-tools cryptsetup locales-all console-setup \
  kbd console-data console-common firmware-b43legacy-installer \
  firmware-b43-installer guymager gnome-core gnome-brave-icon-theme \
  gnome-shell-extensions nautilus-open-terminal gnome-orca

During the installation, you’ll get several prompts for configuring certain packages. Use your best judgement. Once that’s all finished, we’ll install GRUB to the boot partition (assuming a BIOS system–if you use UEFI you’re on your own for that step) and do some final touches:

# echo kali > /etc/hostname
# apt-get clean
# passwd
# grub-install --target=amd64 --recheck /dev/sda
# grub-mkconfig -o /boot/grub/grub.cfg
# exit
$ umount /mnt/proc
$ umount /mnt/dev
$ umount /mnt/boot
$ umount /mnt

If we did everything right, the generated GRUB config should work just fine. Shut down the live Debian system, yank out the USB, and reboot into your shiny new encrypted Kali system! Graphical installers are for the birds ;)