Quantcast
Channel: Cameras – Sergei's incoherrent ramblings
Viewing all 24 articles
Browse latest View live

exploring Dahua firmware

$
0
0

A sidetrack from these two posts: Extracting password from Dahua firmware image and Dahua IPC-HFW4300S

To recap: I managed to extract various UBI (NAND flash) images from firmware image.

binwalk -e {firmware_file}

Which gave me the following files:

check.img
custom-x.ubifs.img
dhboot.bin.img
kernel.img
partition-x.cramfs.img
pd-x.ubifs.img
romfs-x.ubifs.img
user-x.ubifs.img
web-x.ubifs.img

I started with romfs-x.ubifs.img as initial grep revealed it contained root password hash (matched to ‘vizxv’).

Mounting UBIFS is not a straight forward (eg cannot use loop).
With help of two guides I found (here and here) I managed to figure out how to mount these images.

apt-get install mtd-utils
modprobe nandsim first_id_byte=0x20 second_id_byte=0xaa third_id_byte=0x00 fourth_id_byte=0x15
modprobe ubi mtd=0
tail -c+65 romfs-x.ubifs.img > romfs
ubiformat /dev/mtd0 -f romfs
ubiattach -p /dev/mtd0
mkdir target
mount -t ubifs /dev/ubi0_0 target

note: tail -c65 strips the header.

mounting contents of romfs-x.ubifs.img gives some insight on the root file structure:

drwxr-xr-x  2  500  500 5192 Apr  2  2013 bin
drwxr-xr-x  7  500  500  480 Feb 18  2012 dev
drwxr-xr-x  6  500  500  960 Feb 24  2013 etc
drwxr-xr-x  2  500  500  160 Jan 13  2012 home
drwxr-xr-x  2  500  500 4832 Feb 22  2013 lib
lrwxrwxrwx  1  500  500   11 Dec 31  2013 linuxrc -> bin/busybox
drwxr-xr-x 13  500  500  864 Dec  5  2012 mnt
drwxr-xr-x  2  500  500  160 Jan 13  2012 nfs
drwxr-xr-x  2  500  500  160 Jan 13  2012 proc
drwxr-xr-x  2  500  500  160 Jan 13  2012 root
drwxr-xr-x  2  500  500 2728 Dec 25  2013 sbin
drwxr-xr-x  2  500  500  160 Jan 13  2012 share
drwxr-xr-x  2  500  500  160 Jan 13  2012 slave
drwxr-xr-x  2  500  500  160 Jan 13  2012 sys
lrwxrwxrwx  1  500  500    8 Dec 31  2013 tmp -> var/tmp/
drwxr-xr-x  2  500  500  160 Jan 13  2012 usr
drwxr-xr-x  3  500  500  224 Jan 13  2012 var

looking at /etc/inittab:

...
::sysinit:/etc/init.d/dnode
::sysinit:/etc/init.d/rcS
...

the /etc/init.d/dnode sets up some of the device nodes, nothing interesting there…
while /etc/init.d/rcS contains some interesting stuff:

/sbin/ubimkvol /dev/ubi6 -s 2500000 -N config
mount -t ubifs ubi6_0 /mnt/mtd

Here what I found out from contents of each UBIFS file:

UBIFS description
check.img contains some hardware IDs
custom-x.ubifs.img /mnt/custom customisation files?
dhboot.bin.img bootloader
kernel.img kernel image
partition-x.cramfs.img contains partition.txt
pd-x.ubifs.img /mnt/pd/ product description files
romfs-x.ubifs.img / root
user-x.ubifs.img /usr/
web-x.ubifs.im /mnt/web/ webUI related files

Interesting bit regarding partition-x.cramfs.img, that it contains partition.txt:


#       name                cs         offset              size         mask_flags
  U-Boot,             0, 0x0000000000200000,    0x0000000000100000, RW
  hwid,               0, 0x0000000000300000,    0x0000000000100000, RW
  updateflag,         0, 0x0000000000400000,    0x0000000000100000, RW
  partition,          0, 0x0000000000500000,    0x0000000000100000, RW
  custom,             0, 0x0000000000600000,    0x0000000000340000, RW
  product,            0, 0x0000000000940000,    0x0000000000340000, RW
  Kernel,             0, 0x0000000000c80000,    0x0000000000580000, RW
  romfs,              0, 0x0000000001200000,    0x0000000000800000, RW
  web,                0, 0x0000000001a00000,    0x0000000000800000, RW
  user,               0, 0x0000000002200000,    0x0000000001980000, RW
  syslog,             0, 0x0000000007200000,    0x0000000000400000, RW
  config,             0, 0x0000000007600000,    0x0000000000400000, RW
  backup,             0, 0x0000000007a00000,    0x0000000000400000, RW
  END

all this is effort was to find the telnet password...
I am missing /mnt/mtd mount point, specifically /mnt/mtd/Config/passwd file, which looks like contains telnet password (possibly?)...

UPDATE: solution to the password debacle is here (at the end of the article).

Now the question where the portion of the telnet password 7ujMko0 comes from? "Inspecting" (running strings) telnetd binary from flash image reveals that it is hard coded into telnetd. If Dahua ever changes that value I know where to find it now.


Comment Honey Pot

$
0
0

This page is a comment honey pot.

You are welcome to post your spam here.

Leave a Reply

Your email address will not be published. Required fields are marked *


inside of Dahua IPC-HFW4300S

$
0
0

I have decided to switch back from 8mm lens to 3.6mm lens (Mega brand, sold as 3.6mm, f2.3, M12, for 1/3″ sensor).

Disassembly is fairly straight forward.
dahua-ipc-hfw4300s-000
Note: there is no need to remove screw from the back of the camera. It looks like it is covering a breathing hole (the screw does not hold anything).

Unscrew the front half:
dahua-ipc-hfw4300s-001

The IR LED PCB is held by couple of screws:
dahua-ipc-hfw4300s-002

In case of lens change there is no need to disassemble further. But for curiosity I continued.
The SoC board is held by another couple of screws and two screw posts that IR LED PCB was screwed into. These posts can be unscrewed by flat screw driver.
dahua-ipc-hfw4300s-003
Interestingly enough the camera is mostly empty space, the raised part of the body inside is used as heat sink (covered by yellow heat sink pad). There was a bag of silica gel inside.

The SoC board with lens:
dahua-ipc-hfw4300s-004
Lens is simply threaded on the sensor body, secured by locking nut. Everything was finger tight. The locking nut is transferred to the new lens and then the whole thing is assembled back, except IR PCB and front cover. Focusing is done on live camera, preferably with a special pattern. The trick is slightly “over” focus, and then tighten the locking nut (while holding the lens).

Back of SoC board:
dahua-ipc-hfw4300s-005

dahua-ipc-hfw4300s-006

Here what states on the “CPU”:

Ambarella
A5s-CO-RH
A1407
N6WY4-AN3
1N1
A5s88

Here is the front of SoC with lens removed:

dahua-ipc-hfw4300s-007
The dust speckle on the sensor was courtesy of Chinese aliexpress seller (probably when they replaced the lens to 8mm).

I used a bit of sticky tape to remove the dust speckle without leaving anything else on the IR filter.

The screws were one time use only (made out of Chinesium) so I replaced them with nice stainless steel screws.

Rebooting IP cameras remotely

$
0
0

Hikvision

Complete Hikvision API documentation is available here.

To reboot remotely a Hikvision IP camera, all one needs to do is ‘PUT’ /System/reboot:

curl -X PUT --user {USERNAME}:{PASSWORD} http://{CAMERA_IP}/System/reboot

Dahua

Complete Dahua API documentation is available here.

To reboot remotely a Hikvision IP camera, all one needs to do is 'GET' /cgi-bin/magicBox.cgi?action=reboot:

curl --user {USERNAME}:{PASSWORD} http://{CAMERA_IP}/cgi-bin/magicBox.cgi?action=reboot

Converting Blackvue Dashcam gps log

$
0
0

It appears that Blackvue dashcams log GPS data in “almost” NMEA format.
It is possible to convert the file using gpsbabel utility into KML format that google maps/earth can understand.
All you need to do is strip time stamp appended to each line in the log and them process the output with gpsbabel:

cat {BLACKVUE_GPS_LOG}.gps | awk -F ']' '{ print $2 }' | egrep -v '^$' > {BLACKVUE_GPS_LOG}.nmea
gpsbabel -i NMEA -f  {BLACKVUE_GPS_LOG}.nmea -o KML -F {BLACKVUE_GPS_LOG}.kml

This is what log looks like:

[1389266060242]$GPRMC,221417.990,A,4533.1826,S,16737.5506,E,054.7,035.5,080114,,,A*77

[1389266060242]$GPVTG,035.5,T,,M,054.7,N,101.4,K,A*0C

[1389266060242]$GPGGA,221418.990,4533.1701,S,16737.5631,E,1,11,1.1,204.6,M,1.7,M,,0000*78

