Playing with the Patriot Gauntlet Node (Part 1)

I recently picked up a Patriot Gauntlet Node just to take a look at it. Playing with the device, it seemed to be a pretty straightforward wireless SoC with a hard drive interface. Many, if not most, of these embedded SoCs use Linux as their operating system, so I decided to go a bit further and see what was going on.

I headed over to the Patriot website and downloaded the firmware for the Gauntlet Node, unzipped the file, and ran binwalk against it. (Binwalk is an awesome tool that essentially runs 'file' with a special magic file against every possible byte offset to find the parts of a firmware image.)

0         	0x0       	uImage header, header size: 64 bytes, header CRC: 0xE7CCD2D7, created: Mon Nov 19 21:53:24 2012, image size: 5646212 bytes, Data Address: 0x80000000, Entry Point: 0x803DC000, data CRC: 0xCC23D5F0, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: Linux Kernel Image
64        	0x40      	LZMA compressed data, properties: 0x5D, dictionary size: 65536 bytes, uncompressed size: 8244219 bytes
138771    	0x21E13   	JFFS2 filesystem (old) data big endian, JFFS node length: 411382
1909438   	0x1D22BE  	Broadcom header, number of sections: 25170859,
5051328   	0x4D13C0  	JFFS2 filesystem (old) data big endian, JFFS node length: 391617

This confirmed my suspicions -- a Linux OS resides on the device. (And no, before you look, there's no GPL sources to be found on the Patriot site...) So, let's see what's inside. Since the uImage header identified the compression as lzma, and the section at 0x40 is LZMA compressed (and first), it seems likely to be a kernel image. A quick dd if=PA21_1.2.4.5.bin of=kernel.lzma bs=64 skip=1;lzma -d kernel.lzma left me with a kernel image, confirmed by running strings on the file. The kernel by itself isn't very interesting -- userspace can tell us a lot more about how the device works. Let's look for a filesystem -- binwalk has identified two JFFS2 (common on embedded devices) filesystems. Unfortunately, it turns out that neither of those is actually a JFFS2 filesystem (binwalk does get the occasional false positive). So let's look at the kernel some more, maybe we can find some clues. Let's look for the kernel command line:

$ strings img. | grep 'root='
Please append a correct "root=" boot option
console=ttyS1,57600n8 root=/dev/ram0
console=ttyS1,57600n8 root=/dev/ram0

/dev/ram0 suggests we're booting from an initrd of some sort, maybe in the same lzma image? Let's try binwalk on the kernel image itself... That nets us a lot of noise, dozens of lzma and JFFS2 signatures, mostly obvious false positives (massive dictionary sizes, uncompressed sizes, etc.). But the very last image found, an lzma image, has a dictionary size of exactly 1048576 (1MB), so seems like a likely candidate. Another dd and lzma later, and I've got a file that 'file' identifies as a cpio archive (standard for an initrd). cpio -idv --no-absolute-filenames gets me a nice directory structure of a linux root filesystem. Finally something to work with!

I poked around the filesystem a little, and I'll have more on that later, but the most interesting thing I've found so far is a file named killprocess.cgi in /etc_ro/web/cgi-bin. It turns out that given the right argument, this triggers a busybox telnetd. That's right, it just takes a web request to get telnet! (using the default IP) starts telnetd right up. admin/admin logs you right in.

Social Engineering: The Art of Human Hacking

I just got done reading Christopher Hadnagy's Social Engineering: The Art of Human Hacking. If you are interested in the social aspects of information security, this provides an in-depth view of the actual techniques and science behind social engineering. While books like Kevin Mitnick's The Art of Deception and The Art of Intrusion tell amusing and noteworthy stories of social engineering hacking, Hadnagy's book tells you why and how it works. Hadnagy's exposure all reveals the most important lesson -- how to defend against the attacks.

Hadnagy takes you through all the steps of a social engineering exploit -- from information gathering to the exploit. He discusses techniques like elicitation (extracting information from a target), influence (getting them to do what you want), pretexting (developing the back story that makes the attack believable), micro-expressions (control the subtle muscle movements that can give you away), and neuro-linguistic programming (the exact way you say things can make a big difference).

It doesn't matter if you're blue team, trying to protect your valuable assets against attack, or red team, trying to get in there, but it's critical you know how to exploit the human element of security. After all, the devil you know is better than the devil you don't.

The segmentation fault occurred where?!?

I recently ran into a C++ problem where a segfault was occurring in code in a stable library that hadn't been changed in a while. For a while, I couldn't figure out what would have broken in that library, and the call site looked perfectly fine. Before I give away the answer, let's take a quick quiz. What does the following code output? (And yes, this is somewhat compiler dependent, so let's pretend we're talking about how g++ works.)

#include <cstdio>
class Foo {
    char *name;
    void whatami() {
      printf("I am a Foo.\n");
    void whoami() {
      printf("I am %s.\n", name);
int main(int argc, char **argv){
  Foo *f = NULL;

My first instinct was to say "Segmentation Fault" and nothing else, because line 17 is going to dereference a NULL pointer. It turns out, of course, it's not that simple -- it'll actually print the "I am a Foo" before segfaulting. Clearly, then, the segfault must be on line 18, right? Wrong. Line 11 is where we give up, as f is not dereferenced until then. To see why this is, let's think about the equivalent C code:

#include <stdio.h>
typedef struct {
  char *name;
} Foo;
void Foo_whatami(Foo *self) {
  printf("I am a Foo.\n");
void Foo_whoami(Foo *self) {
  printf("I am %s.\n", self->name);
int main(int argc, char **argv) {
  Foo *f = NULL;

As we can see here, the pointer is actually unused by the method "Foo_whatami". But wait, you say, don't we need the address of Foo to resolve the location of the method? No, as whatami and whoami are not virtual methods! Their addresses can be determined by the compiler at compile time. Virtual methods, on the other hand, need a pointer from within the data area of the object to the vtable to resolve addresses. Change whatami to a virtual method, and you'll crash much more efficiently.

So remember, even if the code looks like you're dereferencing the pointer, it may well not be dereferenced until much later!

MITM on KVM Guests

I run a KVM virtualization system as part of my test lab.  I often want to redirect traffic to an intermediate application (such as sslsniff) on the host.  Supposing I have a guest on interface vnet7, bridged to br10, with the host running on the following ebtables & iptables magic gets the job done:

ebtables -t broute -A BROUTING -p IPv4 -i vnet7 --ip-proto tcp --ip-dport 443 -j redirect --redirect-target DROP
iptables -t nat -A PREROUTING -i vnet7 -p tcp --dport 443 -j DNAT --to-destination

Note that you can't use -j REDIRECT, as that's (roughly) equivalent to DNAT to the IP of the incoming interface, but bridged virtual network interfaces (vnet7) have no IP address.

2 Weeks at Google

Two weeks at Google have been... amazing.  There's a lot that I can't talk about, but I can feel comfortable in confirming some of the things you hear about Google:

  • The people are insanely smart.
  • The scale blows your mind as a Noogler (new Googler).
  • The food is great.
  • It has culture.

I'm a "Site Reliability Engineer" which is a job title that may not exist anywhere else.  It's basically production-oriented operational engineering: keeping production systems running and making them run better.

Ann and I have found a new place, so we'll be moving there from the corporate housing next week.  It'll be nice to get our stuff back and get settled in.

(All opinions expressed here are mine and not my employers.  I will not comment on or discuss Google policy, unreleased products, or other proprietary information.)