Its been a little while since I’ve been able to work on any of my various projects but I do plan to finish and release a couple of them soon. In the meantime I’ll be at Def Con so hit me up if anyone wants to meet up.

Hilariously rcrypt 1.5 still bypasses every AV out there (yup that includes KAV) but I assume thats mainly because 1.5 hasn’t been released outside of the web portal. The day or day after I release the stand alone 1.5 binary it will be detected! I might do this eventually but only just before another interesting release ;]

Hold onto ur panties kids.

Happy [after] April Fools!

I was wondering how long I’d let my site be “defaced” but then decided the novelty wore off pretty quickly (especially since the layout looked even better! ha). It was enjoyable watching a crap load of people download the dumped source to rcrypt. If you compile and run it you’ll enjoy a nice lil surprise. If you didn’t do this already, well, you should have =]

Anyway if you want to check out the defaced site feel free to click [april fools].

There will be a new tool coming soon. I’ve been super swamped with work and find almost no time these days for my own personal projects which is a bit depressing. I will continue to code but my free time seems to be dwindling. I hope to have this next tool released sometime soon.

I’ve finally released rcrypt 1.5 via a newly launched website over at ( Not only is rcrypt 1.5 available there but some other classic packers as well! The purpose of this site is to allow users to play with various packers without having to mess around with the packer binaries themselves. Not everyone wants to run a random exe and feel safe afterwards. As for me, I triple click all exes especially from emails from people I’ve never spoken to before!

In anycase rcrypt 1.5 is available to all users of the website and as an added bonus I’ll be creating custom ones for users who are interested and making them available to them via the rcrypt web frontend website. This makes it easier for me and hopefully the user as well.

If anyone wants to contribute their own packers or just any packer please contact me and I’ll be happy to add it to the list! There are only a few currently in the system but as time goes on I will add support for more.


rcrypt 1.5

rcrypt 1.5


For users of the command line versions of rcrypt there have always been easter eggs built into the binary. Since noone has actually bothered to look I will simply share one of them now!

rcrypt.exe [your binary] -h4x

This of course works with the optional parameters as well.

Have fun!

After making rcrypt public it almost immediately became detected. This is not surprising as when something like this becomes more public it will also become detected. Whats important to realize is rcrypt 1.4, being the current released version, is detected but the in progress (fully functional) 1.5 remains undetected.

oh n0ez

oh n0ez


Now does this mean I will rush out and release 1.5? Well not exactly. I want to make clear the types of detection there are and the kinds of things you can do about it. There seems to be no end to incorrect information and lack of understanding so I am hoping to address at least some of that now.

There are two primary methods of detecting binaries employed by AVs.

  • signature detection
  • dynamic detection

The first method is the oldest and least useful. It requires the ability to detect known static patterns in a binary to function. The second one however is far more powerful.

Signature detection is barely more technical than grepping for byte sequences. Perhaps more advanced types have a sort of error tolerance but otherwise this is trivially bypassed by slight modifications in code.

Dynamic detection completely defeats code modification because this form of detection simply executes binaries in a sandbox and observes behavior. This is the important part that I think people don’t seem to understand.

When people try to evade AVs I see techniques employed such as:

  • leetsauce METASM ninja
  • leetsauce polymorphic stuff
  • and more recently leetsauce shellcode injection into random PEs

These techniques are ALL excellent however they all bypass signature detection ONLY. They are absolutely useless against sandbox analysis. Anytime I read somewhere techniques for making msf payloads or random other payloads undetected I see people talk about projects that will, in a nutshell, modify their shellcode in some way.

I’m not knocking any of these techniques as they are all interesting and do something cool. However they don’t address the goal of evading the two main AV detection mechanisms. Another thing I’ve noticed, and I could be wrong, is that these techniques and tools don’t work on binaries at all. They only work on shellcode. This, for me, is useless.

The aim of rcrypt is to show how sandbox analysis can be defeated by, in this case, timing out the analysis engine. So how, you ask, is 1.4 detected? Seeing as how it completely defeats the strongest method of detection, sandbox analysis, it means that the detection is merely a signature match. Which means changing 1 or 2 bytes is all thats necessary to evade this weak detection (nice job KAV). The fact that 1.5 without any changes defeats this shows that the detection is quite weak and trivial to evade.

I won’t go into just how to perform these modifications as I trust that if you understand you can perform these modifications yourself. The fact is that rcrypt has, as of now, completely defeated the strong detection option and evading trivial signature matches is simply a function of swapping bytes around.

I have a couple new projects in the works that might get a public release (maybe one of them) as it seems like something that could be useful to the general public. New linux projects, new windows projects, and maybe new android projects too! A new year needs some new things and hopefully I’ll get enough time to myself to allow for some of these to see the light of day!

On a side note the reason I haven’t released rcrypt 1.5 officially is because there is literally no feature difference between it and 1.4 with the exception of 2 things.

1) rcrypt now evades AVG