[1389266060242]$GPGSA,A,3,16,07,03,19,23,13,10,06,09,27,08,,2.0,1.1,1.7*3D

[1389266060242]$GPGSV,3,1,12,13,80,310,39,07,50,247,36,23,50,019,48,03,48,066,46*71

[1389266060242]$GPGSV,3,2,12,16,45,128,43,27,42,084,44,06,41,096,44,19,28,038,46*79

[1389266060242]$GPGSV,3,3,12,10,26,260,31,08,19,261,32,09,16,257,26,05,06,210,*77

[1389266061239]$GPRMC,221418.990,A,4533.1701,S,16737.5631,E,054.8,035.0,080114,,,A*7F

Navman (Mio) MiVue 388

$
0
0

Navman_MiVue388

I bought Navman MiVue 388 for holiday in Australia, as I was going to do a few thousands kilometres worth of driving.
This camera is sold everywhere else under Mio brand. It is not a Navman product.
When I was purchasing this dash camera I had few prerequisites (which it met, somewhat):
1) 1080p
2) suction cup mount (for easy removal from rental)
3) Modest size
4) Available next day
5) Reasonably priced (under $250)
6) GPS
So basically the only product in New Zealand that met those was this camera.

Whatever you do, do not buy this dash camera. There is nothing really positive I can write about it (apart that it supports 64GB VFAT formatted card, despite the specifications). It pales in comparison to a much cheaper G1W, or Mini0806 or even my dated Blackvue DR400G-HD II. If you are after a good value for money camera get G1W for ~$60USD. Same applies to MiVue 338/358.

Image quality is very grainy:

I didn’t test the camera with optional CPL filter as Navman didn’t sell it at the time (it could have been sources from eBay as Mio branded).

Beyond image quality there are other major issues:

* Suction cup mount is a standard GPS mount, is way too big and vibration prone. It is not very good and falls off after few hours. Not possible for discreet mounting in a smaller car without major view obstruction.
* After 1 month of operation the face plate (screen cover) fell off. It was stuck on by two short strips of double sided tape. After reattaching second time, I gave up and now the camera is used without it.
* Occasionally it decided to completely lose time settings and gets stuck on Setup Time screen. While in that state it does not record!!!
* Cannot turn off blue pixelated “MiVue388” logo on top of the screen (without hacking firmware).
* Battery life is hopeless (about 1 minute and 30 seconds). Good luck actually using park mode.

Two of the issues were because of the climate in New Zealand; this camera is not suitable for being attached permanently on the windscreen due to heat. It is probably far worse for it in Australia.

To address the shitty mount I have decided to build my own mount (secured by not suction cup but double sided tape).
The materials I used are the following:

* Piece of scrap aluminium plate (some random cut off)
* A random drawer knob that I found at hardware store (a 16mm ball with threaded hole and a screw).
* 3M moulding tape
* Black paint

IMG_20140816_125834
IMG_20140816_125848
IMG_20140816_125901
IMG_20140816_125928

Test fit:
IMG_20140816_130112
IMG_20140816_130157

Painted and assembled:
IMG_20140816_131827
IMG_20140816_131849
IMG_20140816_132327

Finished product:
IMG_20140817_141948
IMG_20140817_142026

With my mount the dash cam no longer blocks the view, in fact it is almost not visible (apart from status LED) from drivers seat. It is also very discreet from outside as it is masked by mirror contour.

inside of Mini0806

$
0
0

Below is the breakdown of mini0806 dashcam.

The packaging contents:
IMG_20150727_161216

Camera itself:
IMG_20150807_113915

IMG_20150807_113946

IMG_20150807_113937

To open pop the rear cap with fingers:
IMG_20150807_132100

There are screws behind it holding the whole camera together:
IMG_20150807_132254

Notice torn cable inside of the ring? This is a common assembly/design fault:
IMG_20150807_132408

The shell is easily separated:
IMG_20150807_132554
The beefy heat sink is a good thing to have, I believe it is relatively easy to add a micro fan there (maybe with minimal case cutting).

IMG_20150807_132613

The two boards held together quite tight. Here is the camera side:
IMG_20150807_133206

IMG_20150807_133216

Here is the back side:
IMG_20150807_133319

Notice how battery is simply jammed between two halves? It is held by double sided tape…

Under the battery:
IMG_20150807_133359

I have added insulation tape around battery area in case the battery swells in future:
IMG_20150807_133725

Camera is easily assembled back, one thing to watch out for is the power/GPS cable that feeds through the ring. It can be easily jammed and torn by adjusting the angle, if it is not assembled carefully. I bolted the contact pad last which allowed me to check if the cable is jammed.

Dahua IPC-HDBW4300E

$
0
0

Dahua IPC-HDBW4300E with 2.8mm lens.

Bought on Aliexpress, initially came with Chinese firmware, but seller helped me resolve this (was advertised as English).

Reason why I went with dome vs bullet is because I needed wider angle camera.

Here it is:
IMG_20150601_093506

To adjust it one needs to remove the dome with Allen Key provided:

IMG_20150601_093933
(sorry about blurry photo).
IMG_20150601_093954

IMG_20150601_094002

From Firmware/System perspective it is no different to Dahua IPC-HFW4300S.

Day time image quality exactly the same, except of course the HFW4300S comes with 3.6mm lens minimum while HDBW4300E comes with 2.8mm.
Night time image quality is a bit worse (due to weaker IR, and wider lens).

Here is the angle comparison:

3.6mm (HFW4300S):
Dahua-IPC-HFW4300S-day

Dahua-IPC-HFW4300S-night

2.8mm (HDBW4300E):
2015-9-23-11-23-23-668869

2015-8-23-19-36-17-795868


ILDVR INC-MH40D06

$
0
0

ILDVR INC-MH40D06

A 4MP dome IP camera (this particular has 2.8mm lens) ordered from ildvr.com, somewhat unknown company between western IP camera enthusiasts (although it is known in Russian circles). I have stumbled up when researching new cameras on some Russian website.

Made an enquiry on ildvr.com expecting to have usual “go away” response (as in: “contact our useless resellers, that will not sell you anyway”). To my surprise I got a very quick reply with all my questioned answered.

The retail price of this camera is around $100USD (they charge extra for their windows software, in which I was not interested).

From hardware perspective this camera is similar to Dahua IPC-HDBW4300E.

It has metal construction with plastic dome. Biggest difference is that the Dahua has PoE circuit on the base, while ILDVR has it on the camera body.

The camera came in a cubic box which contained another box padded by thin layer of foam. One issue with packaging I had is that the bag containing the mounting screws was not sealed properly and spilled the screws. One of the screws managed to leave a scratch on the dome. This scratch is not a huge issue is that it is unlikely it will ever be in field of view.

INC-MH40D06_box

INC-MH40D06_box1

The warranty sticker is a nice touch:
INC-MH40D06_box2

INC-MH40D06_box3

The ILDVR letters are bunch of stickers (I will probably remove them as they are a bit tacky):
INC-MH40D06_camera

Second warranty sticker on camera itself:
INC-MH40D06_camera1

INC-MH40D06_camera2

Note the string preventing the dome from falling. The screws are also captive and of torx type (a bit nicer than usual hex screws).
INC-MH40D06_camera3

INC-MH40D06_camera4

A close up of the scratch (nothing to really worry about):
INC-MH40D06_scratch

The box contained a Torx “L” wrench, template, mounting screws/dowels and ethernet jack seal kit.
Note: there was no CD (normally containing crappy windows software) or manual.

An interesting feature is the ethernet status LEDs on the connector:
INC-MH40D06_jack

The cable itself is about 40cm long.

Technical details

Most of this stuff I discovered poking around while waiting for technical details from ILDVR.
I will fill in once I have more details.

With no help from ILDVR I managed to get shell on it.

ARMv7 Processor rev 5 (v7l)
128MB RAM
16MB Flash (MX25L128XX)

/proc/cpuinfo

Processor       : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 1196.85
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

Hardware        : hi3516a
Revision        : 0000
Serial          : 0000000000000000

free -m

             total         used         free       shared      buffers
Mem:           121           64           57            0            0
-/+ buffers:                 64           57
Swap:            0            0            0

load hovers around 3 (less than Dahua and Hikvision).

uname -a

Linux ipc 3.4.35 #5 Fri May 8 10:31:07 CST 2015 armv7l GNU/Linux

df -h

Filesystem                Size      Used Available Use% Mounted on
/dev/root                 2.0M      2.0M         0 100% /
tmpfs                    30.0M     19.9M     10.1M  66% /dev
tmpfs                    30.0M     19.9M     10.1M  66% /tmp
tmpfs                    30.0M     19.9M     10.1M  66% /dev
tmpfs                    30.0M     19.9M     10.1M  66% /var
tmpfs                    30.0M     19.9M     10.1M  66% /tmp
tmpfs                    30.0M     19.9M     10.1M  66% /dev
tmpfs                    30.0M     19.9M     10.1M  66% /var
/dev/mtdblock3           11.0M      8.5M      2.5M  77% /mnt/flash
tmpfs                    30.0M     19.9M     10.1M  66% /mnt/flash/Server
tmpfs                    30.0M     19.9M     10.1M  66% /usr/lib
tmpfs                    30.0M     19.9M     10.1M  66% /etc
tmpfs                    30.0M     19.9M     10.1M  66% /root

