analyzing tenvis mini319W firmware …

Date Tags hacking

I had for a while a tenvis mini319W network camera. this camera is the usual consumer Chinese product, built on the cheap, bad packaging and sold in low end computer shops. Anyway, it was a cheap and dirty solution for a project of mine and despite everything it does the job ok.

The Tenvis mini319W is actually the same as foscam FI8918W and when I say the same, it means different casing, but same exact identical board. It’s just a re-branding. For some reason there are a lot of clones of this model. To stress even more the fact that they are actually the same product I even downloaded the firmware from foscam and flashed my tenvis without problems. The correct firmware to use is lr_cmos_11_37_2_46.bin that is the zip file you can download from the foscam website. I assume that the foscam firmware is more up-to-date, and for the moment the firmware is working fine. The two relevant links : http://www.tenvis.com/web/firmwaredownload.html  http://www.foscam.com/down3.aspx

Here there is a long list of cameras that are compatible with the same firmware. I spent all this time on this gadget just because the tenvis model is not included in this list …

After a fair amount of time learning how to unpack the firmware, I found this blog that has all the information and tools to turn this camera in an open camera. There is also a project called openipcam that focus on this family of products. You can find there all the information that I managed to figure out in the mean time. I thing this wiki is the main source of information about foscam hw/sw.

This is a walk through of all the things I’ve learned this morning about this camera.

First steps to analyze a proprietary firmware

The easier thing you can do while approaching a binary you don’t know if to look at it. After a few try with hexdump I quickly realized that the format wasn’t anything I had seen before. Since I didn’t have enough info to duckduck, I end up asking on irc for help. Shortly after I stumbled on the excellent binwalk a nice tool to unpack firmaware images.

$binwalk lr_cmos_0_37_2_36.bin 

DECIMAL     HEX         DESCRIPTION
-------------------------------------------------------------------------------------------------------
20          0x14        Zip archive data,  at least v2.0 to extract
712036      0xADD64     romfs filesystem, version 1 size: 1094448 bytes, named rom 4cfcea76.
715668      0xAEB94     BFLT executable  version 4,  code offset: 0x00000040,  data segment starts at: 0x00011170,  bss segment starts at: 0x00013760,  bss segment ends at: 0x000150E8,  stack size: 10240 bytes,  relocation records start at: 0x00013760,  number of reolcation records: 693,  ram gzip
[...]

This tool definitely got me started. Analyzing the output it is easy to guess that the first part is a zipped kernel, the second part, and more interesting, is the romfs image. I wanted to know if it is possible to have a shell console on the device, so I focused immediately on the fs image. To extract and mount the image, you just need to get it from the binary blob with dd and the just mount it.

dd if=lr_cmos_0_37_2_36.bin of=romfs.bin bs=1 skip=712036
mkdir test
mount -o loop romfs.bin test/

so far, so good. This is what we got in the image :

test/bin$file *
camera:         BFLT executable - version 4 ram gzip
dhcpc:          BFLT executable - version 4 ram gzip
dhcpcd:         BFLT executable - version 4 ram gzip
dhcpd:          BFLT executable - version 4 ram gzip
fcc_ce.wlan:    POSIX shell script, ASCII text executable
ifconfig:       BFLT executable - version 4 ram gzip
init:           ASCII text
iwconfig:       BFLT executable - version 4 ram gzip
iwpriv:         BFLT executable - version 4 ram gzip
mypppd:         directory
route:          BFLT executable - version 4 ram gzip
rt73.bin:       data
sh:             BFLT executable - version 4 ram gzip
wetctl:         BFLT executable - version 4 ram
wpa_supplicant: BFLT executable - version 4 ram gzip

So there is definitely no way to access remotely to the camera… However at this point, I started to suspect that there were few too many similarities with the foscam firmware… and once you have to right keyword, you can find almost everything on the internet.

Shortly after this revelation I ended up on this post and a minute later on the source code.

From here on, it was easy : somebody else already did all the hard work. Unpacking the firmware with fostar is a breeze:

$fostar -u lr_cmos_0_37_2_36.bin 
***      REMEMBER! ALWAYS KEEP A BACKUP OF YOUR ORIGINAL FIRMWARE       ***
*** I AM NOT RESPONSIBLE FOR YOU TURNING YOUR CAMERA INTO A PAPERWEIGHT ***
***              USE OF THIS SOFTWARE IS AT YOUR OWN RISK               ***
***                                                                     ***
***           If you don't agree to this, press 'Ctrl+C' now.           ***