2) i fixed a relocation miscalculation that causes relocation to fail if it is required (could definitely happen on occasion).

Until I add an actual valid new feature I probably won’t release 1.5 but we’ll see.


Turns out rcrypt didn’t work on Win8. This has been fixed in the unreleased rcrypt 1.5 as well lol. Still holding off releasing until something new is ready though ;]

3) rcrypt works on win8

Version 1.4 adds support for eof data. I hadn’t realized until someone commented but rcrypt destroyed any extraneous data which caused issues with any binaries that made use of this data. This has since been fixed!

MD5 Sum: 40fba75715011b13fd4521163151dbb9
SHA1 Sum: c95dc3708ba8ffafb37e21d5f12b635806fd4a00
Download: rcrypt 1.4

archive pw:

This is a writeup I did about rcrypt a few months back in PDF format for those interested in how rcrypt works. In addition to some general information this writeup shows some reverse engineering analysis and a test case given a sample of known malware in the context of AV evasion. Fun for the whole family!

File: rcrypt writeup

MD5 Sum: 10c73cc7f922c7baea6d33c35180d19a

SHA1 Sum: c05775934ab46c69bb53164a7c3fca3d9ec75b15



So I’ve been interested in the chromecast device since I had heard of it a while back and finally got around to ordering one. For $35 before shipping its not bad, even if its just to play with briefly.

Mine finally arrived today! I am going to share some very quick things I’ve discovered about this nifty little device.

Let me first start off by mentioning that I have NOT gotten this device to successfully connect to my wireless network. Part of the reason I even investigated this (and thus decided to share some of my findings here) are due to being unable to get this sweet little device onto my wifi network. That being said I think looking under the hood allows us to peer into how Google designed this device and how it works!

So step 1? Plug the thing into a power source and stick it into one of my TVs many HDMI ports and see what comes up!

The first thing that comes up is a welcome screen showing you the name of the device which is always ChromecastXXXX where the Xs are four randomly generated numbers. At this point I downloaded the android app and proceeded with the configuration which allowed me to do the following things:

1. detect my chromecastXXX device
2. configure it to connect to my wifi network
3. connect to it via my wifi network for the main functionality provided it can now connect to my wifi network.

It was step 3 that kept failing no matter how many times I tried (and rebooted the device) so I decided to see exactly how this setup process worked.