cat /mnt/flash/productinfo/deviceid.txt

DEVICEID V6202IR-OV4689

I found actual manufacturer of the board:
http://www.hankvision.com/chanpin/wangluomozu/512.html

In case link goes away here is the screenshot:
hankvision_HC-9402A

They claim it is Hi3516D chipset.

The webUI.

Default username and password is admin.
I was hoping for a more modern interface, the one without ActiveX/Windows only crap…
As usual the viewer is useless without ActiveX plugin, even if mjpeg is selected there is a bug where it only shows two frames.
The Video and Camera settings are useless again due lack of plugin.
This webUI is on par on crappiness with Hikvision and Dahua.
One day we will have platform independent HTML5 interface… I hope.

Epic fail with activeX:
ildvr_activeX_crap

ildvr_camera_settings_plugin_fail

MJPEG stream preview is a bit buggy (not really visible here):
ildvr_mjpeg_fail

Various settings:
ildvr_settings_page

ildvr_video_settings

The most important feature that is missing is Telnet/SSH control (I would rather turn off Telnet). The telnet is on all the time (I have enquired about telnet access).
There is also no control regarding password protecting streams.

It took me a while to figure out the streams, due to misleading Dahua style URL working somewhat. This will work rtsp://192.168.1.200:554/cam/realmonitor?channel=0&subtype=0 but it disregards the channel or subtype selection and only gives sub stream (“minor” in ILDVR terms). That URL is not correct.
Below are correct urls (I lifted them off the javascript in the webUI).

Main stream (aka “major”):

rtsp://192.168.1.200:554/1/h264major

Sub stream (aka “minor”):

rtsp://192.168.1.200:554/1/h264minor

Snapshot URL:

http://admin:admin@192.168.1.200/jpgimage/1/image.jpg

Not sure what is the correct URL for mjpeg stream…

Interesting that the camera supports H265/HEVC. I am yet to test it (need to compile ffmpeg with h265 support).

The resolution selection goes all the way up to 2592×1944 (“2K”) on the “major” stream.

As typical there are stream errors with UDP stream (TCP stream is OK).

In general Web UI is very crappy and not tailored to the camera. It does not even get the camera model correctly.
There is a special clause in javascript for hi3518E chip (for whatever reason?).

I have spent a few hours pocking around the camera I noticed a few issues with webUI. I could crash (in a minor way) the camera with malformed fields when setting the time (via curl POST) as the validation happens in the javascript.
The smtp,ftp and alarm settings don’t work. The motion detect is useless without ftp/smtp or alarm settings.

The following quirks I found:

/form/, /cgi/ and /cgi-bin/ are all the same paths.
There is a “form” validation which does not allow arbitrary /cgi-bin/ script execution.
The simple path traversal exploit does not work.
Various little hack failed (command execution, remote inclusion, etc.), but I haven’t tried hard enough (I don’t normally hack things).
Any URL ending with image.jpg will result of attempting to get a snapshot from camera.
The ones that dont match jpgimage/1/image.jpg result in following output:

HTTP/1.0 200 OK
Content-Type: text/html

Image error

 

This potentially could be exploited (I don’t know how yet).

A lot of validation is happening in javascript. It is possible to set IP address, create username or almost any other field to any test string. I am currently trying to exploit this “feature”.

There are also a few places in javascript that has hard-coded “admin/admin” username and password:

document.getElementById("replay").SetLoginParam(srcIP,'admin','admin');		//justin changed 2013.6.27
document.getElementById("replay").SetLoginParamEx(srcIP,'admin','admin',$("#httpPort").val(),$("#rtspPort").val());		//2014.04.12

and:

player.RunPlayEx(ipAddr.toString(),0,"0.0.0.0",2,90,0,"admin","admin");

 

There are a lot of references to “justin” all over the place.

The onvif located at http://192.168.1.200:8999/onvif/
The onvif is not password protected!!!! (I can add remove users, reboot camera, change passwords, etc).

The server headers are very similar to Hikvision (only it is “Hankvision”, lol WTF?):

HTTP/1.1 200 Data follows
Server: Hankvision-Webs
Date: Thu Dec 24 12:44:27 2015
Pragma: no-cache
Cache-Control: no-cache
Content-Type: text/html

 

Digging more around I found that OMEGA-21P22-12 has same firmware (I googled the firmware version number out of desperation).

Basically I am thinking of getting serial port hooked up the board as the manufacturer is silent regarding telnet/shell access and I do not trust this firmware at all.

Here are the innards (the simplest way to remove the board is to unclip IR cover from front using two clips on the side):

INC-MH40D06_module_back

PoE module:
INC-MH40D06_PoE

SoC board (unfortunately cannot tell the model of SoC due to heatsink, looks like Hisilicon, possibly Hi3516D):
INC-MH40D06_SoC

Lens:
INC-MH40D06_lens

Sensor (I assume it is OV4689):
INC-MH40D06_sensor

Conclusion.

It started all promising (communication, pricing and delivery). Hardware is great. Firmware is the show stopper.

I am thinking of putting off buying ILDVR cameras due to “secrecy” regarding firmware and telnet access (not unless I can flash them with generic Hivision firmware).

I’ll probably stick to Dahua, as at least I have shell access on those (and I can hack firmware to fix/address whatever issues arise). Even though Dahua does not want to deal with me directly…

Update: I managed to get shell on it, more info here.

Reverse engineering Hikvision SADP Tool

$
0
0

I got couple of Hikvision cameras that needed to have their passwords reset.

Instead of reset-to-factory default button these cameras have very elaborate password reset process.

Officially one must download SADP tool, get the serial number off the camera, fetch it to the Hikvision support, then they generate you a reset code that you plug in into the camera.

The unreliable Hikvision support can be bypassed with this tool (more details here).

I feel very dirty because I had to install the SADP in a Windows virtual machine (it does not work under Linux).
Interesting that the tool is build around QT and libpcap so technically it should not be too difficult to port it to Linux.

Looking at traffic captures the tool discovers the camera via multicast (239.255.255.250, udp port 37020) with this payload:

<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>13A888A9-F1B1-4020-AE9F-05607682D23B</Uuid><Types>inquiry</Types></Probe>

The camera responds to with this:

<?xml version="1.0" encoding="UTF-8"?>
<ProbeMatch><Uuid>FC25924E-AFE2-49E6-ACC9-F84A6859054D</Uuid>
<Types>inquiry</Types>
<DeviceType>38930</DeviceType>
<DeviceDescription>DS-2CD2432F-IW</DeviceDescription>
<DeviceSN>DS-2CD2432F-IW20150126CCCH502126167</DeviceSN>
<CommandPort>8000</CommandPort>
<HttpPort>80</HttpPort>
<MAC>c0-56-e3-fe-42-92</MAC>
<IPv4Address>10.1.1.251</IPv4Address>
<IPv4SubnetMask>255.255.255.0</IPv4SubnetMask>
<IPv4Gateway>10.1.1.1</IPv4Gateway>
<IPv6Address>::</IPv6Address>
<IPv6Gateway>::</IPv6Gateway>
<IPv6MaskLen>64</IPv6MaskLen>
<DHCP>false</DHCP>
<AnalogChannelNum>0</AnalogChannelNum>
<DigitalChannelNum>1</DigitalChannelNum>
<SoftwareVersion>V5.2.5build 141201</SoftwareVersion>
<DSPVersion>V5.0, build 140714</DSPVersion>
<BootTime>2016-03-06 09:18:17</BootTime>
</ProbeMatch>

This is all nice and easy to replicate, except when discovering that when resetting the password the tool talks to camera directly via ethernet frames:

Reset packet:

12:14:16.063953 52:54:00:db:ae:e4 > XX:XX:XX:XX:XX:XX, ethertype Unknown (0x8033), length 80: 
        0x0000:  2102 0142 0000 173a 0604 0a00 ba54 5254  !..B...:.....TRT
        0x0010:  00db aee4 0a01 0102 XXXX XXXX XXXX 0a01  ........XXXXXX..
        0x0020:  01fb ffff ff00 5252 5364 5264 6572 6439  ......RRSdRderd9
        0x0030:  0000 a100 0000 0000 0000 0000 0000 0000  ................
        0x0040:  0000                                     ..

Response packet:

