Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support models that expect a different IP and filename #3

Open
hunsheridan opened this issue Nov 7, 2017 · 15 comments
Open

support models that expect a different IP and filename #3

hunsheridan opened this issue Nov 7, 2017 · 15 comments

Comments

@hunsheridan
Copy link

Hey,
First of all, thank you for taking the time to develop this. I very, very much appreciate it... I was very relieved when I found it. :)

I'm trying to de-brick a hikvision DS-7608HI-ST/A for a friend. He tried to upgrade the thing, and... you know, the old story, he ended up installing the bad firmware version. Anyway...
I read on forums that it's possible to do this (upload a correct firmware file) via TFTP.
I use Fedora. I followed the - very simple - instructions given, also disabled my firewall to make sure all is working properly.
Current interface configuration:

enp0s31f6:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.0.0.128  netmask 255.255.255.0  broadcast 192.0.0.255
        ether 1c:1b:0d:82:64:89  txqueuelen 1000  (Ethernet)
        device interrupt 16  memory 0xdf000000-df020000

So I connected the device to my LAN swtich (tried direct also!), powered the device on, and waited for something to happen...
Well, nothing really does happen. I started the python script like so:

[root@raptor hikvision-tftpd]# ./hikvision_tftpd.py
Serving 26066596-byte digicap.dav (block size 512, 50912 blocks)

... but nothing happens - it's just sitting there, even after many reboots, turnoffs, etc...
All I can see is that the RX/TX lights on my switch are blinking somewhat, there's definitely a correct link on the port... but nothing else.

I really don't mean to abuse your helpfulness, and I realize that this problem may or may not have to do anything at all with the tool you wrote - but could you give me a hint as to what may be wrong? Frankly, I'm at a loss here.

Thank you so much for any help you could give me.

Levente

@scottlamb
Copy link
Owner

I use Wireshark to investigate problems like this. It shows raw packets going over the Ethernet interface, so you can see if the device is simply not sending anything, if it expects a different address than the ones I tried my software with, etc.

Now, there's usually tons of activity over the network, so you might want to plug in only your computer and the device in question to not see as much irrelevant stuff (you still might see some from your computer itself as it looks for other things on the network), or you might want to use a packet filter expression.

If you know the MAC of the device (a 12-hexadigit number, usually written as six groups of two separated by colons or hyphens), you could filter based on that. It's usually physically written on a label on the device. The packet filter expression would look something like ether host 12:34:56:78:9a.

Otherwise, here are a few specific types of packets that are likely to be of interest:

  • ARP packets might show you that it's alive: ether proto 0x0806
  • Anything to or from the ports I know they use: port 69 or port 9978 or port 9979
  • Any DHCP traffic might be interesting too: port 67 or port 68

If you can get a packet capture, I can probably help you interpret it.

@hunsheridan
Copy link
Author

Hey there, thank you so much for trying to help me!
OK so this is what I have done so far...
First I tried to catch ARP chatter. I have success on that front, here's what's happening:
Every time I turn on the device theese two rows appear on a - filtered down - tcpdump session:

[root@raptor ~]# tcpdump -i enp0s31f6 -vv -e -nn ether proto 0x0806
tcpdump: listening on enp0s31f6, link-type EN10MB (Ethernet), capture size 262144 bytes
16:21:58.804425 28:57:be:8a:aa:53 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 172.9.18.80 tell 172.9.18.100, length 46
16:22:00.805251 28:57:be:8a:aa:53 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 172.9.18.80 tell 172.9.18.100, length 46

Then I tried to look for packets for specific ports or DHCP chatter, but came up empty on that front...
So then I figure what the heck, I should try and use those IP-s... it's obviously looking for 172.9.18.80 and it's IP seem like .100, so I rewrote the IP in the tftp code to .80...
And then this is what I see... the last line repeats "forever"... looks like it's not really what the script expects, but beyond that...

[root@raptor hikvision-tftpd]# ./hikvision_tftpd.py
Serving 26066596-byte digicap.dav (block size 512, 50912 blocks)
Wed Nov  8 16:35:33 2017: Replied to magic handshake request.
Wed Nov  8 16:35:33 2017: Replied to magic handshake request.                
Wed Nov  8 16:35:33 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091         
Wed Nov  8 16:35:38 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091         
Wed Nov  8 16:35:43 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091
Wed Nov  8 16:35:48 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091
Wed Nov  8 16:35:53 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091
Wed Nov  8 16:35:58 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091
Wed Nov  8 16:36:03 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091
Wed Nov  8 16:36:08 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091
Wed Nov  8 16:36:13 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091
Wed Nov  8 16:36:18 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091
Wed Nov  8 16:36:23 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091
Wed Nov  8 16:36:28 2017: received unexpected bytes '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800' from 172.9.18.100:2091

@hunsheridan
Copy link
Author

WHOOPS! :-)
On a gut feeling I tried the procedure with the 2007 Hikvision TFTP server tool inside a Windows 7 Virtualbox VM...
It responded on that funky IP, and it managed to upload the digicap.mav file... then I waited for 10 minutes, but it didn't say that upgrade completed, so I just restarted the hardware.
Now I'm looking at a screen that asks the password. Looks like it's going to work this way somehow... :-)
Altough the device does give out a beep like: "---.." (three long and two short).
Anyway just wanted to let you know... this is where I am now.
Will send feedback if/when I actually succeed to set it up. :-)

@hunsheridan
Copy link
Author

AND IT WORKS!!!!! :-))))
I have web access and everything else... seems like it's OK now.
Friend! Thank you so much for your help!!! You pointed me in the right direction to find out the IP address.
If I can do anything to help you, please do not hesitate.
Best wishes to you and friendly cheers from Hungary! :-)))
Levente

