1: root@system:~/bin/binwalk-0.3.7/src# binwalk AXIS_M1031-W.bin
2:
3: DECIMAL HEX DESCRIPTION
4: -------------------------------------------------------------------------------------------------------
5: 12165 0x2F85 LZMA compressed data, properties: 0x02, dictionary size: 8388608 bytes, uncompressed size: 1073741824 bytes
6: 12189 0x2F9D LZMA compressed data, properties: 0x02, dictionary size: 8388608 bytes, uncompressed size: 1073741824 bytes
7: 12213 0x2FB5 LZMA compressed data, properties: 0x02, dictionary size: 8388608 bytes, uncompressed size: 1073741824 bytes
8: 68693 0x10C55 LZMA compressed data, properties: 0x02, dictionary size: 8388608 bytes, uncompressed size: 1073741824 bytes
9: 68717 0x10C6D LZMA compressed data, properties: 0x02, dictionary size: 8388608 bytes, uncompressed size: 1073741824 bytes
10: 68741 0x10C85 LZMA compressed data, properties: 0x02, dictionary size: 8388608 bytes, uncompressed size: 1073741824 bytes
11: 82110 0x140BE LZMA compressed data, properties: 0x00, dictionary size: 8388608 bytes, uncompressed size: 192 bytes
12: 95704 0x175D8 gzip compressed data, from Unix, last modified: Mon Oct 25 14:03:18 2010, max compression
13: 2899809 0x2C3F61 LZMA compressed data, properties: 0xE0, dictionary size: 8912896 bytes, uncompressed size: 8912896 bytes
14: 5390381 0x52402D LZMA compressed data, properties: 0xAF, dictionary size: 9371648 bytes, uncompressed size: 9371648 bytes
15: 7143469 0x6D002D LZMA compressed data, properties: 0x9E, dictionary size: 28246016 bytes, uncompressed size: 28246016 bytes
16: 7421997 0x71402D LZMA compressed data, properties: 0xBD, dictionary size: 48693248 bytes, uncompressed size: 48693248 bytes
17: 7782445 0x76C02D LZMA compressed data, properties: 0xAF, dictionary size: 2555904 bytes, uncompressed size: 2555904 bytes
18: 8212417 0x7D4FC1 LZMA compressed data, properties: 0x80, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
19: 8216581 0x7D6005 LZMA compressed data, properties: 0x90, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
20: 8220745 0x7D7049 LZMA compressed data, properties: 0xA0, dictionary size: 262144000 bytes, uncompressed size: 262144000 bytes
21: 8224813 0x7D802D LZMA compressed data, properties: 0xAF, dictionary size: 6291456 bytes, uncompressed size: 6291456 bytes
22: 8224977 0x7D80D1 LZMA compressed data, properties: 0xB0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
23: 8229141 0x7D9115 LZMA compressed data, properties: 0xC0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
24: 8233305 0x7DA159 LZMA compressed data, properties: 0xD0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
25: 8237469 0x7DB19D LZMA compressed data, properties: 0xE0, dictionary size: 239861760 bytes, uncompressed size: 239861760 bytes
26: 9443925 0x901A55 Zip archive data, at least v2.0 to extract
27: 9444533 0x901CB5 Zip archive data, at least v2.0 to extract
28: 9449893 0x9031A5 Zip archive data, at least v2.0 to extract
29: 9450294 0x903336 Zip archive data, at least v2.0 to extract
30: 9470202 0x9080FA Zip archive data, at least v2.0 to extract
31: 9471043 0x908443 Zip archive data, at least v2.0 to extract
32: 9484593 0x90B931 Zip archive data, at least v2.0 to extract
33: 9485547 0x90BCEB Zip archive data, at least v2.0 to extract
34: 9486419 0x90C053 Zip archive data, at least v2.0 to extract
35: 9497953 0x90ED61 Zip archive data, at least v2.0 to extract
36: 9499916 0x90F50C Zip archive data, at least v2.0 to extract
37: 11812909 0xB4402D LZMA compressed data, properties: 0x8F, dictionary size: 9764864 bytes, uncompressed size: 9764864 bytes
38: 12894253 0xC4C02D LZMA compressed data, properties: 0x8F, dictionary size: 4063232 bytes, uncompressed size: 4063232 bytes
39: 13754341 0xD1DFE5 LZMA compressed data, properties: 0x80, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
40: 13758505 0xD1F029 LZMA compressed data, properties: 0x90, dictionary size: 264241152 bytes, uncompressed size: 264241152 bytes
41: 13762605 0xD2002D LZMA compressed data, properties: 0x9F, dictionary size: 4194304 bytes, uncompressed size: 4194304 bytes
42: 13762737 0xD200B1 LZMA compressed data, properties: 0xA0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
43: 13766901 0xD210F5 LZMA compressed data, properties: 0xB0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
44: 13771065 0xD22139 LZMA compressed data, properties: 0xC0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
45: 13775229 0xD2317D LZMA compressed data, properties: 0xD0, dictionary size: 241958912 bytes, uncompressed size: 241958912 bytes
46: 13778989 0xD2402D LZMA compressed data, properties: 0xDE, dictionary size: 26476544 bytes, uncompressed size: 26476544 bytes
47: 13779461 0xD24205 LZMA compressed data, properties: 0xE0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
48: 13986717 0xD56B9D LZMA compressed data, properties: 0x80, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
49: 13990881 0xD57BE1 LZMA compressed data, properties: 0x90, dictionary size: 67633152 bytes, uncompressed size: 67633152 bytes
50: 13991981 0xD5802D LZMA compressed data, properties: 0x94, dictionary size: 200802304 bytes, uncompressed size: 200802304 bytes
51: 13995113 0xD58C69 LZMA compressed data, properties: 0xA0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
52: 13999277 0xD59CAD LZMA compressed data, properties: 0xB0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
53: 14003441 0xD5ACF1 LZMA compressed data, properties: 0xC0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
54: 14007605 0xD5BD35 LZMA compressed data, properties: 0xD0, dictionary size: 45350912 bytes, uncompressed size: 45350912 bytes
55: 14008365 0xD5C02D LZMA compressed data, properties: 0xD2, dictionary size: 223084544 bytes, uncompressed size: 223084544 bytes
56: 14011837 0xD5CDBD LZMA compressed data, properties: 0xE0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
57: 14794797 0xE1C02D LZMA compressed data, properties: 0x80, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
58: 14798961 0xE1D071 LZMA compressed data, properties: 0x90, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
59: 14803125 0xE1E0B5 LZMA compressed data, properties: 0xA0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
60: 14807289 0xE1F0F9 LZMA compressed data, properties: 0xB0, dictionary size: 250609664 bytes, uncompressed size: 250609664 bytes
61: 14811181 0xE2002D LZMA compressed data, properties: 0xBE, dictionary size: 17825792 bytes, uncompressed size: 17825792 bytes
62: 14811521 0xE20181 LZMA compressed data, properties: 0xC0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
63: 14815685 0xE211C5 LZMA compressed data, properties: 0xD0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
64: 14819849 0xE22209 LZMA compressed data, properties: 0xE0, dictionary size: 268435456 bytes, uncompressed size: 268435456 bytes
Interesting, so many lzma headers with huge/inaccurate uncompressed sizes and same dictionary size. Something is not correct here and let’s have a closer look on it,
1: root@system:~/axis# dd if=AXIS_M1031-W.bin bs=1 skip=12165 count=32 2>/dev/null | hexdump -C
2: 00000000 02 00 00 80 00 00 00 00 40 00 00 00 00 00 00 52 |........@......R|
3: 00000010 28 00 10 39 00 00 00 00 02 00 00 80 00 00 00 00 |(..9............|
4: 00000020
5: root@system:~/axis# dd if=AXIS_M1031-W.bin bs=1 skip=12189 count=32 2>/dev/null | hexdump -C
6: 00000000 02 00 00 80 00 00 00 00 40 00 00 00 00 00 00 69 |........@......i|
7: 00000010 28 00 10 79 00 00 00 00 02 00 00 80 00 00 00 00 |(..y............|
8: 00000020
9: root@system:~/axis# dd if=AXIS_M1031-W.bin bs=1 skip=12213 count=32 2>/dev/null | hexdump -C
10: 00000000 02 00 00 80 00 00 00 00 40 00 00 00 00 00 00 80 |........@.......|
11: 00000010 28 00 10 72 00 00 00 00 02 00 00 80 00 00 00 00 |(..r............|
12: 00000020
13: root@system:~/axis# dd if=AXIS_M1031-W.bin bs=1 skip=68693 count=32 2>/dev/null | hexdump -C
14: 00000000 02 00 00 80 00 00 00 00 40 00 00 00 00 00 00 94 |........@.......|
15: 00000010 c0 00 c0 39 00 00 00 00 02 00 00 80 00 00 00 00 |...9............|
16: 00000020
It seems that binwalk is matching the first bytes at each section to lzma compression magic numbers incorrectly. From this point on and after doing some more tests with the rest of the lzma suggested entries we will assume that binwalk’s analysis is inaccurate on that and we will not take it in consideration.
Removing the lzma entries our table will look more like this:
1:
2: DECIMAL HEX DESCRIPTION
3: -------------------------------------------------------------------------------------------------------
4: 95704 0x175D8 gzip compressed data, from Unix, last modified: Mon Oct 25 14:03:18 2010, max compression
5:
6: 9443925 0x901A55 Zip archive data, at least v2.0 to extract
7: 9444533 0x901CB5 Zip archive data, at least v2.0 to extract
8: 9449893 0x9031A5 Zip archive data, at least v2.0 to extract
9: 9450294 0x903336 Zip archive data, at least v2.0 to extract
10: 9470202 0x9080FA Zip archive data, at least v2.0 to extract
11: 9471043 0x908443 Zip archive data, at least v2.0 to extract
12: 9484593 0x90B931 Zip archive data, at least v2.0 to extract
13: 9485547 0x90BCEB Zip archive data, at least v2.0 to extract
14: 9486419 0x90C053 Zip archive data, at least v2.0 to extract
15: 9497953 0x90ED61 Zip archive data, at least v2.0 to extract
16: 9499916 0x90F50C Zip archive data, at least v2.0 to extract
Starting with the gzip section, we can verify the signature,
1: dd if=AXIS_M1031-W.bin bs=1 skip=95704 2>/dev/null | file -
2: /dev/stdin: gzip compressed data, from Unix, last modified: Mon Oct 25 14:03:18 2010, max compression
A point of start for the moment there, let’s extract the header of the file first and we will proceed later with the gzip section.
1: root@system:~/axis/analysis# dd if=AXIS_M1031-W.bin bs=1 count=95704 of=header_before.gzip.section
2: 95704+0 records in
3: 95704+0 records out
4: 95704 bytes (96 kB) copied, 1.86194 s, 51.4 kB/s
5: root@system:~/axis/analysis# file header_before.gzip.section
6: header_before.gzip.section: data
7: root@system:~/axis/analysis# strings header_before.gzip.section > header.str
8: root@system:~/axis/analysis# less header.str
9: <...>
10:
11: NAND 2GiB 3,3V 8-bit
12: NAND 2GiB 1,8V 16-bit
13: NAND 2GiB 3,3V 16-bit
14: AND 128MiB 3,3V 8-bit
15: gUp
16: 9j"\
17: 9i2\
18: 40K%
19: -- System halted
20: ran out of input data
21: Malloc error
22: Out of memory
23: incomplete literal tree
24: incomplete distance tree
25: bad gzip magic numbers
26: internal error, invalid method
27: Input is encrypted
28: Multi part input
29: Input has invalid flags
30: invalid compressed format (err=1)
31: invalid compressed format (err=2)
32: out of memory
33: invalid compressed format (other)
34: crc error
35: length error
36: Uncompressing Linux...
37: done, booting the kernel.
We can see that this is the Linux bootloader running in the camera startup process. Few days ago I submitted as bug at the binwalk developers the identification of binary format files. Binwalk was not able to identify binary files properly giving false results, at the time of this writing binwalk has been updated adding a new feature, binary file identification. The results of program now verify what we found earlier,
1: root@system:~/axis/analysis# binwalk -A bootloader | head
2:
3: DECIMAL HEX DESCRIPTION
4: -------------------------------------------------------------------------------------------------------
5: 8512 0x2140 ARM function prologue
6: 8828 0x227C ARM function epilogue
7: 9328 0x2470 ARM function prologue
8: 9336 0x2478 ARM function epilogue
9: 9380 0x24A4 ARM function prologue
10: 9392 0x24B0 ARM function epilogue
11: 17816 0x4598 ARM function prologue
Proceeding with the section identified as gzip we extract the data until next identified signature.
1: root@system:~/axis/analysis# dd if=AXIS_M1031-W.bin bs=1 skip=95704 count=9348221 of=gzip.section.gz
2: 9348221+0 records in
3: 9348221+0 records out
4: 9348221 bytes (9.3 MB) copied, 207.353 s, 45.1 kB/s
As mentioned before there is no clear mark on where is the end of the gzip section, a lot of false positives, so I go ahead and extract the section until the Zip first identified area. gunzip here was able to extract the contents with a twist,
1: root@system:~/axis/analysis# ls -Fal gzip.section.gz
2: -rw-r--r-- 1 root root 9348221 2011-08-21 09:01 gzip.section.gz
3: root@system:~/axis/analysis# gunzip gzip.section.gz
4: gzip: gzip.section.gz: decompression OK, trailing garbage ignored
5: root@system:~/axis/analysis# ls -Fal gzip.section
6: -rw-r--r-- 1 root root 2695168 2011-08-20 22:45 gzip.section
From the initial file that was almost 9.3 Mb the extracted contents are nearly 2.7 Mb, something is not correct here either there is a lot of padding in the file or there is something more inside the contents. At this phase I was stuck, I tried different tools with no apparent results, tools that were used are deezee from matasano’s black bag ( www.matasano.com ) , signsrch from Luigi Auriemma and again binwalk.
1: root@system:~/axis/analysis# ../../src/signsrch gzip.section.gz
2:
3: Signsrch 0.1.6a
4: by Luigi Auriemma
5: e-mail: aluigi@autistici.org
6: web: aluigi.org
7: optimized search function from Andrew http://www.team5150.com/~andrew/
8: disassembler engine from Oleh Yuschuk
9:
10: - open file "gzip.section.gz"
11: - 9348221 bytes allocated
12: - load signatures
13: - open file ../../src/signsrch.sig
14: - 1774060 bytes allocated for the signatures
15: - 2278 signatures in the database
16: - start signatures scanning:
17:
18: offset num description [bits.endian.size]
19: --------------------------------------------
20: 0029cf30 31 Adler CRC32 (0x191b3141) [32.le.1024]
21: 0029d330 33 Adler CRC32 (0x01c26a37) [32.le.1024]
22: 0029d730 35 Adler CRC32 (0xb8bc6765) [32.le.1024]
23:
24: - 3 signatures found in the file
I found a solution after a while looking at the actual hex code on the file. Using hexdump to convert the file I notice a large section inside filled with a sort of padding,
1: 00146100 c8 1a 85 c0 c0 16 85 c0 d0 32 70 c0 a0 16 85 c0 |.........2p.....|
2: 00146110 bc 16 85 c0 56 32 70 c0 a4 16 85 c0 ac 16 85 c0 |....V2p.........|
3: 00146120 9c 16 85 c0 58 00 70 c0 88 96 84 c0 90 96 84 c0 |....X.p.........|
4: 00146130 94 16 85 c0 a8 16 85 c0 00 00 00 00 00 00 00 00 |................|
5: 00146140 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff |................|
6: 00146150 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
7: *
8: 001fca20 ff ff ff ff ff ff ff ff 85 19 01 e0 30 00 00 00 |............0...|
9: 001fca30 78 be 3e fa 01 00 00 00 00 00 00 00 02 00 00 00 |x.>.............|
10: 001fca40 23 6d c5 4c 08 08 00 00 51 ae 45 03 63 c1 56 6c |#m.L....Q.E.c.Vl|
11: 001fca50 2e 64 65 76 2e 74 61 72 85 19 02 e0 96 01 00 00 |.dev.tar........|
12: 001fca60 38 e0 68 15 02 00 00 00 01 00 00 00 a4 81 00 00 |8.h.............|
13: 001fca70 00 00 00 00 00 f0 00 00 23 6d c5 4c 23 6d c5 4c |........#m.L#m.L|
Apparently there is a section between locations 001fca20 and 00146150 filed with ff ff ff ff. Few bytes below address 001fca20, there is visible a dev.tar ( possible filesystem data ? ) entry. I cut through the file to verify that gzip compression data are still valid after chopping the tail of that contents.
1: root@system:~/axis/analysis# dd if=gzip.section.gz bs=1 count=$((0x00146150)) of=until_padding.gz
2: 1335632+0 records in
3: 1335632+0 records out
4: 1335632 bytes (1.3 MB) copied, 36.0775 s, 37.0 kB/s
5: root@system:~/axis/analysis# gunzip until_padding.gz
6: gzip: until_padding.gz: decompression OK, trailing garbage ignored
7: root@system:~/axis/analysis# l until_padding
8: -rw-r--r-- 1 root root 2695168 2011-08-21 09:21 until_padding
Extracted area is giving a file around 1.3 MB of compressed data that expanded is still giving us the same results, trying a bit more and cutting bytes from the end I was able later even to correct the warning from gunzip about trailing garbage.
Further more, strings shows some interesting data on the file like the existence of a jffs2 filesystem and more details to ensure that this is the kernel that we are looking at
1: root@system:~/axis/analysis# strings until_padding | more
2: -romE=
3: (hsqs
4: 1fs-
5: UUUU
6: VUUU
7: root=/dev/mtdblock3 mem=64M init=/linuxrc rootfstype=jffs2 i2c-argus.sda=15 i2c-argus.scl=14 panic=1
8: l??b
9: uncached
10: buffered
11: writethrough
12: <snip>
1: root@system:~/axis/analysis# strings until_padding | grep kernel
2: No init found. Try passing init= option to kernel.
3: Booting kernel
4: <4>start_kernel(): bug: interrupts were enabled *very* early, fixing it
5: <2>start_kernel(): bug: interrupts were enabled early
6: arch/arm/kernel/process.c
7: <2>kernel BUG at %s:%d!
8: Division by zero in kernel.
9: <2>%s: bad page in kernel page table
10: <1>Unable to handle kernel %s at virtual address %08lx
11: kernel/sched_rt.c
12: kernel/fork.c
13: <4>Disabling lock debugging due to kernel taint
14: kernel/exit.c
15: kernel/softirq.c
16: kernel/resource.c
17: kernel/sysctl.c
18: kernel/timer.c
19: kernel/workqueue.c
20: kernel/rcupdate.c
21: kernel/params.c
22: kernel/hrtimer.c
23: kernel/srcu.c
24: kernel/async.c
25: kernel/futex.c
26: kernel/rtmutex.c
27: kernel/up.c
28: <4>Please see the file Documentation/feature-removal-schedule.txt in the kernel source tree for more details.
29: <4>%s: module license '%s' taints kernel.
30: kernel/irq/manage.c
31: kernel/irq/chip.c
32: kernel/irq/devres.c
33: <4>You cannot use older JFFS2 filesystems with newer kernels
34: <3>%s %s: uevent: unsupported action-string; this will be ignored in a future kernel version
35: kernel_max
36: please mail a stack trace to linux-scsi@vger.kernel.org
37: <3>%s %s: Could not create connection due to crc32c loading error. Make sure the crc32c module is built as a module or into the kernel
38: kernel_thread
39: kernel_execve
40: pgprot_kernel
41: kernel_power_off
42: kernel_halt
43: kernel_restart
44: kernel_kobj
45: prepare_kernel_cred
46: current_kernel_time
47: probe_kernel_write
48: probe_kernel_read
49: kernel_read
50: copy_strings_kernel
51: kernel_sock_shutdown
52: kernel_sock_ioctl
53: kernel_sendpage
54: kernel_setsockopt
55: kernel_getsockopt
56: kernel_getpeername
and
1: root@system:~/axis/analysis# strings until_padding | grep -i linux
2: root=/dev/mtdblock3 mem=64M init=/linuxrc rootfstype=jffs2 i2c-argus.sda=15 i2c-argus.scl=14 panic=1
3: Linux version 2.6.31 (madhavi@eater-1) (gcc version 4.3.1 20080521 (prerelease) [gcc-4_3-branch revision 135713] (GCC 4.3.1 Axis release R11/1.1) ) #1 Mon Oct 25 13:03:16 CEST 2010
4: TERM=linux
5: include/linux/security.h
6: Linux
7: include/linux/gfp.h
8: please mail a stack trace to linux-scsi@vger.kernel.org
9: include/linux/skbuff.h
10: Linux
Getting the data after the kernel entry point near address 001fca20, and adding 8 bytes for cleanup
1: 001fca20 ff ff ff ff ff ff ff ff 85 19 01 e0 30 00 00 00 |............0...|2: 001fca30 78 be 3e fa 01 00 00 00 00 00 00 00 02 00 00 00 |x.>.............|3: 001fca40 23 6d c5 4c 08 08 00 00 51 ae 45 03 63 c1 56 6c |#m.L....Q.E.c.Vl|
using dd again ,
1: root@system:~/axis/analysis# dd if=gzip.section.gz bs=1 skip=$((0x001fca28)) of=after_kernel
2: 7264853+0 records in
3: 7264853+0 records out
4: 7264853 bytes (7.3 MB) copied, 157.416 s, 46.2 kB/s
1: root@system:~/axis/analysis# file after_kernel
2: after_kernel: Linux jffs2 filesystem data little endian
looking for the common busybox application usually found in embedded installations,
1: root@system:~/axis/analysis# strings jffs2.fs | grep busybox
2: busybox
3: busybox
4: <snip>
And there is the start of the jffs2 filesystem. Final part, let’s add the zip sections and mount the filesystem. In this part I could had done an easier approach but in my initial assumption the zip sections were unknown sections since I had no knowledge of the jffs2 filesystem’s location.
A bit more slice and dice,
1: root@system:~/axis/analysis# dd if=AXIS_M1031-W.bin bs=1 skip=9443925 of=Zip.section.parts
2: 8463811+0 records in
3: 8463811+0 records out
4: 8463811 bytes (8.5 MB) copied, 158.606 s, 53.4 kB/s
5: root@system:~/axis/analysis# cat jffs2.fs Zip.section.parts > jffs_and_tail
Final cleanup of the jffs filesystem,
1: root@system:~/axis/analysis# hexdump -C jffs_and_tail | tail
2: 00dee3d0 e9 ba 6c 54 77 73 5f 75 73 65 72 73 85 19 02 e0 |..lTws_users....|
3: 00dee3e0 44 00 00 00 1d fb f7 98 b6 02 00 00 01 00 00 00 |D...............|
4: 00dee3f0 a0 81 00 00 89 00 89 00 00 00 00 00 b2 bf 66 4c |..............fL|
5: 00dee400 b2 bf 66 4c b2 bf 66 4c 00 00 00 00 00 00 00 00 |..fL..fL........|
6: 00dee410 00 00 00 00 00 00 00 00 00 00 00 00 f8 bc df cb |................|
7: 00dee420 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
8: *
9: 00f00000 31 37 30 20 20 20 20 20 20 20 20 20 20 20 32 36 |170 26|
10: 00f00010 39 32 34 30 30 39 34 31 |92400941|
11: 00f00018
12: root@system:~/axis/analysis# dd if=jffs_and_tail bs=1 count=$((00dee420)) of=jffs_clear
In order to mount the jffs2 we have two ways to do that, either
- Have a block device emulate a Memory Technology Device (MTD) via block2mtd. or
- Have kernel memory emulate a MTD via mtdram.
I choose the second way
1: root@system:~/axis/analysis# mknod /tmp/mtdblock1 b 31 0
2: root@system:~/axis/analysis# modprobe mtdblock
3: root@system:~/axis/analysis# modprobe mtdram total_size=196608 erase_size=256
4: root@system:~/axis/analysis# dd if=jffs_clear of=/tmp/mtdblock1
5: root@system:~/axis/analysis# mount -t jffs2 /tmp/mtdblock1 /media/jffs2
6: root@system:~/axis/analysis# cd /media/jffs2/
7: root@system:/media/jffs2# ls -Fal
8: total 97
9: drwxr-xr-x 15 root root 0 1970-01-01 02:00 ./
10: drwxr-xr-x 5 root root 4096 2011-08-21 14:52 ../
11: drwxr-xr-x 2 root root 0 2010-10-25 14:43 bin/
12: drwxr-xr-x 5 root root 0 2010-10-25 14:42 dev/
13: -rw-r--r-- 1 root root 61440 2010-10-25 14:42 .dev.tar
14: lrwxrwxrwx 1 root root 13 2010-10-25 14:42 etc -> mnt/flash/etc
15: drwxr-xr-x 7 root root 0 2010-10-25 14:43 lib/
16: drwxr-xr-x 3 root root 0 2010-10-25 14:43 libs/
17: -rwxr-xr-x 1 root root 1770 2010-10-25 14:30 linuxrc*
18: drwxr-xr-x 8 root root 0 2010-10-25 14:43 mnt/
19: drwxr-xr-x 2 root root 0 2010-10-25 14:42 proc/
20: drwx------ 2 root root 0 2010-10-25 14:42 root/
21: drwxr-xr-x 2 root root 0 2006-03-17 13:04 sbin/
22: drwxr-xr-x 2 root root 0 2010-10-25 14:42 share/
23: drwxr-xr-x 2 root root 0 2010-10-25 14:42 sys/
24: lrwxrwxrwx 1 root root 7 2010-10-25 14:42 tmp -> var/tmp
25: drwxr-xr-x 11 root root 0 2010-10-25 14:42 usr/
26: drwxr-xr-x 2 root root 0 2010-10-25 14:42 var/
27: -rw-r--r-- 1 root root 30720 2010-10-25 14:42 .var.tar
28: root@system:/media/jffs2#
Until next time !
Html files and cgi content for further analysis, axis
Hi Nicolas,
ReplyDeleteI hope you still posting about reverse engineering.
I'm also reverse engineering an IP Camera (VStarcam H6837WI): http://acassis.wordpress.com/category/ipcam/
At this moment I already discover how to compile and flash a linux kernel and file system on it. Now I'm trying to understand how video processing is executed by internal DSP (CEVA MM2000) and how to get raw (yuv) camera image from this dsp to do image processing inside this camera.
[]'s
Hi,
DeleteAlways happy to see comments here. I will start posting again soon more on reverse engineering and firmware reversing.
When you will find the way with the IP Camera it will be nice to share your findings with others through a blog post. Let me know your blog address when you are ready and I will make a comment also in mine.
Nicolas
Hi,
ReplyDeleteVery interesting post!
Can you please reupload a file http://chaos.deventum.com/axis.html.tar.gz ?
Link is broken... i would like to take a look since I have a project with that camera.
Did you tried to modify firmware and install it on camera?
Thanks in advance!
Hi, the proper link is http://chaos.deventum.com/research/axis.html.tar.gz. I didn't try for that one but I don't think it's much of a problem.
ReplyDeleteHello,
ReplyDeleteUsing your methodology, i successfully get access to a linux kerne, but can get access to html & cgi files.
Did you met this kind of issue ?
Best regards
Cedric Baillet
Hi Cedric,
ReplyDeleteYou extracted a different partition there is a jffs2 partition with the data.
Regards,
Nicolas
Nicolas, I am having trouble reproducing your steps. Binwalk identifies the start of the JFFS2 block now, but when I carve it out and mount, using your steps, I get a mangled filesystem with directories working, but corrupt files. Some of the files are text files with binaries in the middle of them. Have you seen this before? I think I am using the same Axis firmware as well: M1031-W_5_20_3.bin. I am doing this on the most recent kali. Do you think there are MTD settings in the kernel that are munging the filesystem?
ReplyDeleteHi,
ReplyDeleteTry to use the latest binwalk also you might want to take a look at firmware mod kit, https://code.google.com/p/firmware-mod-kit/.
Check if you have the same results
Thanks for response, yes, latest binwalk and fmk (btw, fmk does not extract the firmware). I am using updated kali as well. I did notice that the Binary Analysis Toolkit BAT does extract the firmware, but it uses jffs2dump and then walks that mapping to extract the files... it is missing some directories as well...but at least the files are there, that it does extract. Would it be possible for you to check your steps on kali, so I know if I am nuts or not... I appreciate any feedback you can give, I would like to simply carve out the JFFS2 portion of the firmware and mount it through MTD but that is not working... again, files are missing and or corrupted.
ReplyDeleteNice post!!Thanks for sharing...While searching i had come across one site that provides both wired and wireless design network camera at an affordable price...