12:14:16.094857 XX:XX:XX:XX:XX:XX > 52:54:00:db:ae:e4, ethertype Unknown (0x8033), length 260: 
        0x0000:  2101 01f6 0000 173a 0604 0b01 8a3b XXXX  !......:.....;XX
        0x0010:  XXXX XXXX 0a01 01fb ffff ffff ffff 0000  XXXX............
        0x0020:  0000 ffff ff00 4453 2d32 4344 3234 3332  ......DS-2CD2432
        0x0030:  462d 4957 3230 3135 3031 3236 4343 4348  F-IW20150126CCCH
        0x0040:  XXXX XXXX XXXX XXXX XX00 0000 0000 0000  XXXXXXXXX.......
        0x0050:  0000 0000 0000 0000 9812 0000 1f40 0000  .............@..
        0x0060:  0001 0000 0000 5635 2e32 2e35 6275 696c  ......V5.2.5buil
        0x0070:  6420 3134 3132 3031 0000 0000 0000 0000  d.141201........
        0x0080:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0090:  0000 0000 0000 5635 2e30 2c20 6275 696c  ......V5.0,.buil
        0x00a0:  6420 3134 3037 3134 0000 0000 0000 0000  d.140714........
        0x00b0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x00c0:  0000 0000 0000 3230 3136 2d30 332d 3036  ......2016-03-06
        0x00d0:  2030 393a 3138 3a31 3700 0000 0000 0000  .09:18:17.......
        0x00e0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x00f0:  0000 0000 0000                           ......

Now looking further it appears that discovery as well as expected UDP communication there is also ethernet frame type of communication going on in parallel:

Broadcast:

12:13:29.539493 52:54:00:db:ae:e4 > ff:ff:ff:ff:ff:ff, ethertype Unknown (0x8033), length 80: 
        0x0000:  2102 0142 0000 1739 0604 0300 80b6 5254  !..B...9......RT
        0x0010:  00db aee4 0a01 0102 ffff ffff ffff 0000  ................
        0x0020:  0000 0000 0000 fe80 0000 0000 0000 889f  ................
        0x0030:  720d 7c8f 8429 0000 0000 0000 0000 0000  r.|..)..........
        0x0040:  0000                                     ..

Response:

12:13:29.555356 XX:XX:XX:XX:XX:XX > 52:54:00:db:ae:e4, ethertype Unknown (0x8033), length 416: 
        0x0000:  2101 01f6 0000 1739 0604 0400 8c42 XXXX  !......9.....BXX
        0x0010:  XXXX XXXX 0a01 01fb ffff ffff ffff 0000  XXXX............
        0x0020:  0000 ffff ff00 4453 2d32 4344 3234 3332  ......DS-2CD2432
        0x0030:  462d 4957 3230 3135 3031 3236 4343 4348  F-IW20150126CCCH
        0x0040:  XXXX XXXX XXXX XXXX XX00 0000 0000 0000  XXXXXXXXX.......
        0x0050:  0000 0000 0000 0000 9812 0000 1f40 0000  .............@..
        0x0060:  0001 0000 0000 5635 2e32 2e35 6275 696c  ......V5.2.5buil
        0x0070:  6420 3134 3132 3031 0000 0000 0000 0000  d.141201........
        0x0080:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0090:  0000 0000 0000 5635 2e30 2c20 6275 696c  ......V5.0,.buil
        0x00a0:  6420 3134 3037 3134 0000 0000 0000 0000  d.140714........
        0x00b0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x00c0:  0000 0000 0000 3230 3136 2d30 332d 3036  ......2016-03-06
        0x00d0:  2030 393a 3138 3a31 3700 0000 0000 0000  .09:18:17.......
        0x00e0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x00f0:  0000 0000 0000 029c 5648 0a01 0101 0000  ........VH......
        0x0100:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0110:  0000 0000 0000 0000 0000 0000 0000 0007  ................
        0x0120:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0130:  0000 0000 0000 0000 0000 0000 0000 0050  ...............P
        0x0140:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0150:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0160:  0000 4453 2d32 4344 3234 3332 462d 4957  ..DS-2CD2432F-IW
        0x0170:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0180:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0190:  0000

So theoretically it is possible to create a tool based on the reset password code generator to completely cut out middle man.
This is the way I see it working:

1) Discover camera and get serial number and camera ip
2) Get camera date/time via simple GET to port 80.
3) Generate reset code with camera serial number and date/time
4) send magic packet to reset camera.

I found some examples of the traffic that does not contain fe80 0000…XXXX…0000 bit at the end (looks like previous version of SADP Tool didn’t append that crap). I successfully replayed that packet.
I have noticed that the checksum does not include the source (header) of the packet, so as long as the MAC address matches in the body the header can be spoofed.

I have changed the mac address on VM where SADP Tool was running and looks like4 bytes between Source MAC and Destination MAC in the body changes. As well as 2x 2 bytes surrounding 06040300.

If I increment any number by one and decrement @ 0x0018 the packet gets response. This implies that the check sum is only 2 bytes long.

So far I figured out the check sum for older type of discovery packet (without crap at the end of the packet).

the check sum is located here:
0x0010: 00db aee4 0a01 0102 ffff ffff ffff 0000
In this example it is 0102.
Actually the check sum is 0201 (reversed order).
The check sum algorithm is 16-bit one’s complement.
The trick (which was given away by comparing sequential packets) is to ignore the header, and to reverse order in these two bytes:
0x0000: 2102 0142 0000 1739 0604 0300 80b6 5254
in example above they are check-summed as b680.

Next step is to see if I can apply the same method to the password reset packet….

At this stage I solved the following: discovery via frames, discovery via UDP, generate reset code and reset the camera via frame.

There is a potential problem to get camera time reliably (in case it is not configured in same subnet).

After poking around Sadp.dll I found these interesting XML strings:

<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>%s</Uuid><Types>inquiry</Types></Probe>
<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>%s</Uuid><Types>update</Types><MAC>%s</MAC><Password>%s</Password><IPv4Address>%s</IPv4Address><CommandPort>%d</CommandPort><HttpPort>%d</HttpPort><IPv4SubnetMask>%s</IPv4SubnetMask><IPv4Gateway>%s</IPv4Gateway><IPv6Address>%s</IPv6Address><IPv6Gateway>%s</IPv6Gateway><IPv6MaskLen>%d</IPv6MaskLen><DHCP>%s</DHCP></Probe>
<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>%s</Uuid><MAC>%s</MAC><Types>reset</Types><Code>%s</Code></Probe>
<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>%s</Uuid><MAC>%s</MAC><Types>reset</Types><Code>%s</Code><Password>%s</Password></Probe>
<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>%s</Uuid><MAC>%s</MAC><Types>reset</Types><SyncIPCPassword>true</SyncIPCPassword ><Code>%s</Code><Password>%s</Password></Probe>
<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>%s</Uuid><MAC>%s</MAC><Types>getcode</Types></Probe>
<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>%s</Uuid><MAC>%s</MAC><Types>exchangecode</Types><Code>%s</Code></Probe>
<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>%s</Uuid><MAC>%s</MAC><Types>activate</Types><Password>%s</Password></Probe>
<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>%s</Uuid><MAC>%s</MAC><Types>getencryptstring</Types></Probe>

None of that proved to be useful of extracting local time (except inquiry).

See this post for actual script.

mini0806 design flaw

$
0
0

Alternative title: why my mini0806 was crashing and stopped working after a light drop.

One of the differences between mini0805 and mini0806 is this heat sink:
IMG_20160703_110658

It is a bitch to remove, so I gently coerced it with a blade:
IMG_20160703_110803

After some time of gentle pushing and heating it managed to peel off:
IMG_20160703_111536

Revealing Samsung ram chip and Ambarella A7LA50 SoC:
IMG_20160703_111758

Here is why it was not working after slight drop (and crashing before that):
IMG_20160703_113213

Pulled out pads! Note that the blade I used to remove would cause other side of pads missing if I applied too much pressure.

My theory is following: the heat sink that bridges RAM and SoC is causing stress on these chips. Mostly because it is glued and not mechanically pressed against the chips. This is a very silly design flaw, if for example, only SoC would have the heat sink (like found on IP cameras) then there would not be any stresses. I don’t think RAM needs heat sinking on those things.

I am tempted to take dremel to my other mini and split the heat sink in two…

Viofo A119

$
0
0

Box:
A119_box

A119_box_side

Camera:
A119_side_usb

A119_screen

A119_lens

GPS mount:
A119_gps_mount_side

A119_gps_mount

Mounting position:
A119_led_front

A119_descreete_mount_screen_on

A119_descreete_mount_screen_off

A119_descreete_mount_outside

A119_descreete_mount_mirror

A119 vs A118c:
A119_A118c_side

A119_A118c_screen_top

A119_A118c_screen_bottom

A119_A118c_mount_side

A119_A118c_lens_mount_side

A119_A118c_lens

A119 vs A118c vs DR400G-HDII vs Mini0806:
A119_A118c_mini0806_DR400GHDII_side

A119_A118c_mini0806_DR400GHDII_lens

A119_A118c_mini0806_DR400GHDII_back

To be continued…

Extracting GPS data from Viofo A119 and other Novatek powered cameras