So I grabbed one of my smaller laptops (this one) and decided to try the “manual setup” which is decribed at (

So how does step 1 work? How was my app able to detect the presence of my ChromecastXXXX device? I assumed it was bluetooth and that configuration occured over a paired bluetooth channel. As it turns out that is not the case. It’s actually good old wifi!


So step one in the manual setup process is to connect to the wireless network with the SSID that represents your device name. In the case where I actually took note of this my device SSID was Chromecast8991.

So the little thing starts up an AP and lets you configure it somewhat like a router! Cool. So I connected to this AP and requested an IP address with dhclient. After [forever] I got one.

I got an IP of and the device itself turned out to be Of course the first thing I did was check for open ports. The following ports were open:

53 (non working DNS)
8008 (main communications)

As soon as you connect to the device as a client it will give you a random 4 digit code on screen which I imagine is used for further communications in the case someone else decides to connect to your unencrypted and open device SSID. It will prevent someone unable to see your TV screen to configure your device but thats about it. Once I get this thing working I will take a look at sniffing network traffic to see if I can “cross the streams” on other people’s chromecasts so to speak. Would be hilarious.


Anyway once you get this code the first step in the configuration begins. All communication with the device at this point is done over json encoded data over HTTP.

The next phase involves telling the device to scan for wireless networks so you can tell it which to connect to and with what security mechanisms. The network traffic looks like this:

GET /setup/eureka_info HTTP/1.1
Connection: keep-alive

HTTP/1.1 200 OK
Access-Control-Allow-Headers: Content-Type
Cache-Control: no-cache
Content-Type: application/json
Content-Length: 852

B0-7DBC-7BFB-F29D84AF87EF”,”uptime”:83.5,”version”:4,”wpa_configured”:false,”wpa_state”:3};,`* cSc52{zerogoki7w,/y*;,`* cSc52{z
erogoki7w,/y*GET /setup/eureka_info HTTP/1.1

Based on the traffic you can see that the /setup/eureka_info URL is used to request the initial scan/results. You can also see various information about the bssid/ssid as well as some of its current configuration, the hostname of the system connected to it, and a bunch of IDs. Also that I’ve somehow opted into sending Google information when there is a crash as well as for stats is noted. Fun. You can see that there seems to be public key crypto which is good if we’re going to be sending our wifi network details over an open and unencrypted wireless network.

I did notice during the multiple times I’ve tried to connect this to my wireless network that the public key changes so it is generated by the device and not hardcoded (which is just fine). What I did find very interesting is that this very request the last couple of times included GPS data which means this device has GPS????? Here is a snippet of a previous response:

HTTP/1.1 200 OK
Access-Control-Allow-Headers: Content-Type
Cache-Control: no-cache
Content-Type: application/json
Content-Length: 998


I’ve verified that that lat/long is exactly where I live. EXACTLY. Very creepy.

Next we see some more data about the public key to use:

{“build_version”:”12072″,”connected”:false,”has_update”:false,”hdmi_control”:true,”hotspot_bssid”:”FA:8F:XX:XX:XX:XX”,”locale”:”en_US”,”mac_address”:”D0:E7:XX:XX:XX:XX”,”name”:”Chromecast8991″,”opt_in”:{“crash”:true,”device_id”:false,”stats”:true},”public_key”:”MIIBCgKCAQEAyoaWlKNT6W5+/cJXEpIfeGvogtJ1DghEUs2PmHkX3n4bByfmMRDYjuhcb97vd8N3HFe5sld6QSc+FJz7TSGp/700e6nrkbGj9abwvobey/IrLbHTPLtPy/ceUnwmAXczkhay32auKTaM5ZYjwcHZkaU9XuOQVIPpyLF1yQerFChugCpQ+bvIoJnTkoZAuV1A1Vp4qf3nn4Ll9Bi0R4HJrGNmOKUEjKP7H1aCLSqj13FgJ2s2g20CCD8307Otq8n5fR+9/c01dtKgQacupysA+4LVyk4npFn5cXlzkkNPadcKskARtb9COTP2jBWcowDwjKSBokAgi/es/5gDhZm4dwIDAQAB”,”release_track”:”stable-channel”,”setup_state”:11,”sign”:{“certificate”:”—–BEGIN CERTIFICATE—–\nMIIDqzCCApOgAwIBAgIEUf6McjANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJV\nUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzET\nMBEGA1UECgwKR29vZ2xlIEluYzESMBAGA1UECwwJR29vZ2xlIFRWMRgwFgYDVQQD\nDA9FdXJla2EgR2VuMSBJQ0EwHhcNMTMwODA0MTcxNjM0WhcNMzMwNzMwMTcxNjM0\nWjCBgDETMBEGA1UEChMKR29vZ2xlIEluYzETMBEGA1UECBMKQ2FsaWZvcm5pYTEL\nMAkGA1UEBhMCVVMxFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEjAQBgNVBAsTCUdv\nb2dsZSBUVjEbMBkGA1UEAxMSWktCVjIgRkE4RkNBM0EwQ0QwMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+HGhzj+XEwhUT7W4FbaR8M2sNxCF0VrlWsw6\nSkFHOINt6t+4B11Q7TSfz1yzrMhUSQvaE2gP2F/h3LD03rCnnE4avonZYTBr/U/E\nJZYDjEtOClFmBmqNf6ZEE8bxF/nsit1e5XicO0OJHSmRlvibbrmC2rnFwj/cEDpm\na1hdqpRQkeG0ceb9qbvvpxBq4MBsomzzbSq2nl7dQFBpxDd2jm7g+4EC7KqWmkWt\n3XgX++0qk4qFlbc/+ySqheYYddU0eeExvg93WkTRr5m6ZuaTQn7LOO9IiR8PwSnz\nxQmuirtAc50089T1oyV7ANZlNtj2oW2XjKUvxA3n+x8jCqAwfwIDAQABoy8wLTAJ\nBgNVHRMEAjAAMAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkq\nhkiG9w0BAQUFAAOCAQEAXmXinb7zoutrwCw+3SQVGbQycnMpWz1hDRS+BZ04QCm0\naxneva74Snptjasnw3eEW9Yb1N8diLlrUWkT5Q9l8AA/W4R3B873lPTzWhobXFCq\nIhrkTDBSOtx/bQj7Sy/npmoj6glYlKKANqTCDhjHvykOLrUUeCjltYAy3i8km+4b\nTxjfB6D3IIGB3kvb1L4TmvgSuXDhkz0qx2qR/bM6vGShnNRCQo6oR4hAMFlvDlXR\nhRfuibIJwtbA2cLUyG/UjgQwJEPrlOT6ZyLRHWMjiROKcqv3kqatBfNyIjkVD4uH\nc+WK9DlJnI9bLy46qYRVbzhhDJUkfZVtDKiUbvz3bg==\n—–END CERTIFICATE—–\n”,”nonce”:”Aw4o0/sbVr537Kdrw9YotiXxCLIaiRrDkHeHrOpih3U=”,”signed_data”:”fcTwn3K4I/ccok1MeZ5/nkM0pI5v4SrTv3Q4ppOQtVL5ii3qitNo+NLhY+DM9zmnP6ndNMZbkyIEyMm7LjganoDoE+o0e0/r4TyGEGLxYlfWSzf+Z3cSdNe4+MyHx/7z02E0/3lLsOFuOEPSgR26JFtyhDLCJ9Y8Cpl3GZMUqm4toaTNaIbhNMR9Bwjkz4ozKXzFl9dF5FTU6N48KeUP/3CuYqgm04BVUGxg+DbBmTidRnZE4eGdt9ICJht9ArUNQDL2UdRYVY2sfgLmF29exTaSrVkBZb/MsbDxN5nYpF1uE7IhzJnT5yFM9pmUOIKKTfeVaLVLGgoWd+pjEbOv+Q==”},”ssdp_udn”:”82c5cb87-27b4-2a9a-d4e1-5811f2b1992c”,”ssid”:””,”uma_client_id”:”4DE23B6E-B2B0-7DBC-7BFB-F29D84AF87EF”,”uptime”:101.98,”version”:4,”wpa_configured”:false,”wpa_state”:3}GET /setup/eureka_info HTTP/1.1

After this the device knows you are ready to configure it and returns the next bit of data which represents the results of a successful wireless scan of potential SSIDs to connect to:

gnal_level”:-42,”ssid”:”myotherssid”,”wpa_auth”:7,”wpa_cipher”:4},{“bssid”:”30:46:xx:xx:xx:xx”,”signal_level”:-53,”ssid”:”Hooters”,”wpa_auth”:7,”wpa_cipher”:4},{“bssid”:”00:1d:xx:xx:xx:xx”,”signal_level”:-61,”ssid”:”neighborsssid”,”wpa_auth”:7,”wpa_cipher”:4},{“bssid”:”b8:9b:xx:xx:xx:xx”,”signal_level”:-64,”ssid”:”anotherRetardedNeighborSSID”,”wpa_auth”:7,”wpa_cipher”:4},{“bssid”:”06:27:xx:xx:xx:xx”,”signal_level”:-42,”ssid”:”free open wifi1″,”wpa_auth”:1,”wpa_cipher”:1},{“bssid”:”06:27:xx:xx:xx:xx”,”signal_level”:-44,”ssid”:”more free open wifi”,”wpa_auth”:1,”wpa_cipher”:1}]&,* cSc52{zerogoki7w,/y*&,* cSc563:T`;&,* cSc562zerogoki7w,/y*&,* cSc563:T`;zerogokiwwwwgooglecom


A fun thing to note is that I’ve opted for not sending any information but this is conveniently ignored and I am still opting in for submitting data when there is a crash and for stats. Anyway, you can see SSID signal levels and other information. At this point you configure the device to connect to a wifi network by telling it the SSID and password.

This looks like the following:

POST /setup/connect_wifi HTTP/1.1
Connection: keep-alive
Content-Length: 450
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36
Content-Type: application/json;charset=UTF-8
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

{“bssid”:”5c:0a:xx:xx:xx:xx”,”signal_level”:-42,”ssid”:”myotherssid”,”wpa_auth”:7,”wpa_cipher”:4,”enc_passwd”:”AKWQ1K76dYzBzd5XLCkieFepJq+jvWcDMzTWGud7U66iWpfHS5LN4hhzEEcCdrWGyRC2pw0FRbx6dXUILPr40Os2ysp7AYqIloazqc6JsKAP+aLVv9OW8UpJJTEQVbkgcJiuh9+tPLZrmnHTURWHpXlBuYSJkwZDkW8ywnTcg8+wnrRho6BtMtKyXvNH3QIJhk+nXKHxLh154aMdA9+N3R4ZfH+4SNHrFiHhILXPiBgVmsMCM64kEgNQTRNu3Fzasyfea6XVVaQdWRB2DZC+euapWM1G/Pr9dXz1MraUc2tlEaO1LvDoDmy+08+k/ATwuOQO0DjIExsrEcHQIVXfPY=”}HTTP/1.1 200 OK
Access-Control-Allow-Headers: Content-Type
Cache-Control: no-cache
Content-Length: 0

At this point you can see that the request to connect uses the URL /setup/connect_wifi and is encrypted with the public key of the router (thankfully). You can see the target SSID/BSSID cipher type and password in the request.

It is at this point that the on screen display says: Connecting to “myssid” and for me it sits there FOREVER and never connects. I even tried to connect to a router I setup 5 feet away and ended up with this being the furthest it would go.


Obviously once I get this connected I’ll continue my review of this cool little device and more importantly see what kind of fun things we can discover by analyzing its network traffic. For example I don’t even see the 4 digit code used in the communication between the client and the device but who knows? Maybe it is used in some obscure way that I haven’t seen. Another interesting thing is that although you can see that the http traffic is local between you and the device, it is facilitated over a connection to the public internet URL ( that uses local IP links/requests. I havent’ even looked at the website/js that performs these actions yet but I’m sure it would be interesting as well. Especially since I’m sure it takes note of the various responses returned from your GPS enabled device.

All in all, very impressive for a $35 device. Its tiny and comes with a built in AP used for configuration. I look forward to checking out its actual functionality once successfully connected!

rcrypt 1.3

Added functionality:
– breaks certain automated analysis engines
– added polymorphism to various other existing functionlities

If you don’t know what rcrypt is check out the original post

md5 sum: 80cc3105b0f035daa0cd19e85bc7c379
sha1 sum: 345fb729fcda1ef5bf004869abc1634092685718

download rcrypt

archive pw:


Last time I posted about this topic I had planned to support tuxonice for suspend to RAM and disk. However since then I’ve decided to drop that aspect for two reasons.

1 TOI is way behind in terms of kernel versions

2 The default in kernel suspend to RAM/disk seems to work just fine

Instead of just continuing from the last post I wanted to create a new one that is hopefully a bit more clear. Again we will start at the part of the Gentoo handbook installation where we partition our disks.

Normally we’d create partitions for boot, swap, and root. Instead we will create two partitions. One for boot and the other for encrypted LVM. This LVM partition will use logical volume management to contain an arbitrary number of logical volumes which in our case will be used for swap and root.

Creating your encrypted partition

As before using fdisk (or whatever partition tool you prefer) create to partitions.



sda1 above is set to bootable and is of filesystem type 83 (linux). sda2 is of the same filesystem type.

I normally use ext2 for my boot partition but you can use whatever you like.

mkfs.ext2 /dev/sda1

Now we will prepare our encrypted partition. Load the following modules if they aren’t already available.

modprobe dm-crypt
modprobe aes
modprobe sha256

Now format the partition with cryptsetup.

cryptsetup luksFormat /dev/sda2

Create your password and be sure to memorize it.

Now open the encrypted partition.

cryptsetup luksOpen /dev/sda2 main

Enter your password.

You will now have access to your partition in /dev/mapper/main. Keep in mind the name “main” was chosen randomly and is just the name of the file that will represent the unlocked partition. You can change it every time you unlock it if you want.

Now create the physical volume and volume group.

pvcreate /dev/mapper/main
vgcreate [vgname] /dev/mapper/main

Now we create two logical volumes in our new volume group [vgname].

lvcreate -L 1G -n swap [vgname]
lvcreate -L XG -n root [vgname]

Here I chose 1G for the swap partition size. X is just the size of the remaining space available to be for the root partition. You can find the remaining space available with the following command.


If you look at the value for the field “PE Total” you will see how much space is available for allocation. Other fields can also be helpful to such as “allocated” and “free”.

At this point you now have two logical volumes for swap and root respectively. You can now format them as you normally would.

mkswap /dev/vg/vg-swap
mkfs.ext4 /dev/vg/vg-root

At this point the rest of the gentoo handbook applies as normal. The exception is that you will need an initramfs to perform the unlocking of your encrypted partition. After you create your initramfs you will need to make sure to reference it in your grub config or whatever you use to bootstrap your OS installation.

Creating the initramfs

Now onto creating the minifilesystem loaded by the kernel first. This is necessary to decrypt your encrypted partition to allow the boot process to continue.

Create a directory to work under, as we’ll be creating a filesystem.

mkdir initramfs
cd initramfs

Now create the directories with the following.

mkdir -p bin lib dev etc mnt/root proc root sbin sys

Now copy of the usual device nodes from your existing filesystem into your initramfs.

cp -a /dev/{null,console,tty,sda1,sda2} .

Feel free to copy other devices as needed. Also if your drive is not sdaX change it accordingly.

You will want to copy over various utilities that you might want to use as well. Just be sure they are compiled with the “static” use flag as any dependencies binaries have will also need to be copied. To avoid copying over huge chains of dependencies just compile the files you want statically so you won’t have to worry about this.

Since we are using cryptsetup and lvm we will need to copy our cryptsetup and lvm binaries (built statically)  onto the filesystem.

Once you build them statically just copy them into the ./sbin directory.

Its also typical to build busybox and add it to ./bin so feel free to customize.

The main part of the initramfs is the init script in the root of the initramfs. It is what gets executed immediately after the kernel boots and then it, once the real root partition is decrypted, calls the main init script.

Below is part of my initramfs init script. This is the minimum requirement to accomplish the decryption and booting we need.

#mount proc and sys filesystems

mount  -t proc none /proc

mount -t sysfs none /sys

echo 0 > /proc/sys/kernel/printk

# decrypt

/sbin/cryptsetup luksOpen /dev/sda2 main

/sbin/lvm vgscan –mknodes

/sbin/lvm lvchange -aly vg/swap

/sbin/lvm lvchange -aly vg/root


mount /dev/mapper/vg-root /mnt/root


umount /proc

umount /sys

# and we continue

exec switch_root /mnt/root /sbin/init

Save this into your init script.

chmod u+x init

Some of the things I put in here could use a bit of explanation.

The echo 0 disables kernel printk debug messages. I did this because these kernel messages come up a lot, even during typing of my password. I found it irritating so I disabled it during the initramfs process.

The cryptsetup line is pretty straightforward as it lets us unlock our encrypted partition. The following lvm lines are to enable our logical volumes and make the representative device nodes in /dev/mapper.

The final part is where the script hands off control to the decrypted init script on the root partition. Keep in mind that there is a space between the /mnt/root and /sbin/init.

Once you’ve created the filesystem to your needs you must build this mini filesystem into an initrd gzipped cpio type file to be included along with your kernel. To build the initramfs file you can issue the following command.

find . -print0 | cpio --null -ov --format=newc | gzip -9 > /boot/my-initramfs.cpio.gz

Name your initramfs.cpio.gz file however you like and make sure to include it in your bootloader. For grub it would look something like the following.

title=My Linux

root (hd0,0)

kernel /boot/my-kernel

initrd /boot/my-initramfs.cpio.gz

At this point you can reboot your system and test your setup. Your initramfs should load and allow you to enter your encrypted partition password. After that bootup should continue as usual. You can of course make your init script smarter by checking for a correct login or spawning a busybox shell if you need to. These options are left to you.

LVM device nodes

Another thing you might want to do is add a startup script to be executed by your system during boot that will re-create the lvm device nodes as they will no longer exist when the initramfs is removed from memory after it is done. If you use swap your system won’t be able to find /dev/vg/swap since the node for it wouldn’t have been created. I’m not sure why lvm doesn’t automatically see this but I added a simple script to my /etc/local.d/ called 40_fixlvmnodes.start that has the following contents.


echo “creating lvm nodes”

/sbin/lvm vgscan –mknodes

echo “enabling swap”

swapon /dev/vg/swap

Don’t forget to make this script executable too.

chmod u+x 40_fixlvmnodes.start

Be sure to update your /etc/fstab with your root and swap filesystems with the appropriate device paths. Mine looks like this.

/dev/vg/root / ext4 noatime 0 1

/dev/vg/swap none swap sw 0 0

Additional LVM usage

It is useful to become more familiar with lvm as it can be needed if you have to make any changes. For example when I did this on my new laptop I had created the root logical volume too small. It was using only 172G leaving over 500G unallocated! Using lvextend you can add unallocated space to a logical volume provided the physical volume can accommodate it.

lvextend -L+500G /dev/vg/root

Using lvextend I was able to use the full free space for my root partition as I had originally intended. The filesystem used for my root partition is ext4. In order for this already existing filesystem to see the available space I had to expand the filesystem as well.

I was able to do this, after resizing the logical volume above, with the following.

resize2fs /dev/mapper/vg-root

Keep in mind I did this from my livecd so the filesystem was not mounted during these operations. I’ve read that ext4 can be resized during runtime however I prefer not to chance potential filesystem corruption.

Once this was done I just rebooted and verified that my root partition was as large as it should be. All was good.

Final notes on full disk encryption

Other notes are that this is not entirely full disk encryption. The boot partition is obviously left unencrypted. If you truly want your entire disk to be encrypted you would have to perform the same operations but for all things involving the /boot partition you would use a USB drive of some kind. You will need this USB disk to boot your system. This offers more protection but managing a physical item is overkill for me. I just want to mention it in case someone is interested in doing this.

Now your root and swap partitions are fully encrypted at rest! Once your system is on however the disk is obviously unencrypted so disk encryption is only really useful “at rest”. This means if you shut down your system your content is safe. However once you boot up your filesystem is available if you are, say, nabbed while your system is on. In addition to this your crypto key is in memory at a probably known location (cryptsetup/dm-crypt are open source afterall). Its unlikely you will be in a scenario where this matters as only feds and those with some fun tools can make use of this information. I just want to be complete with this article so you are more aware. Knowing the ins and outs of security is very important.

That said, enjoy!