@scottlamb
Copy link
Owner

I'm glad you got it working.

If you're able, could you get a packet capture of the successful procedure with the Hikvision tool? I'd like to see what it's doing so I can match it.

fwiw, the "unexpected bytes" are these:

>>> '0001646967696361702e6d6176006f637465740074696d656f7574003500626c6b73697a65003134363800'.decode('hex')
'\x00\x01digicap.mav\x00octet\x00timeout\x005\x00blksize\x001468\x00'

which looks like TFTP options as specified in RFC 2347 and RFC 2348, but in standard TFTP they'd be part of a request on the TFTP port. Here they're apparently on their own and sent to Hikvision's weird handshake port.

@scottlamb
Copy link
Owner

Also, do those addresses 172.9.18.100 and 172.9.18.80 match any configuration of your network or your friend's network? I'm guessing not, as whois -h whois.arin.net 172.9.18.100 says they belong to AT&T Internet Services (a major US ISP), pretty far from Hungary...

@hunsheridan
Copy link
Author

Ah dang, I gave it back to him before I went to bed last night.
Okay, I can still do this for you. Next week, he's coming around again, I'll ask him to bring it with him.
We'll do a backup and repeat the procedure with tcpdump running. I'll get you your capture :-)
And no, like you suspect, those IP-s are nowhere near what any of us uses locally.
So, anyway, I don't know yet on which specific day, but I'll do the capture next week and post it to you! :-)

@scottlamb
Copy link
Owner

No worries. I think now I misread that "unexpected bytes" line. I actually log that two places in my code, so it could have been either on the "handshake" socket or the TFTP socket, and the latter makes more sense. It looks like it's a valid request but for the filename digicap.mav rather than digicap.dav. I found some documentation suggesting that some models expect one filename; some expect the other.

I'll add a couple things to my TODO list:

  • configurable IP address
  • support either digicap.dav or digicap.mav

Maybe we can see if my program works on this model with those changes.

@hunsheridan
Copy link
Author

That sounds terrific! :-) In fact...
What if, apart from making the change as to the filenames, you could create some sort of "autodetection" for the IP address in the long run?
For example... you could start the program with a flag, like "--auto-ip eth0", then it would start listening for the ARP calls. Then at first boot the ARP calls are recognised, then the program would ask for a confirmation maybe. Then create a temporary alias on the specified NIC, configure for the IP, and request the user to reboot the device again. Then on second attempt it would do the transfer, then upon exiting the program, it would dispose of the NIC alias.
This would definitely work reliably when connected directly, but if you add an option to manually filter for given MAC address of the device (optional) then it would be OK for a switched environment also.
Further... if the MAC has a specific signature to look for (like vendor id maybe?) then autodetect wouldn't necessarily require specifying the MAC even in a switched setting - it would just look for the right vendor? But that sounds less reliable and would almost certainly need some kind of database maintenance as new models come out.
Also, even if it doesn't configure the alias interface or recognise the MAC automatically, some "autodetection" feature like that to ease manual setup would be great I think.

@scottlamb
Copy link
Owner

Yeah, that'd be a lot slicker. I wonder if the official Hikvision TFTP server is doing something like that. One caveat is that I think raw packet interfaces are a lot less portable; right now the same code works on Linux, OS X, and (according to #1; I haven't tried it) Windows. Probably other systems too.

For now, I just made the changes I described and mentioned them in the documentation.

@scottlamb scottlamb changed the title Not connecting support models that expect a different IP and filename Nov 9, 2017
@hunsheridan
Copy link
Author

Nice!

From observation I can tell that the original Hikvision server probably just picks up and uses whatever IP the active interface has and uses that for listening on. At least this is how it seems to work. (I tried several random IP-s just now under the VM).

Also I agree.. that autodetect feature would be much less portable... And looks like Hikvision's design also simply leaves to the user to set up the networking (and the IP) as they see fit and adjusts to that.

Still, portability aside, the issue of unknown initiator IP is a real problem as I experienced first hand. I wonder... How else could the procedure of finding an unknown device IP be made easier on a non tech-savvy end user, without damaging portability too much? Hm...

Well, next week as I said, I'll be seeing that device again... can't wait to test! :-)

@scottlamb
Copy link
Owner

fwiw, If I did recognize MACs (through any of the methods you mentioned: database of Hikvision OUIs, commandline flag, or interactively) and use raw packets, it wouldn't be too hard to skip the IP layer setup entirely. Listen for the ARPs on the raw socket and send a reply myself saying I have whatever IP they're looking for. Then listen for UDP packets on the raw socket and send a reply from whatever IP address they sent it to back to whatever IP address they mentioned they had.

@scottlamb
Copy link
Owner

Another advantage of doing that would be that you could upgrade a bunch of devices at once, even ones that require different firmware. Through a config file or interactively, you could select what firmware to use for each MAC, and it'd work even if they're all using the same IP at once.

@hunsheridan
Copy link
Author

Now THAT's just wicked! :-))) I'm not sure even Hikvision's tools can do this.

@scottlamb
Copy link
Owner

It turns out that libpcap makes the raw packet stuff easy to do portably. There are two catches, though:

  • Basically no one has the Python interface to that installed on their system, or even the C header files. I don't want to complicate installation. Probably best if I switch to a compiled language (I prefer Rust or Go) so I could release a binary that Just Works as the Python script does now.
  • The user interface problem seems trickier. I can imagine a text-based user interface based on Rust's tui or some such, but designing it is a bit of work. It'd need to do stuff like allowing you to select which device to flash, probably disabling flashing that device again after a transfer completes (to not be in a loop forever), etc. Definitely possibly but some care required.

I don't think I have time to do anything like that right now. Maybe some day...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants