Part IV: Customizations – Custom Kernels and building Chroots
This is the blog part 4 of building your custom Pentesting device. If you haven’t read the previous blogs, here are the links to them: –
So, now let’s get started with adding our own set of firmware support and customizations in the kernels. By default, the kernels supplied by the manufacturers are pretty restrictive because they want users to have the least level of access to the hardware level. This is because there is a high risk of security and also the non-technical users will mess it up if they are allowed root access. But these kernels too can be modified and multiple different features can be added to them. In short, the Android kernel is nothing but a stripped off kernel of Linux. And this is the reason why we can add multiple Linux features including chroot in them with just little modifications. And this is what we are going to do today.
Before we start building the kernel, it is always a good idea to check if there are pre-ported kernels for your device. You can start that by searching your device name in the nethunter’s official build directory. If for some reason your device is not listed there, you can start by downloading a non-nethunter universal kernel from the same repo which should be named something like kernel-nethunter-generic-armhf.
Once you have downloaded the generic kernel, you are ready to go. Now remember, these kernels only support armhf architecture devices. So, you will have to check whether your device is armhf or armel architecture. These generic kernels do no replace the existing kernel. They only modify the ramdisk for the SuperSU app, bash and shell terminal support and the init.d support. As for people who don’t know what Ramdisk is, it’s as good as a RAM portion written to a disk. You can think of this as a swap, whereas ramdisk is faster than swap. Unlike swap, where a lot of junk is directly passed on to swap and the RAM is never fully utilized until the swap is full, Ramdisks work in a different manner. For example, in the case of ramdisk, an application when launched first is transferred to the actual volatile memory i.e. the RAM, and once fully loaded it is then transferred to the partitioned disk(ramdisk). This basically improves the read and write speed to a much faster extent.
So now that we know how to get started, let’s move on to some practical stuff. There are two ways to install Linux onto your Android device: –
- The Hard way – Modifying existing kernels without installing a new one (For unsupported devices)
- The Easy way – Building nethunter kernels with the official way (For Supported devices only)
So, either of these two methods will install everything onto your device ranging from kernels to chroots and other features. These is also another method using Linux Deploy, which will only install a Linux chroot onto your system, meaning that you can still run a chrooted Linux system, but you don’t kernel features like the HID support or USB Ethernet/wireless or SDR support since we are not installing any kernel here. And this is the reason, why I won’t be including that method here since that is something we don’t need when we can run a full-fledged running Linux distro on our android. So, now let’s get started with the hard way first:
The Hard way:
The primary thing that we would want to do is to download an existing kernel so that we can modify it. There are two sources from where you may find the kernel for your device:
Now remember, we are downloading kernel sources here and not a full-fledged installable kernel. Once a kernel source has been downloaded, we would need to install toolchain to build and compile the sources. Below is the command to download the toolchain for 64-bit Linux machines:
$ git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 -b marshmallow-release toolchain64 Remember, the above command will download the toolchain for marshmallow version for the Nexus 5 series. You may need to change that depending upon the device and android version you are using. Next thing is, we will export the PATH and start the compiling the toolchain:
$ export ARCH=arm64
$ export SUBARCH=arm64
$ export CROSS_COMPILE=`pwd`/toolchain64/bin/aarch64-linux-android-
(the ending part of the 3rd command ends with hyphen. It’s not incomplete) Once done, the next thing is to navigate to the kernel directory we just downloaded and start compiling the kernel using defconfig. Kernels include multiple configuration files for e.g.: – menuconfig, xconfig, gconfig, oldconfig and the defconfig. Defconfig holds the whole configuration for the kernel including support for various firmwares. This configuration file changes according to the architecture of the device. More information on the kernel building can be found out here. Once these basic things have been compiled from the object sources, we can also start adding kernel patches for extra features. Now let’s build the kernel and add the mac80211 injection patch to add usb network adapter support to our device.
(This exact name of the defconfig may change depending upon your kernel)
In the above image, I’ve unzipped the kernel that I downloaded for the Nexus and added the patch to those files.
For the HID support, you can download the sources from here. This should directly add support for HID to your kernel:
$ git clone https://github.com/pelya/android-keyboard-gadget$ git checkout android-tegra3-grouper-3.10-marshmallow-mr1$ patch -p1 < ../kernel-3.10.patch$ make tegra3_android_defconfig$ make -j4
Similarly, other additional support and features can be added in a similar fashion and more information on the addition of other firmware support can be found here.
Once all the required features have been added, it’s time to compile the kernel and convert it to boot.img. So, first we need to download the APIs and manifest files to compile it to a bootable image file:
Once done, next thing is to synchronize the repo and start building the image. Navigate to the kernel directory and perform the following commands. The stdout of the below commands were pretty long to insert a screenshot here, but the below commands should do the trick.
$ repo sync
$ cp -f ../tegra/arch/arm/boot/zImage device/asus/grouper/kernel
$ cp .config arch/arm/configs/kali_defconfig
$ make clean$ make kali_defconfig
$ make -j4 TARGET_PRODUCT=aosp_grouper TARGET_BUILD_VARIANT=userdebug
That’s it. A boot.img file will be created in the same directory. Your kernel is now ready and you can flash the generated boot.img with fastboot like we did in the previous blog when flashing recoveries:
$ fastboot flash boot boot.img
Now, this was all about the hard way. Now let’s take a look as to how we can do all of this in a much easier manner where we have all the kernel’s and flashables ready:
The Easy Way:
Download the Nethunter Repository of Kali from github.
$ git clone https://github.com/offensive-security/kali-nethunter
Once downloaded, the next thing is to initialize the kernel directories and update the sources. One can perform the below steps to do the same:
It may take a while for the above process to complete. Once completed, this is all we need to start building the kernel. To build the final kernel and chroot, you can perform the below command for nexus. For other devices, see the help section in the image.
Once the chroot and kernel has been created, you can simply copy it to your android device and flash it via TWRP recovery. These are by far the easiest methods to modify the existing kernels. Once the kernels have been patched, you may need to check the SELinux status by opening your kali terminal in your phone and using the below command: –
When SELinux is disabled, type the following to enable it: –
For Security purposes, it is recommended that SELinux status should be enforcing. And yes, that’s it. We have finally developed our custom Kernel and a chrooted full-fledged Linux environment. In the next blog, we will start writing some automated pentesting and rubber ducky scripts for the same.