$
0
0

The script.

Here it is: nvtk_mp42gpx.py

What does it do?

This script will attempt to extract GPS data from Novatek MP4 file and output it in GPX format.

Usage: ./nvtk_mp42gpx.py -i<inputfile> -o<outfile> [-f]
        -i input file (will quit if does not exist)
        -o output file (will quit if exists unless overriden)
        -f force (optional, will overwrite output file)

In short: it takes Novatek encoded MP4 file (with embedded GPS data) and extract GPS data in GPX format (as separate file). Note; it does not modify the original MP4 file.

In long:

What the? Where is the bloody GPS data?
Unlike competitors (Ambarella and such) Novatek actually embeds the GPS data in MP4, specifically in free atoms/boxes in midst of the stream chunks. This is a bit different than Amberalla’s embedding in the subtitle track (which is trivial to extract with open source tools).

The search for documentation for the Novatek data structure was a scavenger hunt on itself.

Although writing the MP4 rudimentary parser took longest time, figuring out Novatek data structure was more complicated due to lack of information.

MP4 container basics
Disclaimer: I am no expert or even at enthusiast level regarding the video containers, thus information below is not guaranteed to be correct. These are simply my findings and should be “taken with a grain of salt”.

In very simple terms the MP4 container consists of atoms/boxes (the name depends which documentation you read). The boxes can contain other boxes.

Each box starts with 8 byte “header” (including the beginning of the file). The first 4 bytes is the size of the box (big endian unsigned int), the second 4 bytes contains 4 character string name/type of the box. The size includes itself (so valid size is >= 0x0008 unless the special type of large box which I will conveniently omit in this post ;)). Basically MP4 container can be treated as some rudimentary file system.

For example:

00 00 00 1c  66 74 79 70

translates to box size of 28 bytes (0x1c) of type “ftyp”, the first box in the file (0x66=f 0x74=t 0x79=y 0x70=p in ASCII). As note: “ftyp” is basically “file type” description box.

00 01 68 7d  6d 6f 6f 76

translates to box size of 92285 bytes and of type “moov”, the box of special importance.

For purpose of extracting data I am interested in only following box types: “moov”, “gps ” and indirectly “free”.

The “moov” box is a special type, kind of index/metadata box (box of all boxes ;)). It contains video/audio/other data chunk mapping, other boxes and of a special importance, a non-standard “gps ” box.
This non-standard “gps ” box contains mapping of all GPS data boxes (will cover this later).

I assume that “moov” box should always be in top level (not a sub-box).

In my script I basically iterate through all top level boxes until I hit the “moov” box. Then I begin to iterate sub-boxes inside of the “moov” box, until I hit “gps ” box (this where the fun begins).

Note: Here is the reference I used to figure some of it out: http://l.web.umkc.edu/lizhu/teaching/2016sp.video-communication/ref/mp4.pdf and http://www.cmlab.csie.ntu.edu.tw/~cathyp/eBooks/14496_MPEG4/ISO_IEC_14496-14_2003-11-15.pdf

Novatek special “gps ” box
The “gps ” box is found inside of “moov” box.
The “gps ” box stores the file offset (in bytes) and size (in bytes) for each GPS data box.
The first 8 bytes in the “gps ” box contain version and encoded build date. I simply chose to ignore this data.
The subsequent 8 bytes contain 4 byte file offset (absolute) and 4 byte size (offset and size are big-endian unsigned ints).

00 2b e9 50  00 00 10 00

Translates to a GPS data box at position 0x002be950 (at 2877776 bytes) of size of 4096 bytes (0x1000).
Following the offset we find the GPS data box exactly where it supposed to be:

002be950  00 00 10 00 66 72 65 65  47 50 53 20 4c 00 00 00  |....freeGPS L...|

Novatek special “free” box beginning “GPS “
Not to be confused with “gps ” box ;).
This box sits in “free” box in midst of data chunks. The box can be identified with a magic “GPS ” string.
For some reason Novatek decided to store all the data in this box in little-endian format…

Here is the structure:

# Datetime data
hour: unsigned little-endian int (4 bytes)
minute: unsigned little-endian int (4 bytes)
second: unsigned little-endian int (4 bytes)
year: unsigned little-endian int (4 bytes)
month: unsigned little-endian int (4 bytes)
day: unsigned little-endian int (4 bytes)

# Coordinate data
active: string (1 byte) # satelite lock "A"=active, everything else (eg " ") lost reception
latitude hemisphere: string (1 byte) # "N"=North or "S"=South
longitude hemisphere: string (1 byte) # "E"=East or "W"=West
unknown: string (1 byte) # No idea, always "0"? 
latitude: little-endian float (4 bytes) # unusual format of DDDmm.mmmm D=degrees m=minutes
longitude: little-endian float (4 bytes) # unusual format of DDDmm.mmmm D=degrees m=minutes
speed: little-endian float (4 bytes) # Knots (the nautical kind)
bearing: little-endian float (4 bytes) # degrees, not used in GPX.

Disclaimer: this was a good hint in right direction: https://github.com/kbsriram/dcutils

Converting odd DDDmm.mmmm coordinate format to GPX compatible
Here is the algorithm:

def fix_coordinates(hemisphere,coordinate):
    # Novatek stores coordinates in odd DDDmm.mmmm format
    minutes = coordinate % 100.0
    degrees = coordinate - minutes
    coordinate = degrees / 100.0 + (minutes / 60.0)
    if hemisphere == 'S' or hemisphere == 'W':
        return -1*float(coordinate)
    else:
        return float(coordinate)

Converting knots to m/s

speed * float(0.514444)

Putting together GPX format

For GPX format to work one needs header similar to this:

<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.0"
        creator="Sergei's Novatek MP4 GPS parser"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.topografix.com/GPX/1/0"
        xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
        <name>../Videos/ubertec moron/2016_0716_235252_140.MP4</name>
        <url>sergei.nz</url>
</gpx>

Specifically it will not import without:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd"

The track data is put together in following way:

<trk><name>test.gpx</name><trkseg>
                <trkpt lat="-36.863672" lon="174.765625"><time>2016-07-16T23:52:51Z</time><speed>23.484369</speed></trkpt>
                <trkpt lat="-36.863546" lon="174.765397"><time>2016-07-16T23:52:52Z</time><speed>23.479224</speed></trkpt>
</trkseg></trk>

Testing GPX file

I found an utility called xmllint that can be used to test GPX data (apt-get install libxml2-utils):

xmllint --noout --schema http://www.topografix.com/GPX/1/0/gpx.xsd test.gpx

One year with Mini0806

$
0
0

WARNING: DO NOT BUY MINI0806 UNDER ANY CIRCUMSTANCES.

You have been warned.

Here is simple reason why: out of 8 mini0806s that passed through my hands, 5 failed and one dying(failure rate >60%).

Here is the tally:

First ever mini0806 I got was on 01/05/2016.
I purchased it from gearbest.com on 31/03/2016, and got it after a month of being, what I assumed, shipped via a bottle thrown in the sea.
Immediately I noticed that it would crash when chosen any high resolution other than 2560x1080p30. Press stop/start recording 3 times and it would lockup (30s power button reset was the only way to recover it).
I created a ticket with gearbest only to be given run around. They suggested to get it fixed locally, and they will reimburse the bill. How many component level repair specialist that charge $5/hour are in New Zealand? After being offered 10% discount coupon, I decided to contact Megtech directly (the manufacturer of the camera).
After spending $40NZD (~30% of the cost of the camera) on shipping, in about one month I got the replacement. While waiting for the replacement I bought another mini0806 (I never learn ;)) this turned out to be the only reliable mini I personally owned).
The replacement from Megtech had exactly same problem. As if they simply returned my camera back, if it was not for protective film on LCD suggesting it is another new unit.
In between getting my faulty camera returned, I had the second camera running well, thus my friends decided to buy mini0806 for themselves (bad move).

Friend #1: 2x minis, both faulty (crash on power off, crash on running).
Friend #2: 1x faulty (crash on power off, crash on running), 1x OK (replacement) so far
Friend #3: 1x OK but never checked the recordings for missing data.

So total so far: 5/8 failed. My good mini0806 has low battery warning permanently on.

Megtech suggested bad Micro SD cards. Well, I tested the mini0806s with Samsung Pro, Transcend Ultimate 633x, Strontium Nitro, all class 10, most of them are MLC flash. All of these cards Work fine in Blackvue, Viofo, Navman (MiVue), GitUp cameras. All of these cards also work fine in good mini as well.

At this stage I removed my mini in favour of Viofo A119, which runs really well, has reasonable temperature ratings and no battery.

In conclusion do not buy anything that Megtech makes, or anything from gearbest.com.

python OpenCV basic motion detection

$
0
0

Here I will describe how I use OpenCV for capturing RTSP streams, with purpose of motion detection.

For basic OpenCV I use these two libraries:

import cv2
import numpy as np

