Hacking the Foscam – Part IV

•May 10, 2010 • 108 Comments

As a result of bricking and subsequently recovering my Foscam, I found a few interesting things out tonight.

If you enter the ‘debug’ mode on the camera, and issue the “boot” command, you can retain access to the console once the camera has booted (this may be possible directly, but it wasn’t apparent).  From here you can access the camera as a linux machine, with standard shell commands, browse directories, etc.

The WebUI firmware is mounted on /home, and it is stored in a separate volume in flash memory.  Despite my bricked camera, and erasing and reloading volumes 6 and 7 with romfs.img and linux.zip images, my hacked WebUI was still present, as was all of my camera settings.  This is particularly interesting since, while the romfs.img may appear to be limited to a physical size of 2MB, it should be possible to load larger binaries onto the camera (like sshd) from the WebUI firmware, and still have the /etc/init (in romfs) run them from /home/sshd, and possibly also specify a local /home/sshd.conf file.  I am also curious if its possible to symlink /home/root to /, thereby allowing access to the entire memory from the WebUI.

What’s more interesting (though lower-level) about all of this WebUI stuff, is that there are other aspects of the flash memory that are utilized, and can possibly be reallocated for different needs.  Ie, now there is a 2MB ROMFS, and a who-know-how-big WebUI, but in theory, from what I was seeing, you could potentially combine these volumes into a single volume that could more easily accommodate larger images.

The Sparkfun USB-Serial UART interface I bought was actually small enough that I was able to push it inside the camera, still wired onto the board, and reassemble the camera.  My son is insisting that I “put it in there all the time”, and make small cutout for the Mini-B USB port, so that I can connect the camera via USB at any time, without having to disassemble the camera.  A very tempting thought.

I noticed after booting the camera, and looking around in the /dev folder, there are 2 video devices.  I need to find a way to dump the data from these devices, selectively across the network, or console.  I find the prospect of two devices interesting.  My gut suspicion is that they are for different image resolutions (since the camera supports 2 modes, 320×240 and 640×480).  One of my long-term hacking goals is to write code that will allow the camera to track motion.  This would be a great start along those lines.

At this point, the ideal next step would be finding source for the ‘camera’ application, but I’d be happy with some decompiled sources.  I guess its about time I start installing the ARM/ucLinux build tools.

Advertisements

Recovering the Foscam

•May 10, 2010 • 7 Comments

Got my USB->Serial UART adapter from SparkFun today. A few minutes wiring up the camera’s port per the recovery guide on GadgetVictims, a whole lot of time spent trying to find good XMODEM tools on linux (cutecom, it’s anything but cute, but it works), and a few minutes poking around with the console, before rebooting, and everything is back to FUN!

Hacking the Foscam FI8908W – Part III

•May 6, 2010 • 5 Comments

Well, some good news. Some bad news.

I was able to put some more code together the last few days, and updated the foscam-util project on SourceForge.net. The changes utilize Lawrence’s findings relating to the system firmware file, and now the utility ‘fostar’ can pack and unpack the system firmware. With a little bit of magic using romfs and ucLinux build tools, its possible to rebuild the firmware file, and thereby possible to do install your own code on the camera.

The bad news. My tools, right now, just work in theory. I bricked my camera tonight after uploading a new firmware. I was able to unpack the original firmware, repack it, and upload it without any problem. But when I modified the romfs image, adding a couple of network binaries (telnetd, ftpd, and ping), as well as an empty /etc/ftpd.conf file, the camera loaded the firmware, didn’t report that it was invalid, but failed to reboot. Earlier I had tried with a firmware that included ssh and sshd binaries. The uploader reported the image was invalid, likely because the entire firmware package exceeded 2MB. I’m not sure what to make of the new situation though. I’m tearing apart my camera and hopefully I can plug into the JTAG and force the old firmware again.

Frustrating, but the only time progress isn’t made is when you’re not working on the problem, right? Hopefully I can find the parts to get my camera back up sooner than later.

Until I find out what’s wrong… be careful using the foscam-util stuff… Just say’n.

Hacking the Foscam – Part II

•April 7, 2010 • 6 Comments

Okay, been busy with the code I posted earlier, as well as some other code goodies, but I’ll post about those another time.

I’ll keep this post short, and to the point.  I’ve finished my extract.c application into a full-fledged utility for extracting, and yes, reassembling the APP_WARE firmware file (also known as the Embedded UI).  With this program you can extract all of the files from the UI firmware file, make changes, add new files, etc. and reassemble them back into a working firmware file, which can then be uploaded onto the camera.

Apparently WordPress doesn’t let me host even small source files, so I decided to go and make a project on SourceForge.net to host it, and other progresses made by myself or others. You can find the source here.

Enjoy!  (I trust, given my earlier post, you can figure out how to compile and run this…)

Hacking the Foscam FI8908W

•March 30, 2010 • 142 Comments

I recently bought a Wireless Pan/Tilt IP Camera in an effort to eventually replace all of the old 2.4GHz wireless cameras around the house, which have ruthlessly stressing my Wireless B/G (also 2.4GHz) Internet.  I found these cameras, and lots of reviews and articles about how good they are, despite their rather small price-tag.  In the world of P/T Cameras, let alone IP Cameras, you’d typically be looking at 2-3x the price for the next best thing.  They aren’t perfect, but updated to the more recent versions of their firmware, they are great cameras that almost equally well in Windows, OS X, or Linux.  Top that with a company that is reportedly very responsive to customer needs, open documentation for protocols and APIs to manipulate the camera, and you’ve got the makings of a great product.  You can read up on any number of reviews via Google, but I’ll link one in particular here.

Based on the title of this post, I suspect you’re not interested in which camera to buy… rather, you’ve already bought one and you’re wondering what else it can do.  I did too.  After a little searching around, I decided to download the latest firmware files and take a look at them under the proverbial microscope of the Hex Editor.

