A blog on Computer Science, Security, Programming, and more...
11
May
2013

Creating Encrypted Virtual Volumes in Linux

Written by Matt

Here's how to create a "drive inside a file", the way TrueCrypt does, but using tools that are already included by default on most Linux distributions.

First, create the file that you will use as the drive using the command dd:

dd if=/dev/zero of=drive.bin bs=1048576 count=1024

The above creates a 1GB file called "drive.bin" filled with zeros, the block size being 1MB (1024*1024), and the number of blocks being 1024, which is exactly 1GB.

All the steps now will need to be run as root. We now need to associate the file with a drive using the loop device tool losetup:

losetup /dev/loop0 ./drive.bin

Now we use cryptsetup, the front-end that provides all disc encryption capabilities on Linux through dm-crypt, to initialize the virtual volume we just made and set a key for it:

cryptsetup -s 256 -y luksFormat /dev/loop0

WARNING!
========
This will overwrite data on /dev/loop0 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: [Enter password]
Verify passphrase: [Re-enter password]

Next, we use cryptsetup once again to "open" the volume and associate it to the device mapper, after the following command, the drive will show up in /dev/mapper/cryptvol:

cryptsetup luksOpen /dev/loop0 cryptvol
Enter passphrase for /dev/loop0: [Enter password]

The last step is to take your virtual drive you've just mapped and format it using your preferred filesystem, I use XFS here:

mkfs.xfs -f /dev/mapper/cryptvol

Now mount it, and use it as you would use a regular drive. The file /dev/mapper/cryptvol is seen by the system as an actual disk device. So you just have to run the following:

mkdir /media/cryptvol
mount /dev/mapper/cryptvol /media/cryptvol

That's it, now we have an XFS formatted virtual volume that's stored inside a file, associated as a loop device, and mapped through cryptsetup providing it with encryption. You can treat the folder /media/cryptvol just as you would a mounted drive. After you're done putting data or reading it, just do the following:

umount /media/cryptvol
cryptsetup luksClose cryptvol
losetup -d /dev/loop0

The first command unmount the userland level drive, the second command disassociates the mapper volume, and the last command removes the loop0 loop device from use.

The next time you want to mount the drive, just do the following:

losetup /dev/loop0 ./drive.bin
crypsetup luksOpen /dev/loop0 cryptvol
Enter passphrase for /dev/loop0: [Enter password]
mount /dev/mapper/cryptvol /media/cryptvol

And that's it, you now have a file that is encrypted with AES in cbc-essiv:sha256 mode that can be mounted as a volume. You can use a tool like hexedit to check that the data you put on the virtual volume is indeed encrypted.

Topic: Linux tags: linux, encryption
23
Apr
2013

Security News - PostgreSQL CVE-2013-1899

Written by Matt

A little old by now, but I just remembered this and went to check that my PostgreSQL install is patched. There was a recent fairly severe security issue in the PostgreSQL daemon that makes it treat clients connecting to databases that have names starting with "-" as command line arguments, giving sort of local-level access to the client even if the daemon is not running on the same machine.

There's a full report on the severity of the vulnerability here: http://blog.blackwinghq.com/2013/04/08/2/.

I'd say this shouldn't matter for most people, as PostgreSQL in most cases would be run locally, or through a UNIX socket, where it's not accessible from outside of the machine, but most managed servers use over-network clustered database systems, and most people don't firewall their VPSes properly or bind to 0.0.0.0 which makes this exploit work in a lot more cases. As the above entry says, there are over 300,000 hosts listening on port 5432 (the default PostgreSQL port).

Fairly big oversight on the part of the PostgreSQL developers.

Topic: Security tags: postgresql, RCE, DoS, CVE
23
Apr
2013

Service Fingerprinting

Written by Matt

Why is it that most services and daemons feel the need to relay their exact version and signature every time? It serves for statistics, but it does draw on security quite a bit when one knows everything about your setup from a GET request.

Compare the response from my local apache server that I used for development to the secure one I set for this server.

Default (more or less) Apache:

HTTP/1.1 200 OK
Date: Tue, 23 Apr 2013 03:04:29 GMT
Server: Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8r DAV/2 PHP/5.3.6 SVN/1.6.16
Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT
ETag: "2a5ec-2c-3e9564c23b600"
Accept-Ranges: bytes
Content-Length: 44
Connection: close
Content-Type: text/html

Customized response (I had to edit nginx's source for this):

HTTP/1.1 200 OK
Server: Anonymous
Date: Tue, 23 Apr 2013 03:06:07 GMT
Content-Type: text/html
Connection: close
Set-Cookie: [...]
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache

The former relays exact versions of 6 services which could be exploitable. For bots that scan the 'net passively and attempt canned exploits, reading the headers for which service versions are available would make them far more efficient. This masking won't do much to stop a single, focused attacker (though it won't hurt), but it does help a lot as far as guarding against passive exploitation scans.

Topic: Security tags: php, nginx, apache, http, bots
23
Apr
2013

Some Updates

Written by Matt

Recently switched to a new hosting provider and purged most of the stuff from the database.

Blog now runs under OpenBSD 5.2, and I've increased security a bit. I've detailed all my steps for building the chroot and I'll post them in parts later on, from Packet Filter rules to chroots and daemon configurations. I see very little on OpenBSD on the 'net in general, especially on this, so it would probably be a worthwhile contribution.

I'll add some more functionality to the blog later this week.

Topic: General tags: OpenBSD, meta, hosting
04
Jun
2012

Written From Scratch

Written by Matt

The backend

This system runs OpenBSD, web server is a chrooted, statically compiled nginx installation, using FastCGI for PHP, which is also chrooted and compiled with -fstack-protect, the two communicate through a TCP socket, neither have access to any files, they can't even see the underlying system. The database is PostgreSQL which also communicates with FastCGI PHP through a TCP socket, using the pgsql.so module loaded from within the chroot. PostgreSQL might as well be running on another system, as it is also chrooted, but outside of FastCGI and nginx's chroot. Packet Filter disallows any connections that don't go directly into the web server port, and the kernel is in Security Level 2 on boot, which means any change in the PF rules requires physical access and a reboot, as you'd have to access the system before SSH is started through the VNC which only listens locally on the host address.

Setting this up was something else. There was absolutely nothing online that described how to link together FastCGI PHP and PostgreSQL. OpenBSD is incredibly obscure search-wise when looking for problems. The stuff I did find seemed to have been written by morons as half the directions were completely off, or they'd skip over huge steps. I've got it all running now, in a VM nonetheless. I've made a copy of it for future use, just need to change the credentials for different uses.

The blog system

Beyond that, the entire blog system was written from scratch using PHP 5.3 with suhosin (hardened PHP) and PostgreSQL. I don't really like wordpress, nor trust the security of it. Every packaged blog system either feels cheap or has too many flaws. I also wrote my own BBCode parser, which is what I use to generate the markup for these posts. Much better than just submitting raw HTML as this validates the tag pairs before they are submitted. The output validates under XHTML 1.1 strict. Keeps me from making mistakes, and it's neat in general.

Since I'll probably be posting code on here a lot I also imported Google's JS library prettify, which along with the BBCode parser makes it easy to include properly formatted and syntax highlighted code:

/* Comment Sample */
#include <stdio.h>

int main(int argc, char **argv){
  fprintf(stdout, "Hello, world!\n");
  return 0;
}

It's a very nice library. The only thing that's left to implement in the parser is tables, which will require some nested tag checks, but I just have to generalize it a bit more, it's already pretty flexible anyway.

Topic: General tags: sysadmin, php, nginx, OpenBSD, meta