cv2 is OpenCV library (second version), and numpy is python numeric lybrary (useful for manipulating matrices among other things).

To initiate capture one simply does following:

cap = cv2.VideoCapture('rtsp://192.168.1.69:554/Streaming/Channels/2')

In this example I use second stream (of lower resolution) for motion detection.

From there you can get heigh and width of the frame (this will be useful later):

width = cap.get(3)
height = cap.get(4)

I use BackgroundSubtractorMOG for motion detection (somewhat cheating ;)):

bg = cv2.BackgroundSubtractorMOG(100,3,0.6,30)

The magic is in parameters, I used following:
100 – history
3 – number of Gaussian mixtures
0.6 – background ratio
30 – noise strength
The numbers above are not necessarily “correct” but I came to them with error and trial (and “guestimation”).
Here is document in detail describing this algorithm: http://personal.ee.surrey.ac.uk/Personal/R.Bowden/publications/avbs01/avbs01.pdf

The actual capture loop looks something like this:

while(True):
    ...
    ret, frame = cap.read()
    motion = bg.apply(frame, learningRate=0.005)
    kernel = np.ones((3, 3), np.uint8)
    motion = cv2.morphologyEx(motion, cv2.MORPH_CLOSE, kernel, iterations=1)
    motion = cv2.morphologyEx(motion, cv2.MORPH_OPEN, kernel, iterations=1)
    motion = cv2.dilate(motion,kernel,iterations = 1)
    contours, hierarchy = cv2.findContours(motion, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    ...
ret, frame = cap.read()

captures a single frame

motion = bg.apply(frame, learningRate=0.005)

extracts a black and white image with the background removed (learnignRate value has been chosed by error and trial).

Next four lines simply manipulate extracted image in such that it does following:
MORPH_CLOSE: removes small holes (up to 3×3 pixel, defined by kernel) within the object (“white”) in the extracted motion matrix.
MORPH_OPEN: removes small dots within the “background” (black) in the extracted motion matrix.
dilate: is making sure there all adjacent islands are joined together, so when we extract contours we get small amount of contours as result.

The “3×3 pixel” block comes from here:

kernel = np.ones((3, 3), np.uint8

The last step from processing frame is extracting the contours:

contours, hierarchy = cv2.findContours(motion, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

The extracted contours can then be iterated and hull drawn around them:

for cnt in contours:
    hull = cv2.convexHull(cnt)

The hull points then can be checked against the mask if motion is inside of the area of interest:

Lets define the mask as the whole frame (I am pretty sure there is a better way;)):

mask_points = [
( 0 , 0 ),
( 1 , 0 ),
( 1 , 1 ),
( 0 , 1 ),
]

mask_array=[]
for point in mask_points:
    mask_array.append([[int(point[0] * width ), int(point[1] * height )]])
mask = np.array(mask_array, np.int32)

This looks cumbersome, but what I am achieving here is converting mask_points list of human readable relative coordinate tuples (eg: centre will be at (0.5,0.5)). Mask can be defined as a polygon with relative positioning of each corner to the frame (independent from pixel size).

We check if hull point is inside our mask

for point in hull:
    distance = cv2.pointPolygonTest(mask,tuple(point[0]),1)
    if distance > 0:
        it_is_inside()

and vice-versa (in case if mask is smaller than the frame):


Note: The colour is defined by this tuple: (0,255,0)

Then do display the whole thing insert this inside of the while(True):

cv2.imshow('motion',frame)
k = cv2.waitKey(30) & 0xff
if k == 27:
    break

The above is basic idea behind my motion detection scripts. I have omitted a lot of glue logic and arithmetic due to my script is not ready for public display ;).


ILDVR INC-MH40D06 security nightmare part 2

$
0
0

I have put off the ILDVR camera, as I kind of lost interest.
For previous posts see here, here and here.

I was bored so I decided to poke at again.

I was interested where does the camera store users and in what format. What I found out is an atrocious mocking of security.
The camera stores local users and their passwords (in plain text) in following file:

/mnt/flash/data/OwnUserInfo.txt

Yep: the same directory which is accessible without auth via port 10081. So if you forgot password (and forgot the silly hardcoded HANKVISION), then you can get a reminder what it is by simply going here:

http://${CAMERA_IP}:10081/OwnUserInfo.txt

There is also another “binary” file that contains interesting references to HANKVISION and local users:

/mnt/flash/data/UserInfo

strings that and you get following:

HANKVISION
e82f5af1f39f021b44e78089b5a40a8e0aa8d2768c705e8f139bec04d87d5a54
8f081b5a8e0685ca975a01d4159930f9
0d9a1f80bcc7a1e4a00f04588062ed67
admin
8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
21232f297a57a5a743894a0e4a801fc3
76eb00c6458e9b2755b570ae565ba0a6

Changing the password to HANKVISION reveals that this string is “encoded” “HANKVISION”:

e82f5af1f39f021b44e78089b5a40a8e0aa8d2768c705e8f139bec04d87d5a54
8f081b5a8e0685ca975a01d4159930f9

Not sure if the obfuscation is worth spending time on, especially when we already know HANKVISION is hardcoded in web server binary and OwnUserInfo.txt already contains passwords in clear texts.

strace-ing ‘webs’ process during certain conditions opens the /tmp/umconfig.txt, which contains following:

TABLE=users
ROW=0
name=HANKVISION
password=0d9a1f80bcc7a1e4a00f04588062ed67
group=Administrator
prot=1
disable=0
ROW=1
name=admin
password=76eb00c6458e9b2755b570ae565ba0a6
group=Administrator
prot=1
disable=0
ROW=2
name=adminadmin
password=5ca1e16e4fa3fa58b6656b9ad547fa0f
group=Normal
prot=0
disable=0
TABLE=groups
ROW=0
name=Administrator
priv=4
method=2
prot=0
disable=0
ROW=1
name=Normal
priv=4
method=2
prot=0
disable=0
TABLE=access
ROW=0
name=/browse/
method=2
secure=0
ROW=1
name=/jpgimage/
method=2
secure=0
ROW=2
name=/mjpgstreamreq/
method=2
secure=0
ROW=3
name=/form/
method=2
secure=0
group=Administrator
ROW=4
name=/cgi/
method=2
secure=0

The “hashes” correlate to /mnt/flash/data/UserInfo…

Looking firmware upload function (in browse/javascript/sysInf.js) I found this bit:

function fileUpload(){
...
		var typeAllow = [".ifu", "macaddr.txt", "deviceid.txt", "sn.txt", "audio.dat", ".bin", ".png", ".ifc", ".lib", ".uid", ".pid","logo.gif","whitelist.txt"];
		var fileType = ["ifu", "mac", "deviceid", "sn", "audio", "bin", "png", "ifc", "lib", "uid", "pid","gif","wlst"];
....

I have tested the upload function with logo.gif and that worked: the logo on top got replaced, so it brings a possibility of doing something more (sneaking in a binary?).

Looking at ‘webs’ binary I decided to google for strings in case someone leaked the source or these bastards stole somebody else’s work.
Here what I found:
The string:

webs: websWrite lost data, buffer overflow

Matches suspiciously named file here:
https://github.com/socoola/yhrouter/blob/master/user/goahead/src/webs.c

Same could be said for these strings:

webs: Listening for HTTP requests at address %s
webs: accept request

What is surprising is that they avoided doing execve calls where they could. IP addresses, routes, all set via ioctl, even time is set via settimeofday function. This removed possibility of command injection.

Here is what I believe is going on with this firmware:

The video side and core functionality has been lifted off SDK by Hisilicon. The web server stuff has been implemented by actual Hankvision people, most likely low paid undergraduate Chinese students. The core web server functionality has been lifted off the internet (see above).

What could have been done better without spending much on development:

Remove hard coded passwords!
Throw away all activeX crap (use MJPEG stream for “preview”).
Turn off telnet and leave ssh on with configurable password (perhaps make it a separate user?).
Do not store plain passwrods anywhere
Throw away all the dyndns and cloud nonsense.
Add actual off checkbox for FTP, Mail and SIP stuff (and possbly throw away SIP stuff).
Add VLC plug-in functionality.
Remove web server that listens on port 10081 exposing whole bunch of private data.

I am not sure what they are trying to achieve by not allowing SSH/Telnet access, but this is counter productive. I will not buy a security product to which I do not have control! Besides if I wanted to get access to your firmware, I don’t need SSH or Telnet, when I have RS232 and soldering iron.

For those who purchased this camera, if you really have to use it do the following:

Hexedit webs binary and change the HANKVISION bit to something else

And

Remove gateway setting (set it the same IP as camera) and preferably isolate camera from rest of the network (separate VLAN and port forwarding to recorder).

Or

Just chuck it in the bin and never purchase anything from ILDVR again.

Shame on you ILDVR for not responding to me when I contacted you almost a year ago about hard coded passwords. Shame on you ILDVR for not providing root password or firmware updates.

ILDVR – and their lack of professionalism

$
0
0

It all started with me purchasing ILDVR INC-MH40D06 IP Camera. I decided to poke at it and discovered some interesting and blatant security flaws.

About a year ago I contacted ILDVR (Arnold and Marika Wei) regarding the security issues, which got no response.
After about a year of the camera sitting on a shelf, I decided to poke at it again.
Which prompted me to send them this email:

For which I got a friendly response from Marika:

To which I replied, asking for firmware update (which I thought was reasonable to expect firmware updates for products with serious security flaws):

The only response I got is this peculiar email from sales@ildvr.com:

So, it seems that:
1) ILDVR.com/ILDVR does not care about security
2) ILDVR.com/ILDVR does not care about PR
3) ILDVR.com/ILDVR does not care about customers