Extracting linux.zip (712016 bytes)...
Extracting romfs.img (1094656 bytes)...

$unzip linux.zip 
Archive:  linux.zip
  inflating: linux.bin               

$strings linux.bin | grep -E "Linux version"
Linux version 2.4.20-uc0 (root@maverick-linux) (gcc version 3.0) #1452 

Now I know the architecture and in theory with this info I could recreate the build environment to add more binaries to the rom. Then the Web interface is in a different binary blob. To extract :

$./fostar -x /var/tmp/mini_1.2.2.18.bin /var/tmp/webUI
***      REMEMBER! ALWAYS KEEP A BACKUP OF YOUR ORIGINAL FIRMWARE       ***
*** I AM NOT RESPONSIBLE FOR YOU TURNING YOUR CAMERA INTO A PAPERWEIGHT ***
***              USE OF THIS SOFTWARE IS AT YOUR OWN RISK               ***
***                                                                     ***
***           If you don't agree to this, press 'Ctrl+C' now.           ***

Disassembling firmware file '/var/tmp/mini_1.2.2.18.bin' to '/var/tmp/test2/'
Extracting /admin.htm (1153 bytes)...
Extracting /admin_content.htm (4519 bytes)...
[...]

fostar has also built in the capability to repack the image, giving the possibility to fix, hack and modify the interface (or the rom image, if you want to go thought the hassle of cross compiling your tools.

These cameras can also be connected via a jtag (serial cable) interface. I’ve a small jtag to usb cable and I want to try this next…

These are other few interesting links related to firmware analysis in different contexts that I found and read along the way.

  • http://www.devttys0.com/2011/05/reverse-engineering-firmware-linksys-wag120n/
  • http://en.wikipedia.org/wiki/ZIP
  • http://aluigi.altervista.org/mytoolz.htm
  • http://0entropy.blogspot.fr/2011/08/firmware-reverse-engineering.html
  • https://sites.google.com/site/shihsung/rc32xxx-soc/analyze-firmware
  • http://code.google.com/p/firmware-mod-kit/source/checkout
  • http://www.networkworld.com/community/node/41672

privoxy + adblock-plus

If you use iceweasel / firefox and privoxy , you might want to let privoxy do its job more effectively and to remove all ads from your webpages. In the past I’ve used the adblock firefox extension, but I’ve the gut feeling that letting privoxy handle the ads removal might be more effective.

There is a very nice script here to convert adblock plus rule to privoxy rules. Using it, it is very easy :

$sudo apt-get install --solver aspcud privoxy
[...]
$sudo /var/tmp/privoxy-blocklist.sh
[sudo] password for abate: 
Processing https://easylist-downloads.adblockplus.org/easylistgermany.txt ...

Downloading https://easylist-downloads.adblockplus.org/easylistgermany.txt ...
.. downloading done.

Modifying /etc/privoxy/config ...
... modification done.

Installing new config ...
... installation done


Modifying /etc/privoxy/config ...
... modification done.

Installing new config ...
... installation done

... https://easylist-downloads.adblockplus.org/easylistgermany.txt installed successfully.

Processing http://adblockplus.mozdev.org/easylist/easylist.txt ...

Downloading http://adblockplus.mozdev.org/easylist/easylist.txt ...
.. downloading done.
... http://adblockplus.mozdev.org/easylist/easylist.txt installed successfully.

The only thing left to do it to point your web browser to provoxy and have fun on your new clean internet.

Update

After one day of use, I’ve to say that the adblock extension of firefox is still neede for few website. it seems privoxy is not that good at blocking pop-ups and other more subtle trick to display advertisement . For the moment i’ll use both…


batch instance creation with ganeti

Date Tags ganeti

Now that my infrastructure is up and running I’d love to have a command to create a small cluster of VM for a specific purpose. Up until now to create my VMs I’ve used a simple script calling the following command line.

gnt-instance add -t plain --disk 0:size=10G --disk 1:size=1G -B memory=1024 -o debootstrap+unstable --no-ip-check --no-name-check --iallocator hail cbse4

Then reading the gnt-instance I discovered the batch-create command.

After writing the script I realized I’ve done all this just to satisfy my need of using a json snippet. But I guess my script is not longer and less understandable then before… Ah well. This is a bit from the Dpt of useless optimizations… Anyway there you go.

The gnt-instance man page is a bit low on details about the syntax to use. Looking at the queue directory (/var/lib/ganeti/queue) you can have a look at the json generated by the command line above. From there it’s easy to figure out the various options you can use.

# cat cbse.json 
{
  "cbse1": {
    "template": "plain",
    "iallocator": "hail",
    "os": "debootstrap+unstable",
    "disk_size": ["10G","1G"],
    "backend": {"memory": 1024},
    "ip_check" : false,
    "name_check": false
  }
}

Once you got this bit, we can easily script the creation of multiple instance :

#!/bin/bash

set -x 
name=$1
start=$2
end=$3

tmpfile=`tempfile`

echo "{" > $tmpfile
for i in $(eval echo {$start..$end}); do

cat >> $tmpfile <<EOF
  "$name$i": {
    "template": "plain",
    "iallocator": "hail",
    "os": "debootstrap+unstable",
    "disk_size": ["10G","1G"],
    "backend": {"memory": 1024},
    "ip_check" : false,
    "name_check": false
  }
EOF

if [ $i != $end ]; then
    echo "," >> $tmpfile
fi

done
echo "}" >> $tmpfile

cat $tmpfile
gnt-instance batch-create $tmpfile

Consider that the json snippet above can include a number of other parameters specific to the hypervisor you are using. In my setup, I’ve configured the hypervisor once for all with the following options:

gnt-cluster modify --hypervisor-parameter xen-pvm:root_path='/dev/xvda1'
gnt-cluster modify --hypervisor-parameter xen-pvm:initrd_path='/boot/initrd-2.6-xenU'

apt-get with external solvers : call for testers

Last year we invited David to work with us for a few days to add a generic interface to apt to call external solvers. After a few iterations, this patch finally landed in master and recently (about 3 months ago), in debian unstable.

[ David Kalnischkies ] * [ABI-Break] Implement EDSP in libapt-pkg so that all front-ends which use the internal resolver can now be used also with external ones as the usage is hidden in between the old API * provide two edsp solvers in apt-utils: - ‘dump’ to quickly output a complete scenario and - ‘apt’ to use the internal as an external resolver

Today the new version of apt-cudf was upload in unstable and with it the latest bug fixes that makes it ready for daily use. I’ve used it quite a lot myself to upgrade my machine and it seems working pretty well so far… The most important difference with the old version is the support for multi-arch enabled machines.

This marks an important milestone in our efforts to integrate external solvers, built using different technologies, directly into apt. From a user prospective, this means that (s)he will have the possibility to check if there exists a better (best ?) solution to an installation problem then what proposed by the internal apt solver. Moreover, even if apt-get gives very satisfactory answers, there are occasions where it fails miserably, leaving the user wondering how to unravel the complex web of dependencies to accomplish his task. Available cudf solvers in debian are at the moment : aspcud, mccs and packup.

From an architectural point of view this is accomplished by abstracting the installation problem via a simple textual protocol (EDSP) and using an external tool to do the heavy duty translation. Since all solvers now available in debian are not meant to be debian-specific, using them involve a two step translation. The EDSP protocol specification is for the moment “hidden” in the apt documentation. I hope to find a better place for it soon : it would be cool if other package managers as smart or cupt could add an implementation on EDSP in their code so to automatically benefit of this technology.

To make it happen, Apt first creates an EDSP file that is then handled to apt-cudf that takes care of the translation to cudf and back into EDSP that is then read back by apt. Apt-cudf is the bridge between edsp and the external solvers and takes care of doing the book keeping and to select the right optimization criteria.

Roberto recently wrote a very nice article explaining how to use apt-get with an external solver.

In a nutshell, if you want to try this out you just need to install apt-cudf, one external solver like aspcud from the university of Pasdam and then call apt-get using the —solver option (that is not yet documented #67442 ). For example :

apt-get install -s gnome --solver aspcud

This will install gnome while using the a optimization criteria that tries to minimizing the changes on the system. Various other optimization criteria for all apt-get default actions can be specified in the apt-cudf configuration file /etc/apt-cudf.conf

I hope the new release of apt-cudf make it into testing before the freeze. Time to test !!!


x220 battery info

This situation piss me off a big time. And I don’t understand what’s wrong ! I’ve a 9 cell battery, but I’m not able to squeeze out of it more then 1.30 mins. And this is ridiculous considering that other people report 6 hs and more with an x220 and a 9 cell bat.

Well I’m putting here various info for reference… maybe I’ll find the culprit .

These info are obtained with this script: thinkpad-smapi.sh

    BATTERY 0 INFORMATION
    =====================

    Battery slot:
      Battery present: yes
      Battery state: discharging

    Embedded info:
      FRU P/N: 42T4940
      Barcoding: 1ZJRM1BHCDR
      Serial number: 13521
      OEM Manufacturer: SANYO
      Chemistry: LION
      Manufacture date: 2011-11-17
      Design capacity & voltage: 93240 mWh, 11100 mV

    Battery health:
      First use date: 2012-01-23
      Cycle count: 134
      Last full capacity: 93180 mWh
      Average current / power (past 1 minute): -1079 mA, -12077 mW

    Battery status:
      Remaining capacity: 78420 mWh (84 %)
      Remaining running time: 441 min
      Running current & power: -1054 mA, -11797 mW
      Temperature: 33400 mC
      Voltage: 11193 mV
      Remaining charging time: [not charging]

    Battery charging control:
      Start charging at: [unavailable] %
      Stop charging at: 85 %
      Prevent charging for: 0 min
      Force battery discharge: [unavailable]

Here I print out the output of ibam

$ibam --all
Bios percentage:            81 %
Battery percentage:         80 %
Soft low percentage limit:  4 %
Charge percentage:          81 %
Bios time left:              1:00:00
Battery time left:           6:33:59
Adapted battery time left:   6:33:59
Charge time left:            0:22:48
Adapted charge time left:    0:22:48
Total battery time:          8:11:12
Adapted total battery time:  8:11:12
Total charge time:           2:00:00
Adapted total charge time:   2:00:00
Profile logging enabled.
Current file: /home/abate/.ibam/profile-002-battery
$acpitool -B
  Battery #1     : present
    Remaining capacity : 75460 mWh, 80.98%, 06:09:21
    Design capacity    : 93240 mWh
    Last full capacity : 93180 mWh, 99.94% of design capacity
    Capacity loss      : 0.06435%
    Present rate       : 12258 mW
    Charging state     : Discharging
    Battery type       : Li-ion 
    Model number       : 42T4940
    Serial number      : 13521

And this is what upsets me the most. One moment the battery is at 74% one moment at 6% !!! I really don’t understand …

$ibam --all
Bios percentage:            70 %
Battery percentage:         72 %
Soft low percentage limit:  4 %
Charge percentage:          70 %
Bios time left:              5:37:45
Battery time left:           8:41:28
Adapted battery time left:  39:16:35
Charge time left:            0:36:00
Adapted charge time left:    0:07:58
Total battery time:         12:00:57
Adapted total battery time: 54:18:04
Total charge time:           2:00:00
Adapted total charge time:   0:26:33
Profile logging enabled.
Current file: /home/abate/.ibam/profile-003-battery

$ibam --all
Bios percentage:            6 %
Battery percentage:         2 %
Soft low percentage limit:  4 %
Charge percentage:          6 %
Bios time left:              0:33:45
Battery time left:           0:15:50
Adapted battery time left:   1:11:33
Charge time left:            1:52:48
Adapted charge time left:    0:24:58
Total battery time:         12:00:57
Adapted total battery time: 54:18:05
Total charge time:           2:00:00
Adapted total charge time:   0:26:33
Profile logging enabled.
Current file: /home/abate/.ibam/profile-003-battery

$ibam --all
Bios percentage:            6 %
Battery percentage:         2 %
Soft low percentage limit:  4 %
Charge percentage:          6 %
Bios time left:              0:28:46
Battery time left:           0:15:50
Adapted battery time left:   1:11:33
Charge time left:            1:52:48
Adapted charge time left:    0:24:58
Total battery time:         12:00:57
Adapted total battery time: 54:18:05
Total charge time:           2:00:00
Adapted total charge time:   0:26:33
Profile logging enabled.
Current file: /home/abate/.ibam/profile-003-battery

Update

Interesting post : http://zbz.ca/X220/thinkpad_x220_linux.html

Update 2

I finally managed to get a new battery and BAM ! 8 hrs on a charge. I feel really unlucky with this new laptop …