Foscam has two separate firmware files.  One is a ‘core’ firmware, and the other is the ‘WebUI’.  Immediately, it was clear that the ‘core’ firmware was a much more complicated beast; my current, best assumption is that the file is a bonefied, honest-to-God self-extracting binary.  I haven’t taken my camera apart yet to figure out which processor its running, but I suspect I’ll find an ARM processor inside.  What I can tell from scanning the core firmware file is that the underlying OS which the firmware provides is, you guessed it, Linux.  I like these Foscam guys more and more.  I digress.  About this point, I decided to go check out the other file.

The second file, the WebUI firmware, was much easier to tame.  A few simple guesses about what the header information in the file meant, and a couple hours of validating my theories produced the following truth table.

Offset:     Data Type/Size:    Description/Value/Etc:
0x0000      INT32_LE           Size of file
0x0004      Byte[4]            Version Number, each byte a min/minor  value (2.4.8.12)
0x0008      Char[21]           File Description

{ ## Repeats until End-Of-File

+0x000      INT32_LE           Length of File Name
+0x004      Char[...]          File Name
+(Filelen)  Byte               File Type (0 = directory, 1 = file)

{ If 'File Type' == 1 then
+0x001      INT32_LE           Length of File Data
+0x004      Char[...]          File Data
}

}

Based on this data, I was able to whip out the utterly mind-numbing C code below:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

int main(int argc, char **argv) {
  FILE *f = NULL;
  int len = 0, type = 0;
  char src_file[512], dst_file[512], *data = NULL;
  int max_data = 0;

  if ( (f = fopen(argv[1], "rb")) == NULL)
    exit(-1);

  fseek(f, 0, SEEK_END);
  int file_len = ftell(f);
  fseek(f, 0, SEEK_SET);

  fread(&len, 1, 4, f);
  if (len != file_len) {
    fprintf(stderr, "File size doesn't match that reported in the header: %d/%d\n", len, file_len);
    exit(-1);
  }

  fseek(f, 29, SEEK_SET); // seek to first file

  while(!feof(f)) {
    memset(src_file, 0, sizeof(src_file));
    memset(dst_file, 0, sizeof(dst_file));

    fread(&len, 1, 4, f); // read filename length
    fread(src_file,1,len,f); // read filename
    sprintf(dst_file, "%s%s", argv[2], src_file);

    type = 0;
    fread(&type, 1, 1, f); // read entry type
    if (type == 0) {
      if (mkdir(dst_file, 0770) != 0) {
        fprintf(stderr, "Unable to write file: %s", dst_file);
        exit(-1);
      }
    } else if (type == 1) {
      FILE *f2 = fopen(dst_file, "wb");
      if (f2 == NULL) {
        fprintf(stderr, "Unable to write file: %s", dst_file);
        exit(-1);
      }

      fread(&len, 1, 4, f); // read data length
      if (len > max_data) {
        data = realloc(data, len);
        max_data = len;
        if (data == NULL) {
          fprintf(stderr, "Unable to allocate  data necessary to extract file.  Requested: %d bytes.\n", len);
          exit(-1);
        }
      }
      fread(data,1,len,f);

      fprintf(stdout, "Extracting %s (%d bytes)...\n", src_file, len);
      fwrite(data, 1, len, f2);
      fclose(f2);
    }
  }

  fclose(f);
  free(data);
  return 0;
}

You should be able to copy/paste this into and empty .c file (for example, “extract.c”) and run the following command:

gcc extract.c -o extract

Change “extract.c” and “extract” to whatever you want to call it.  Running that command will create an executable file named “extract” (or whatever you changed it to).  This is the executable file that will extract the contents of the firmware file.

When you have that file, you should be able to run the following command:

./extract <path_to_firmwarefile> <path_to_destination>

This should extract all the files in the firmware file into the path specified.  I would encourage you to first create a directory for the extracted firmware files.  If you want to extract to the current directory, you must still enter this parameter as “./”  (but without the quotes) Ie:

./extract ../FI8908W-fw11.14.1.46bis/2.4.8.12.bin ./

Have fun, and happy hacking…  Hopefully soon, I’ll post the code for a second utility to repackage a firmware file.  If someone beats me to it, please feel free to post, or ask any questions about the format of the file.  At the least, being able to see how the web/javascript interact with the underlying OS should provide options for making a back door.

Tango, GDC, and DSSS follow-up

•December 14, 2009 • Leave a Comment

I’ve had some recents setbacks, and some advances in my struggle for ‘D’.

First,

cat 'profile=gdc-posix-tango' > /usr/etc/rebuild/default

Next make the following symlinks:

ln -s /usr/etc/dsss /etc/dsss
ln -s /usr/etc/rebuild /etc/rebuild

Finally, rebuild tango via dsss:

sudo dsss net install tango

This should update tango to 0.99.8. For fun, from here, you should install derelict as well:

sudo dsss net install derelict

Enjoy

Tango, GDC, and Ubuntu 9.10 (Karmic) on x64

•December 7, 2009 • Leave a Comment

After months of dicking around with D, on various platforms, I finally got this working as easily as possible.

1) Install gdc-4.2 and libphobos-4.2 from the Ubuntu Repos.

sudo apt-get install gdc-4.2 libphobos-4.2

Download DSSS .deb and install:

http://download.palos.ro/Debian%20D%20Packages/dsss_0.78-1_amd64.deb

2) Write your D program:

import tango.io.Console;
void main() {
	Cout("Hello World!");
}

3) Compile your program:

gdc -fversion=Posix HelloWorld.d -lgtango -o HelloWorld

Hope it works as easily for you, as it did for me. You’re mileage may vary.