Perhaps they should adopt the following motto:

“GO TO HELL! – ILDVR (where security does not matter)”.

To be honest, I would probably let go this whole thing if they simply not responded. It would have taken them less effort to not to respond either. Instead they chose to send me email with “GO TO HELL!”. I find this thing very hilarious.

It is even more hilarious if you look at google search results:

ILDVR INC-MH40D06 or hacking cheap chinese camera

$
0
0

Continuation of ILDVR INC-MH40D06

Since manufacturer will not divulge the super secret telnet password, and not having ability to turn off the telnet from web ui, I have decided to get access to camera via more brute method.

This involves opening the camera, soldering a pin header/wires to RS232 pads on the SoC board:

ildvr_rs232_pads_labels

ildvr_1.27mm_rs232

ildvr_1.27mm_to_2.54mm_rs232

ildvr_1.27mm_rs232_2

ildvr_usb_rs232

The RS232 is connected to a 3.3V (NOT 5V!) USB RS232 TTL adapter (a few bucks on ebay). BTW the ebay sourced USB adapter did not come with instruction/pin-out. It is in fact the following:

Red - 3.3V
Green - TX
White - RX
Black - GND

The pin spacing is 1.27mm. I could not find the connector that would fit so I botched 1.27mm->2.54mm header adapter (since the USB adapter came with 2.54mm sockets):

I disconnected the 3.3V pin as the SoC was using that for power and would not reboot when PoE was disconnected.
I used minicom with following settings:

115200 8N1
ttyUSB0

Once power is applied immediately press any key to interrupt the boot process and get uBoot prompt:

U-Boot 2010.06 (May 18 2015 - 09:40:27)

Check spi flash controller v350... Found
Spi(cs1) ID: 0xC2 0x20 0x18 0xC2 0x20 0x18
Spi(cs1): Block:64KB Chip:16MB Name:"MX25L128XX"
In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0 
hisilicon #

To find out correct boot parameters run printenv:

hisilicon # printenv 
bootcmd=sf probe 0;sf read 0x82000000 0x50000 0x2b0000;bootm 0x82000000
bootdelay=1
baudrate=115200
ethaddr=00:00:23:34:45:66
ipaddr=192.168.6.99
serverip=192.168.6.10
netmask=255.255.252.0
bootfile="uImage"
board=hi3516d
bootargs=mem=128M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=jffs2 mtdparts=hi_sfc:320K(boot),2752K(kernel),2M(rootfs),11M(data)
stdin=serial
stdout=serial
stderr=serial
verify=n
ver=U-Boot 2010.06 (May 18 2015 - 09:40:27)

To get root you will need to modify the bootargs variable:

setenv bootargs mem=128M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=jffs2 mtdparts=hi_sfc:320K(boot),2752K(kernel),2M(rootfs),11M(data) init=/bin/sh

It is pretty much exactly the same as original bootargs from printenv except the init is changed to shell (/bin/sh).

To boot, simply run the values from bootcmd variable from printenv:

sf probe 0;sf read 0x82000000 0x50000 0x2b0000;bootm 0x82000000

To continue with boot (to get rest of the mounts and things up and running) run following:

/etc/init.d/rcS

At this stage you can change the root password (via passwd). This will not stick, to make it stick modify Server.tar.xz with desired etc/passwd entry (see below).

Horrible stuff below.
Everything runs as root!

The point of interest is /mnt/flash/Server.tar.xz, I believe init script unpacks it into /mnt/flash/.
It is possible to get the whole file without using tfpt or any other trickery by simply copying it accross into accessible area from webui:

cp /mnt/flash/Server.tar.xz /mnt/flash/web/browse/


From there you can simply type http://${camera_ip}/browse/Server.tar.xz and download the whole thing.

Examining the "server" binary I discovered major security flaw. Specifically in Server/LINUX/webs there are following strings:

name=HANKVISION
password=HANKVISION

I tested it against web ui, and to my horror these credentials allowed me to log in (with admin right nevertheless).

Here is the Server.tar.xz for curious types.

Other things.

The /etc/passwd contained the following:

root:$1$EnVGPLqH$OmqpejDjDsF8NQkcwH/og.:0:0::/root:/bin/sh

I am using JTR with Cuda (on GTX970) against it (at this stage alpha 4-8), but I doubt I will get anywhere. I need to find an exploit to change /etc/passwd without using serial.

The /etc/passwd- contained the following:

root:$1$y3A1TsGe$n7RvgOkNPb1PhGPGnh9v5.:0:0::/root:/bin/sh

There are a lot of references to Justin and paths like /home/zhangxq/

Since you can get Server.tar.xz and there is wget, you can modify Server.tar.xz and replace modified version via wget, which opens to plenty of possibilities.

root password is hkvision888

Hikvision applied shotgun to the foot and squeezed the trigger

$
0
0

I guess I will not be recommending Hikvision any more to anyone.

Here is why:
http://www.hikvision.co.uk/faq_80.html
https://goo.gl/2uTtHk

So in short, Hikvision decided to only sell their cameras to authorized installers. The same installers that want $800 for $80 camera.
Well guess what, screw you Hikvision this is not pre-internet era where greedy corporation can dictate what is happening on the market.
I guarantee that this move will not curb prevalence of Chinese sourced cameras on ebay and aliexpress.
Granted this only affects UK and EU. I think this is just a beginning.

I personally will not be buying Hikvision and will definitely advising against buying Hikvision (be that from authorized rip-off artists or aliexpress).

As a company you should not screw with enthusiasts, as the same enthusiasts will be making purchasing decisions for their employers, and you will be losing many million of dollars at the end of the day. I am glad we went with Dahua.

Here is the full spiel:

August 2017

To Our Valued Customers,

As is well known, professional HIKVISION products are highly technical devices that require substantial product knowledge for the best possible system design, installation, support, and maintenance that our customers and end users deserve. Unfortunately, a large amount of products now are acquired from unauthorized channels and are not valid, up to date, or genuine HIKVISION products and accessories with qualified warranty or technical support.

For your protection, and to ensure you receive the best advice, technical support, and genuine HIKVISION products and accessories, HIKVISON is proceeding to build the selective distribution program in EU and UK (hereinafter referred as “HIKVISION Selective Distribution Program”), a new way different from generally intensive and exclusive distribution.

For HIKVISION Selective Distribution Program, HIKVSION establishes a set of criteria for authorized distributors (hereinafter referred as “Authorized Wholesalers”)and authorized system integrators/installers (hereinafter referred as “AuthorizedSystem Integrators/Installers”)(“Authorized Wholesalers” and “Authorized System Integrators/Installers” together referred as “Authorized Partners”), who are required to meet certain criteria and responsibilities mandated by HIKVISION. This includes not limited to the establishment and maintenance of the service staff, facilities, plant and equipment at one or more locations suitable for the satisfactory maintenance and repair of the HIKVISION Products. In other words, only the one who meet the relevant criteria can be the Authorized Partners, which HIKVISON products can only be bought and sold by, including online and offline. And the Authorized Wholesaler will only operate at the wholesale level of trade, and shall not sell the Products to end-users and the Authorized System Integrator/Installer will sell the HIKVISION Products to end-users at the retail level.

When becoming an Authorized Partner, you are able to leverage the HIKVISION partner portal, comprehensive multi-year warranty, and online project registration program. Also, you will have access to HIKVISON pre-sales support for sales questions, configuration and design assistance for the registered projects.

HIKVISION Selective Distribution Program will protect Authorized Partners that have invested the time and resources into becoming and maintaining their authorized status and in being knowledgeable in HIKVISION products to provide the best products choices to protect our customers.

Vendors who fail to meet its criteria or violate HIKVISION Selective Distribution Program by selling products to the unauthorized wholesalers/system integrators/installers after prior notification by HIKVISION are automatically moved to the Unauthorized Wholesalers/Systems Integrators/Installers.

To be our Authorized Partners, please contactus for complete criteria.

For more questions about this Program,please feel free to contact us at sales.uk@hikvision.com

ILDVR INC-MH40D06

$
0
0

ILDVR INC-MH40D06

Attention: before you read all this, see this post!

A 4MP dome IP camera (this particular has 2.8mm lens) ordered from ildvr.com, somewhat unknown company between western IP camera enthusiasts (although it is known in Russian circles). I have stumbled up when researching new cameras on some Russian website.

Made an enquiry on ildvr.com expecting to have usual “go away” response (as in: “contact our useless resellers, that will not sell you anyway”). To my surprise I got a very quick reply with all my questioned answered.

The retail price of this camera is around $100USD (they charge extra for their windows software, in which I was not interested).

From hardware perspective this camera is similar to Dahua IPC-HDBW4300E.

It has metal construction with plastic dome. Biggest difference is that the Dahua has PoE circuit on the base, while ILDVR has it on the camera body.

The camera came in a cubic box which contained another box padded by thin layer of foam. One issue with packaging I had is that the bag containing the mounting screws was not sealed properly and spilled the screws. One of the screws managed to leave a scratch on the dome. This scratch is not a huge issue is that it is unlikely it will ever be in field of view.

INC-MH40D06_box

INC-MH40D06_box1

The warranty sticker is a nice touch:
INC-MH40D06_box2

INC-MH40D06_box3

The ILDVR letters are bunch of stickers (I will probably remove them as they are a bit tacky):
INC-MH40D06_camera

Second warranty sticker on camera itself:
INC-MH40D06_camera1

INC-MH40D06_camera2

Note the string preventing the dome from falling. The screws are also captive and of torx type (a bit nicer than usual hex screws).
INC-MH40D06_camera3

INC-MH40D06_camera4

A close up of the scratch (nothing to really worry about):
INC-MH40D06_scratch

The box contained a Torx “L” wrench, template, mounting screws/dowels and ethernet jack seal kit.
Note: there was no CD (normally containing crappy windows software) or manual.

An interesting feature is the ethernet status LEDs on the connector:
INC-MH40D06_jack

The cable itself is about 40cm long.

Technical details

Most of this stuff I discovered poking around while waiting for technical details from ILDVR.
I will fill in once I have more details.

With no help from ILDVR I managed to get shell on it.

ARMv7 Processor rev 5 (v7l)
128MB RAM
16MB Flash (MX25L128XX)

/proc/cpuinfo

Processor       : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 1196.85
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

Hardware        : hi3516a
Revision        : 0000
Serial          : 0000000000000000

free -m

             total         used         free       shared      buffers
Mem:           121           64           57            0            0
-/+ buffers:                 64           57
Swap:            0            0            0

load hovers around 3 (less than Dahua and Hikvision).

uname -a

Linux ipc 3.4.35 #5 Fri May 8 10:31:07 CST 2015 armv7l GNU/Linux

df -h

Filesystem                Size      Used Available Use% Mounted on
/dev/root                 2.0M      2.0M         0 100% /
tmpfs                    30.0M     19.9M     10.1M  66% /dev
tmpfs                    30.0M     19.9M     10.1M  66% /tmp
tmpfs                    30.0M     19.9M     10.1M  66% /dev
tmpfs                    30.0M     19.9M     10.1M  66% /var
tmpfs                    30.0M     19.9M     10.1M  66% /tmp
tmpfs                    30.0M     19.9M     10.1M  66% /dev
tmpfs                    30.0M     19.9M     10.1M  66% /var
/dev/mtdblock3           11.0M      8.5M      2.5M  77% /mnt/flash
tmpfs                    30.0M     19.9M     10.1M  66% /mnt/flash/Server
tmpfs                    30.0M     19.9M     10.1M  66% /usr/lib
tmpfs                    30.0M     19.9M     10.1M  66% /etc
tmpfs                    30.0M     19.9M     10.1M  66% /root

cat /mnt/flash/productinfo/deviceid.txt

DEVICEID V6202IR-OV4689

I found actual manufacturer of the board:
http://www.hankvision.com/chanpin/wangluomozu/512.html

In case link goes away here is the screenshot:
hankvision_HC-9402A

They claim it is Hi3516D chipset.

The webUI.

Default username and password is admin.
I was hoping for a more modern interface, the one without ActiveX/Windows only crap…
As usual the viewer is useless without ActiveX plugin, even if mjpeg is selected there is a bug where it only shows two frames.
The Video and Camera settings are useless again due lack of plugin.
This webUI is on par on crappiness with Hikvision and Dahua.
One day we will have platform independent HTML5 interface… I hope.

Epic fail with activeX:
ildvr_activeX_crap

ildvr_camera_settings_plugin_fail

MJPEG stream preview is a bit buggy (not really visible here):
ildvr_mjpeg_fail

Various settings:
ildvr_settings_page

ildvr_video_settings

The most important feature that is missing is Telnet/SSH control (I would rather turn off Telnet). The telnet is on all the time (I have enquired about telnet access).
There is also no control regarding password protecting streams.

It took me a while to figure out the streams, due to misleading Dahua style URL working somewhat. This will work rtsp://192.168.1.200:554/cam/realmonitor?channel=0&subtype=0 but it disregards the channel or subtype selection and only gives sub stream (“minor” in ILDVR terms). That URL is not correct.
Below are correct urls (I lifted them off the javascript in the webUI).

Main stream (aka “major”):

rtsp://192.168.1.200:554/1/h264major

Sub stream (aka “minor”):

rtsp://192.168.1.200:554/1/h264minor

Snapshot URL:

http://admin:admin@192.168.1.200/jpgimage/1/image.jpg

Not sure what is the correct URL for mjpeg stream…

Interesting that the camera supports H265/HEVC. I am yet to test it (need to compile ffmpeg with h265 support).

The resolution selection goes all the way up to 2592×1944 (“2K”) on the “major” stream.

As typical there are stream errors with UDP stream (TCP stream is OK).

In general Web UI is very crappy and not tailored to the camera. It does not even get the camera model correctly.
There is a special clause in javascript for hi3518E chip (for whatever reason?).

I have spent a few hours pocking around the camera I noticed a few issues with webUI. I could crash (in a minor way) the camera with malformed fields when setting the time (via curl POST) as the validation happens in the javascript.
The smtp,ftp and alarm settings don’t work. The motion detect is useless without ftp/smtp or alarm settings.

The following quirks I found:

/form/, /cgi/ and /cgi-bin/ are all the same paths.
There is a “form” validation which does not allow arbitrary /cgi-bin/ script execution.
The simple path traversal exploit does not work.
Various little hack failed (command execution, remote inclusion, etc.), but I haven’t tried hard enough (I don’t normally hack things).
Any URL ending with image.jpg will result of attempting to get a snapshot from camera.
The ones that dont match jpgimage/1/image.jpg result in following output:

HTTP/1.0 200 OK
Content-Type: text/html

Image error

 

This potentially could be exploited (I don’t know how yet).

A lot of validation is happening in javascript. It is possible to set IP address, create username or almost any other field to any test string. I am currently trying to exploit this “feature”.

There are also a few places in javascript that has hard-coded “admin/admin” username and password:

document.getElementById("replay").SetLoginParam(srcIP,'admin','admin');		//justin changed 2013.6.27
document.getElementById("replay").SetLoginParamEx(srcIP,'admin','admin',$("#httpPort").val(),$("#rtspPort").val());		//2014.04.12

and:

player.RunPlayEx(ipAddr.toString(),0,"0.0.0.0",2,90,0,"admin","admin");

 

There are a lot of references to “justin” all over the place.

The onvif located at http://192.168.1.200:8999/onvif/
The onvif is not password protected!!!! (I can add remove users, reboot camera, change passwords, etc).

The server headers are very similar to Hikvision (only it is “Hankvision”, lol WTF?):

HTTP/1.1 200 Data follows
Server: Hankvision-Webs
Date: Thu Dec 24 12:44:27 2015
Pragma: no-cache
Cache-Control: no-cache
Content-Type: text/html

 

Digging more around I found that OMEGA-21P22-12 has same firmware (I googled the firmware version number out of desperation).

Basically I am thinking of getting serial port hooked up the board as the manufacturer is silent regarding telnet/shell access and I do not trust this firmware at all.

Here are the innards (the simplest way to remove the board is to unclip IR cover from front using two clips on the side):

INC-MH40D06_module_back

PoE module:
INC-MH40D06_PoE

SoC board (unfortunately cannot tell the model of SoC due to heatsink, looks like Hisilicon, possibly Hi3516D):
INC-MH40D06_SoC

Lens:
INC-MH40D06_lens

Sensor (I assume it is OV4689):
INC-MH40D06_sensor

Conclusion.

It started all promising (communication, pricing and delivery). Hardware is great. Firmware is the show stopper.

I am thinking of putting off buying ILDVR cameras due to “secrecy” regarding firmware and telnet access (not unless I can flash them with generic Hivision firmware).

I’ll probably stick to Dahua, as at least I have shell access on those (and I can hack firmware to fix/address whatever issues arise). Even though Dahua does not want to deal with me directly…

Update: I managed to get shell on it, more info here.

Viewing all 24 articles
Browse latest View live