Jump to content
Allodo

Dahua VTO2000A, SIP Firmware and Asterisk

Recommended Posts

Ok, here we go. These instructions are based on a Debian 8 system. But this should work on most distributions i guess, only the package installation will be different.

You must have root rights for this to work !

 

  1. Install Python 3:
    apt install python3


  2. Install needed tools for next steps:
    apt install build-essential wget unzip cramfsprogs u-boot-tools squashfs-tools


  3. IMPORTANT: Install modified squashfs3 tools as our old VTO Linux kernel does not support squashfs4 (that is how you can easily brick your VTO)
    cd
    wget https://github.com/BotoX/squashfs-tools/archive/v3.4.zip
    unzip v3.4.zip
    cd squashfs-tools-3.4/squashfs-tools
    make install
    


  4. Download the firmware-mod-tools:
    cd
    wget https://github.com/BotoX/Dahua-Firmware-Mod-Kit/archive/master.zip
    unzip master.zip


  5. Extract / Unpack the firmware. Be sure the extract script says "WARNING Autodetected config: VTO":
    cd Dahua-Firmware-Mod-Kit-master
    cp ~/General_VTO2000A_Eng_P_16M_SIP_V1.200.1000.0.R.20160505.bin .    <------ copy your img file into this directory, this line must of course be adapted
    ./extract.py General_VTO2000A_Eng_P_16M_SIP_V1.200.1000.0.R.20160505.bin
    


  6. Make your modifications. Sound files for example are in General_VTO2000A_Eng_P_16M_SIP_V1.200.1000.0.R.20160505.bin.extracted/data-x.cramfs.img.extracted/Sounds
  7. Go back to Dahua-Firmware-Mod-Kit-master root folder. If you followed step by step it should be in your home directory:
    cd ~/Dahua-Firmware-Mod-Kit-master


  8. Repack the firmware. Be sure the build script says "WARNING Autodetected config: VTO":
    ./build.py General_VTO2000A_Eng_P_16M_SIP_V1.200.1000.0.R.20160505.bin.extracted


  9. The newly packed firmware is now in the General_VTO2000A_Eng_P_16M_SIP_V1.200.1000.0.R.20160505.bin.extracted/build subdirectory:
    cd General_VTO2000A_Eng_P_16M_SIP_V1.200.1000.0.R.20160505.bin.extracted/build
    ls -la
    
    drwxr-xr-x 2 root root     4096 Oct 17 17:59 .
    drwxr-xr-x 9 root root     4096 Oct 17 17:59 ..
    -rw-r--r-- 1 root root    12352 Oct 17 17:59 custom-x.cramfs.img
    -rw-r--r-- 1 root root    12288 Oct 17 17:59 custom-x.cramfs.img.raw
    -rw-r--r-- 1 root root   901184 Oct 17 17:59 data-x.cramfs.img
    -rw-r--r-- 1 root root   901120 Oct 17 17:59 data-x.cramfs.img.raw
    -rw-r--r-- 1 root root   255584 Oct 17 17:59 dm365_ubl_boot_16M.bin.img
    -rw-r--r-- 1 root root 13073267 Oct 17 17:59 General_VTO2000A_Eng_P_16M_SIP_V1.200.1000.0.R.20160505.bin       <----------------
    -rw-r--r-- 1 root root      467 Oct 17 17:59 Install
    -rw-r--r-- 1 root root  1686604 Oct 17 17:59 kernel-x.cramfs.img
    -rw-r--r-- 1 root root    45120 Oct 17 17:59 pd-x.cramfs.img
    -rw-r--r-- 1 root root    45056 Oct 17 17:59 pd-x.cramfs.img.raw
    -rw-r--r-- 1 root root  3117120 Oct 17 17:59 romfs-x.cramfs.img
    -rw-r--r-- 1 root root  3117056 Oct 17 17:59 romfs-x.cramfs.img.raw
    -rw-r--r-- 1 root root  5857344 Oct 17 17:59 user-x.cramfs.img
    -rw-r--r-- 1 root root  5857280 Oct 17 17:59 user-x.cramfs.img.raw
    -rw-r--r-- 1 root root  1441856 Oct 17 17:59 web-x.cramfs.img
    -rw-r--r-- 1 root root  1441792 Oct 17 17:59 web-x.cramfs.img.raw
    

That's it. This should work .....

 

Flash it and light a candle before rebooting

 

edit1: added mkimage

edit2: added squashfs-tools

edit3: added info about config file autodetection

 

Serge

Edited by Guest

Share this post


Link to post
Share on other sites

Hello Serge!

 

Big, very Big thank you!!!

Great work!

 

Greetings,

Julian

 

P.S. By me, he don't found mkimage, so installed addtitionaly u-boot-tools. Is this correct?

And in /usr/loca/bin i found only unsquashfs3, but extract.py need unsquashfs, so i make symbilc link in /usr/local/bin for unsquashfs. The same for mksquashfs3 an mksquashfs. Is it ok?

 

Is it normal, that i become a slightly smaller file - about 718 bytes (without changes in the firmware - only repackaged)?

Share this post


Link to post
Share on other sites
P.S. By me, he don't found mkimage, so installed addtitionaly u-boot-tools. Is this correct?

Absolutely. Sorry, i forgot that one as it was already installed on my system. I updated the post. Thank you for this ons.

 

And in /usr/loca/bin i found only unsquashfs3, but extract.py need unsquashfs, so i make symbilc link in /usr/local/bin for unsquashfs. The same for mksquashfs3 an mksquashfs. Is it ok?

It probably is in your case and when using a VTO. But the right way is to install the squashfs-tools package. I also added that one to my previous post. Both tool versions have to be installed, the 3.4 and the 4.0 ones. The scripts pick the ones that it needs.

 

Is it normal, that i become a slightly smaller file - about 718 bytes (without changes in the firmware - only repackaged)?

Yes, this is probably due to newer zip version with better compression. I had the same.

 

One more thing: Be carefull when extracting and even more important when building that the script shows you the following line:

WARNING	Autodetected config: VTO

Share this post


Link to post
Share on other sites

Hello Serge!

 

Great! Thanks!!!

 

Edit 1: Can you explain me please, how it works wit the unsquashfs or better with the mksquashfs?

The squash tools 3.4 installs only a binary mksquashfs3 in /usr/local/bin. So when i start build.py he call mksquashfs and can't find it, because there is no mksquashfs (without 3 at the end) yet.

When we install the squash-tools package from debian he install mksquashfs, that can be used, but is in version 4. Is this not the wrong version? So how... and when build.py start the right one (v3)? I'm not sure that this is the case. So i'm very afraid yet to flash my VTO.

Maybe im thinking worng, but if we not make a manual symbolic link to mksquashfs3, he will use the new one? And will brick the VTO? Were i'm wrong.

 

Yes i saw, that here is variable with the Name Version in build.py and that this is added to the command String for mksquashfs at the end. But he calls further only mksquashfs and not mksquashfs3. Or is there other way to start in version 3?

I don't understand something. Excuse me.

Share this post


Link to post
Share on other sites
Can you explain me please, how it works wit the unsquashfs or better with the mksquashfs?

The squash tools 3.4 installs only a binary mksquashfs3 in /usr/local/bin. So when i start build.py he call mksquashfs and can't find it, because there is no mksquashfs (without 3 at the end) yet.

When we install the squash-tools package from debian he install mksquashfs, that can be used, but is in version 4. Is this not the wrong version? So how... and when build.py start the right one (v3)?

For the extract script all this is not important. The important part is that the new firmware is build with the right version, so let's only focus on build.py

The script checks if mksquashfs exists because at the beginning of the script it has the line

DEPENDENCIES = ["sudo", "mksquashfs", "mkimage"]

All these binaries must be there or else the script does exit with an error. Even though in our case the mksquashfs is not needed it still checks for it here:

def CheckDependencies(self):
   Ret = 0
   for dependency in self.DEPENDENCIES:
           if not distutils.spawn.find_executable(dependency):
                   self.Logger.error("Missing dependency: '%s'", dependency)
                   Ret = 1
   return Ret

Then the part where the magic you asked for happens:

        def Handle_SquashFS(self, Key):
[... not importand...]
               # Read SquashFS header to figure out compression and blocksize of the original file.
               OrigFile = open(OrigPath, "rb")
               Header = SquashFS.parseHeader(OrigFile)
               OrigFile.close()
[... not importand...]
               Version = "" if Header == 4 else str(Header["s_major"])
[... not importand...]
               Result = subprocess.call(["sudo", "mksquashfs" + Version, ExtractedDir, DestPath] + ConOpts)

If you try to understand the lines above you can see it does:

  1. Open the original squashfs file extracted previously
  2. Read the header and check if the squashfs version originaly was v3.4 or v4.0
  3. Write that in a variable called 'Version' which then is "3" if it was v3.4 and "" (empty) if it was v4
  4. It calls the mksquashfs binary and appends the previously set 'Version' variable which is 3 or

Was my explanation clear ? If not just tell me where it was not and i will try to edit it.

Share this post


Link to post
Share on other sites

Hey !!! I am able to unlock my door via my SIP phones !!!

 

Here is an example of how i configured my VTO (8801), my xLite Softphone and my SIP trunk (fritzbox). I can open the door with xlite and with my IP phones connected to my fritz!box. I am 99,99% sure the magic is done by the "dtmfmode=info" statement in my VTO configuration (8001). After pushing 55 (the unlock code i defined in VTO webgui) it takes about 3 seconds before i hear the relay clicking and the "The door is unlocked" mp3 ...

 

[fritzbox]
type=peer
qualify=yes
nat=no
secret=xxxxxxxx
username=626
host=fritz.box
dtmfmode=rfc2833
insecure=port,invite
fromuser=626
fromdomain=fritz.box
context=incoming

[xlite]
type=friend
host=dynamic
secret=xxxxxxxx
context=users
deny=0.0.0.0/0
permit=192.168.1.0/16

[8001]
type=friend
host=dynamic
pedantic=no
username=8001
callerid=Türklingel
secret=xxxxxxxx
dtmfmode=info
context=users
disallow=all
allow=ulaw
allow=h264

Share this post


Link to post
Share on other sites

Hello Serge!

 

Thank you for the mksquashfs statement. So if correct understand, the only reason to install squashfs-tools is that build.py can find the prerequisite file at start (mksquashfs)?

I see.... ok, then symbolic sholud be fully OK and not neccesary to install the tools.

 

I was not 100% sure, that Version is really set to 3 in build.py...

But now i can sleep quiet.

 

Thank You!

Share this post


Link to post
Share on other sites
I was not 100% sure, that Version is really set to 3 in build.py...

But now i can sleep quiet.

If you want to sleep really quiet just double check. cd into the build directory on use the file command on the img.raw file like so:

serge@srvdevel:~/Dahua-Firmware-Mod-Kit/General_VTO2000A_Eng_P_16M_SIP_V1.200.1000.0.R.20160505.bin.extracted/build$ file user-x.cramfs.img.raw 
user-x.cramfs.img.raw: Squashfs filesystem, little endian, version 3.1, 5856508 bytes, 197 inodes, blocksize: 131072 bytes, created: Tue Oct 18 07:40:14 2016

Here you can clearly see that the build file is in squashfs 3.1 format and not in the 4 format.

Share this post


Link to post
Share on other sites
After pushing 55 (the unlock code i defined in VTO webgui) it takes about 3 seconds before i hear the relay clicking

 

Yes, i can confirm that. And this 3 sec. are logical: the VTO is waiting to see if there will folow more Key input and so far there no any more, he evaluate the input - in your case 55, in my 123.

 

Thanks!

Share this post


Link to post
Share on other sites
With my old legacy doorbell i have it configured that whenever someone rings i get a Prowl Notification on my iPhone. When i'll put my VTO into production i want a message with a picture (Snapshot) on my iPhone. I don't know yet how i will transfer that picture. Maybe Whatsapp or Telegram.

Hello Serge!

 

I tested some with Pushbullet on my Android Xperia M4. So far i now, Pushbullet works with iPhone too.

He can send not only Notes per Push - he can send Files (Pictures) too. It is a little bit complicated, than Notes, but it works perfect. And Pushbullet is for free if you don't need Support.

 

Here is a call how to send a Note:

#!/bin/bash

API="API-Key kommt hier rein"
MSG="$1"

curl -u $API: https://api.pushbullet.com/v2/pushes -d device_iden="iden-code wohin die Nachricht gehen soll" -d type=note -d title="Alert from Pi" -d body="$MSG"

More or less from here: https://jankarres.de/2014/03/raspberry-pi-push-benachrichtigung-bei-ssh-anmeldung/

 

Here is a Script to Send a files:

 #!/usr/bin/perl

use JSON;
use LWP::UserAgent;

# credentials and device identifier

my $api_key  = 'XXXXXXXXXXXXXXXXXXXXXXXXXXX';
my $password = 'XXXXXXXX'; # for what?!?!?
my $device   = 'XXXXXXXXXXXXXX';  # iden-code come here

# file to send

my $file_name = 'image.png';
my $file_type = 'image/png';

my $user_agent = LWP::UserAgent->new();
$user_agent->agent('My File Pusher v1.0');

# Send a request for authorisation to upload a file ..

my $request_response =  $user_agent->post('https://api.pushbullet.com/v2/upload-request',
                                         'Authorization' => 'Bearer '.$api_key,
                                         'Content'       => ['file_name' => $file_name,
                                                             'file_type' => $file_type]);

if ($request_response->is_success) {

 # no obvious error from the server, parse the JSON ..

 my $json = from_json($request_response->content);

 if ($json->{'upload_url'}) {

   # we have an end point to push to and we can upload the file

   my @data;

   # the order of these fields is important, AWS will cry if you don't respect the ordering!!

   foreach my $item ('awsaccesskeyid', 'acl', 'key', 'signature', 'policy', 'content-type') {

     push(@data, $item => $json->{'data'}->{$item})
   }

   # and add the file

   push(@data, 'file' => [ $file_name ]);

   # now attempt to upload the file

   my $upload_response = $user_agent->post($json->{'upload_url'},
                                           'Content_Type' => 'form-data',
                                           'Content'      => \@data);

   if ($upload_response->is_success) {

     # looks like we uploaded the file successfully
     # so now send the actual push to the device

     my $push_response = $user_agent->post('https://api.pushbullet.com/v2/pushes',
                                           'Authorization' => 'Bearer '.$api_key,
                                           'Content-Type'  => 'application/json',
                                           'Content'       => to_json({'device_iden' => $device,
                                                                       'type'        => 'file',
                                                                       'file_name'   => $json->{'file_name'},
                                                                       'file_type'   => $json->{'file_type'},
                                                                       'file_url'    => $json->{'file_url'}}));

     if ($push_response->is_success) {

       print "Pushed OK!\n";
     }
     else {

       print "Push failed!\n";
     }
   }
 }
}

Source:

 

May be it works for you?

 

Greetings

 

Edit: I'm using Pushbullet to send a Note with a Key-Word. Under Android i have the App TASKER which looks what for Notes came in per Pushbullet. When he see the Keyword he start by me IP Cam Viewer App. But it should work by you without Tasker an only with a Picture too.

Simple sends of Pictures per script (from here) from my Raspberry to Sony M4 works perfect. Delay is not more then 1-2 sec., but it depends of course on the internet connection. When no connection, Push comes later, when connection is reestablished.

Share this post


Link to post
Share on other sites

Danke !

 

I will have a lock when i have time. For now i have telegram working. As soon as everything works i will try to tune and tweak.

 

I think i have nearly everything working i wanted:

  • Phones on Fritz!Box, Asterisk soft-phones and our 2 GSM phones are ringing all together when someone rings the doorbell
  • On my soft-phone apps (linphone) i see live video
  • I can now open the door with '55'
  • I get a picture via telegram to our two GSM phones
  • I have modified these horrible pseudo-english mp3's

 

Is there something still missing that makes sense ?

Share this post


Link to post
Share on other sites
Hey !!! I am able to unlock my door via my SIP phones !!!

 

Here is an example of how i configured my VTO (8801), my xLite Softphone and my SIP trunk (fritzbox). I can open the door with xlite and with my IP phones connected to my fritz!box. I am 99,99% sure the magic is done by the "dtmfmode=info" statement in my VTO configuration (8001). After pushing 55 (the unlock code i defined in VTO webgui) it takes about 3 seconds before i hear the relay clicking and the "The door is unlocked" mp3 ...

 

[fritzbox]
type=peer
qualify=yes
nat=no
secret=xxxxxxxx
username=626
host=fritz.box
dtmfmode=rfc2833
insecure=port,invite
fromuser=626
fromdomain=fritz.box
context=incoming

[xlite]
type=friend
host=dynamic
secret=xxxxxxxx
context=users
deny=0.0.0.0/0
permit=192.168.1.0/16

[8001]
type=friend
host=dynamic
pedantic=no
username=8001
callerid=Türklingel
secret=xxxxxxxx
dtmfmode=info
context=users
disallow=all
allow=ulaw
allow=h264

This would be great if I could get it working on my end.

 

My VTO is configured as following with FreePBX. I changed DTMF mode as you suggested, but still couldn't get it to unlock. The VTO is still set to the default Open Door Command of 123. I pressed those keys during a call but the VTO did not seem to react.

 

Any ideas? Are there any other settings you had to change on the VTO? Thanks!

 

[8001]
deny=0.0.0.0/0.0.0.0
secret=xxxxxxxxxxxxxxxxxxxxx
dtmfmode=info
canreinvite=no
context=from-internal
host=dynamic
trustrpid=yes
sendrpid=no
type=friend
session-timers=accept
nat=force_rport,comedia
port=5060
qualify=yes
qualifyfreq=60
transport=udp
avpf=no
force_avp=no
icesupport=no
encryption=no
namedcallgroup=
namedpickupgroup=
dial=SIP/8001
permit=0.0.0.0/0.0.0.0
callerid=Doorbell <8001>
callcounter=yes

Share this post


Link to post
Share on other sites

Hello pkozul!

 

Please try to set dtmfmode=info on both sides - not only at the 8001.

The conversation from rfc2833 to info should work, but if the other side is set to inband (audio) then asterisk can not transfer the dtmf tone to info. It continous to came as sound at the VTO.

Do you hear the tone when you press the keys? If yes, then this is the case.

 

Or show us please you other DID, of the other side, i see here only the 8001.

 

Thanks!

Edited by Guest

Share this post


Link to post
Share on other sites

Yes please try what gerdshi said, or make sure the other end has dtmfmode=rfc2833

I have that line in my general section of my sip.conf afaicr

Share this post


Link to post
Share on other sites

Has anyone tried an Android App called Elcom Videofon? Not sure if it is available for iPhone too.

This app is made especially for an Intercom and has an button for unlocking the door. I think this is more comfortable to use with VTO, if it works

 

I've tried but get no Video on it. But I also had no Video on Linphone or any other Android App which seems to be an configuration problem on my side.

When I get my new VTO or maybe my old unbricked back, I will try. Till then I couldn't try anything

 

It is so fantastic what you have realized till now " title="Applause" /> " title="Applause" /> " title="Applause" />

Share this post


Link to post
Share on other sites

Hi!

 

Yes i tryed it, but become only audio and not video. The same like you.

At Asterisk i become the message unknown rtp codec 95. I think that Elcom use Mjpeg (for access as IP Camera?) and something other (VP8/9?) for SIP (Really?!).

The App is created from Zoiper for Elcom and it seems, that it is specialy developed for Elcom DoorPhone and Cameras.

 

May be i'm wrong, but i think i remember that codec 95 message occurs only if i set in the original Zoiper App the V9 Video-Codet to on.

 

Edit:

Ha.... here stay that 95 is unasigned.... Great

http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml

Share this post


Link to post
Share on other sites

Below are my settings. I set all my extensions to use DTMF mode 'info'. My VTO (extension 8001) rings extension 5000 which is a call group, and that call group dials extensions 8003, 8007, etc. During a call, I pressed 123 and could hear the tones, but the VTO did not show any signs of relay being activated and no voice indicating that the door is unlocked.

 

[5000]
deny=0.0.0.0/0.0.0.0
secret=xxxxxxxxxxx
dtmfmode=info
canreinvite=no
context=from-internal
host=dynamic
trustrpid=yes
sendrpid=no
type=friend
session-timers=accept
nat=force_rport,comedia
port=5060
qualify=yes
qualifyfreq=60
transport=udp
avpf=no
force_avp=no
icesupport=no
encryption=no
namedcallgroup=
namedpickupgroup=
dial=SIP/5000
permit=0.0.0.0/0.0.0.0
callerid=Doorbell ring group <5000>
callcounter=yes
faxdetect=no

[8001]
deny=0.0.0.0/0.0.0.0
secret=xxxxxxxxxxx
dtmfmode=info
canreinvite=no
context=from-internal
host=dynamic
trustrpid=yes
sendrpid=no
type=friend
session-timers=accept
nat=force_rport,comedia
port=5060
qualify=yes
qualifyfreq=60
transport=udp
avpf=no
force_avp=no
icesupport=no
encryption=no
namedcallgroup=
namedpickupgroup=
dial=SIP/8001
permit=0.0.0.0/0.0.0.0
callerid=Doorbell <8001>
callcounter=yes
faxdetect=no

[8003]
deny=0.0.0.0/0.0.0.0
secret=xxxxxxxxxxx
dtmfmode=info
canreinvite=no
context=from-internal
host=dynamic
trustrpid=yes
sendrpid=no
type=friend
session-timers=accept
nat=force_rport,comedia
port=5060
qualify=yes
qualifyfreq=60
transport=udp
avpf=no
force_avp=no
icesupport=no
encryption=no
namedcallgroup=
namedpickupgroup=
dial=SIP/8003
permit=0.0.0.0/0.0.0.0
callerid=Tetyana <8003>
callcounter=yes
faxdetect=no

[8007]
deny=0.0.0.0/0.0.0.0
secret=xxxxxxxxxxx
dtmfmode=info
canreinvite=no
context=from-internal
host=dynamic
trustrpid=yes
sendrpid=no
type=friend
session-timers=accept
nat=force_rport,comedia
port=5060
qualify=yes
qualifyfreq=60
transport=udp
avpf=no
force_avp=no
icesupport=no
encryption=no
namedcallgroup=
namedpickupgroup=
dial=SIP/8007
permit=0.0.0.0/0.0.0.0
callerid=Samsung Tablet <8007>
callcounter=yes
faxdetect=no

Share this post


Link to post
Share on other sites

Did you try setting your other phones explicitly to dtmfmode=rfc2833 ? I have all my phone in dtmfmode=rfc2833 except the VTO which is set to info.

Share this post


Link to post
Share on other sites
Did you try setting your other phones explicitly to dtmfmode=rfc2833 ? I have all my phone in dtmfmode=rfc2833 except the VTO which is set to info.

 

That was how I had it set originally, but today I also tried setting them all to info. I wonder if it's something to do with how FreePBX does things.

Share this post


Link to post
Share on other sites
That was how I had it set originally, but today I also tried setting them all to info. I wonder if it's something to do with how FreePBX does things.

Good question. I am more the 'vi sip.conf' guy

Share this post


Link to post
Share on other sites
That was how I had it set originally, but today I also tried setting them all to info. I wonder if it's something to do with how FreePBX does things.

Good question. I am more the 'vi sip.conf' guy

 

He he. I am considering the same. I probably should look at getting to the bare metal rather than relying on a web-based user interface to manage my Asterisk settings.

Share this post


Link to post
Share on other sites

Hi Guys,

 

I unpacked the sonia binary and read through the strings contained in the binary. By that way i found out a lot of commands of the http API that i want to share with you. I didn't test all commands, so some are probably not working. The firmware seems to be +/- the same for their cameras, so a lot of commands don't make sense on a doorbell. But one is particulary interesting: The one to get a snapshot of the camera.

 

To launch a command with the browser you have to type in:

http://{USERNAME}:{PASSWORD} @{CAMERA_IP}/{COMMAND}
example:
http://admin:admin@192.168.1.110/cgi-bin/snapshot.cgi

To use it form command line, for example to use in a script, use curl for example:

curl --user {USERNAME}:{PASSWORD} —digest http://{CAMERA_IP}/{COMMAND}
example:
curl --user admin:admin --digest http://192.168.2.10/cgi-bin/magicBox.cgi?action=getMachineName

Here's the list:


  • /cgi-bin/configFileExport.backup?action=All&sessionId=*
    /cgi-bin/Snapshot.cgi*
    /cgi-bin/audio.cgi?action=postAudio*
    /cgi-bin/*
    /cgi-bin/snapshot.cgi
    /cgi-bin/snapManager.cgi?action=attachFileProc
    /cgi-bin/eventManager.cgi?action=attach
    /cgi-bin/RPC_Loadfile
    /cgi-bin/loadfile.cgi?action=startLoad
    /cgi-bin/Config.backup?action=All
    /cgi-bin/Log.backup?action=All
    /cgi-bin/mjpg/video.cgi
    /cgi-bin/playBack.cgi?action=
    /cgi-bin/realmonitor.cgi?action=
    /cgi-bin/audio.cgi?action=getAudio
    /cgi-bin/deviceDiscovery.cgi?action=attach
    /cgi-bin/VideoTalkPeer.cgi?action=attachState
    /cgi-bin/configManager.cgi?action=getConfig
    /cgi-bin/configManager.cgi?action=setConfig
    /cgi-bin/configManager.cgi?action=restore
    /cgi-bin/userManager.cgi?action=getGroupInfo&
    /cgi-bin/userManager.cgi?action=getGroupInfoAll
    /cgi-bin/userManager.cgi?action=getUserInfo&
    /cgi-bin/userManager.cgi?action=getUserInfoAll
    /cgi-bin/userManager.cgi?action=getActiveUserInfoAll
    /cgi-bin/userManager.cgi?action=addUser
    /cgi-bin/userManager.cgi?action=deleteUser
    /cgi-bin/userManager.cgi?action=modifyUser
    /cgi-bin/userManager.cgi?action=modifyPassword
    /cgi-bin/ptz.cgi?action=start
    /cgi-bin/ptz.cgi?action=stop
    /cgi-bin/ptz.cgi?action=getProtocolList
    /cgi-bin/ptz.cgi?action=getStatus
    /cgi-bin/ptz.cgi?action=getCurrentProtocolCaps
    /cgi-bin/ptz.cgi?action=reset
    /cgi-bin/ptz.cgi?action=moveAbsolutely
    /cgi-bin/ptz.cgi?action=moveRelatively
    /cgi-bin/ptz.cgi?action=moveDirectly
    /cgi-bin/ptz.cgi?action=moveContinuously
    /cgi-bin/ptz.cgi?action=moveStop
    /cgi-bin/ptz.cgi?action=isMoving
    /cgi-bin/ptz.cgi?action=setFocusMode
    /cgi-bin/ptz.cgi?action=setFocusPoint
    /cgi-bin/ptz.cgi?action=focusManually
    /cgi-bin/ptz.cgi?action=setIrisMode
    /cgi-bin/ptz.cgi?action=setIrisValue
    /cgi-bin/ptz.cgi?action=adjustIris
    /cgi-bin/ptz.cgi?action=setPreset
    /cgi-bin/ptz.cgi?action=getPresets
    /cgi-bin/ptz.cgi?action=gotoPreset
    /cgi-bin/ptz.cgi?action=removePreset
    /cgi-bin/ptz.cgi?action=setHomePosition
    /cgi-bin/ptz.cgi?action=gotoHomePosition
    /cgi-bin/ptz.cgi?action=setTour
    /cgi-bin/ptz.cgi?action=getTours
    /cgi-bin/ptz.cgi?action=removeTour
    /cgi-bin/ptz.cgi?action=addTourPoint
    /cgi-bin/ptz.cgi?action=removeTourPoint
    /cgi-bin/ptz.cgi?action=tourStart
    /cgi-bin/ptz.cgi?action=autoTour
    /cgi-bin/ptz.cgi?action=tourStop
    /cgi-bin/ptz.cgi?action=patternRecordStart
    /cgi-bin/ptz.cgi?action=patternRecordStop
    /cgi-bin/ptz.cgi?action=getPatterns
    /cgi-bin/ptz.cgi?action=removePattern
    /cgi-bin/ptz.cgi?action=patternReplayStart
    /cgi-bin/ptz.cgi?action=patternReplayStop
    /cgi-bin/ptz.cgi?action=menuControl
    /cgi-bin/ptz.cgi?action=auxControl
    /cgi-bin/alarm.cgi?action=getInSlots
    /cgi-bin/alarm.cgi?action=getOutSlots
    /cgi-bin/alarm.cgi?action=getInState
    /cgi-bin/alarm.cgi?action=getOutState
    /cgi-bin/eventManager.cgi?action=getEventIndexes
    /cgi-bin/magicBox.cgi?action=reboot
    /cgi-bin/magicBox.cgi?action=shutdown
    /cgi-bin/magicBox.cgi?action=getDeviceType
    /cgi-bin/magicBox.cgi?action=getDeviceClass
    /cgi-bin/magicBox.cgi?action=getVendor
    /cgi-bin/magicBox.cgi?action=getHardwareVersion
    /cgi-bin/magicBox.cgi?action=getSerialNo
    /cgi-bin/magicBox.cgi?action=getMachineName
    /cgi-bin/magicBox.cgi?action=getLanguageCaps
    /cgi-bin/magicBox.cgi?action=getSystemInfo
    /cgi-bin/magicBox.cgi?action=getProductDefinition&name=MaxExtraStream
    /cgi-bin/magicBox.cgi?action=getSoftwareVersion
    /cgi-bin/magicBox.cgi?action=getBuildDate
    /cgi-bin/netApp.cgi?action=getInterfaces
    /cgi-bin/netApp.cgi?action=getUPnPStatus
    /cgi-bin/netApp.cgi?action=getVirtualServiceStatus
    /cgi-bin/encode.cgi?action=getConfigCaps
    /cgi-bin/encode.cgi?action=getCaps
    /cgi-bin/recordManager.cgi?action=getCaps
    /cgi-bin/eventManager.cgi?action=getCaps
    /cgi-bin/storage.cgi?action=getCaps
    /cgi-bin/snapManager.cgi?action=getCaps
    /cgi-bin/devVideoInput.cgi?action=getCaps
    /cgi-bin/global.cgi?action=getCurrentTime
    /cgi-bin/global.cgi?action=setCurrentTime&time=
    /cgi-bin/log.cgi?action=startFind
    /cgi-bin/log.cgi?action=doFind
    /cgi-bin/log.cgi?action=stopFind
    /cgi-bin/log.cgi?action=clear
    /cgi-bin/mediaFileFind.cgi?action=factory.create
    /cgi-bin/mediaFileFind.cgi?action=findFile
    /cgi-bin/mediaFileFind.cgi?action=findNextFile
    /cgi-bin/mediaFileFind.cgi?action=close
    /cgi-bin/mediaFileFind.cgi?action=destroy
    /cgi-bin/storageDevice.cgi?action=factory.getCollect
    /cgi-bin/storageDevice.cgi?action=factory.getPortInfo
    /cgi-bin/workGroup.cgi?action=factory.getCollect
    /cgi-bin/workDirectory.cgi?action=factory.getCollect
    /cgi-bin/devVideoInput.cgi?action=getCurrentWindow
    /cgi-bin/devVideoInput.cgi?action=setCurrentWindow
    /cgi-bin/ddns.cgi
    /cgi-bin/localSearch.cgi?
    /cgi-bin/localPlayback.cgi?
    /cgi-bin/split.cgi?action=getMode
    /cgi-bin/split.cgi?action=setMode
    /cgi-bin/split.cgi?action=enableTour
    /cgi-bin/devVideoInput.cgi?action=autoFocus
    /cgi-bin/devVideoInput.cgi?action=adjustFocusContinuously
    /cgi-bin/devVideoInput.cgi?action=adjustFocus
    /cgi-bin/devVideoInput.cgi?action=getFocusStatus
    /cgi-bin/devVideoAnalyse.cgi?action=getcaps
    /cgi-bin/wlan.cgi?action=scanWlanDevices
    /cgi-bin/IntervideoManager.cgi?action=getVersion
    /cgi-bin/storageDevice.cgi?action=getDeviceAllInfo
    /cgi-bin/storageDevice.cgi?action=setDevice
    /cgi-bin/devVideoInput.cgi?action=getCollect
    /cgi-bin/devAudioInput.cgi?action=getCollect
    /cgi-bin/devAudioOutput.cgi?action=getCollect
    /cgi-bin/trafficSnap.cgi?action=getParkingSpaceStatus
    /cgi-bin/trafficParking.cgi?action=getAllParkingSpaceStatus
    /cgi-bin/LogicDeviceManager.cgi?action=getCameraAll
    /cgi-bin/split.cgi?action=getScene
    /cgi-bin/monitorWallManager.cgi?action=addMonitorWall
    /cgi-bin/matrix.cgi?action=getCards
    /cgi-bin/matrix.cgi?action=getCardInfo
    /cgi-bin/split.cgi?action=setSource
    /cgi-bin/split.cgi?action=setRect
    /cgi-bin/split.cgi?action=openWindow
    /cgi-bin/split.cgi?action=closeWindow
    /cgi-bin/monitorWallManager.cgi?action=remove
    /cgi-bin/monitorWall.cgi?action=getScene
    /cgi-bin/monitorWall.cgi?action=setScene
    /cgi-bin/monitorWall.cgi?action=addBlock
    /cgi-bin/monitorWall.cgi?action=delBlock
    /cgi-bin/monitorWall.cgi?action=loadCollection
    /cgi-bin/monitorWall.cgi?action=saveCollection
    /cgi-bin/fastControl.cgi?action=addAreaCamera
    /cgi-bin/fastControl.cgi?action=delAreaCamera
    /cgi-bin/accessControl.cgi?action=openDoor
    /cgi-bin/accessControl.cgi?action=getDoorStatus
    /cgi-bin/recordFinder.cgi?action=doSeekFind
    /cgi-bin/recordFinder.cgi?action=getQuerySize
    /cgi-bin/recordFinder.cgi?action=find
    /cgi-bin/recordUpdater.cgi?action=insert
    /cgi-bin/recordUpdater.cgi?action=update
    /cgi-bin/recordUpdater.cgi?action=remove
    /cgi-bin/RadiometryManager.cgi?action=getCaps
    /cgi-bin/RadiometryManager.cgi?action=getRandomPointTemper
    /cgi-bin/RadiometryManager.cgi?action=getTemper
    /cgi-bin/VideoTalkPeer.cgi?action=detachState
    /cgi-bin/VideoTalkPeer.cgi?action=invite
    /cgi-bin/VideoTalkPeer.cgi?action=answer
    /cgi-bin/VideoTalkPeer.cgi?action=refuse
    /cgi-bin/VideoTalkPeer.cgi?action=cancel
    /cgi-bin/VideoTalkPeer.cgi?action=hangup

 

edit1: Added complete list

edit2: Added even more complete list

Share this post


Link to post
Share on other sites
I unpacked the sonia binary and read through the strings contained in the binary.

What tools do have used to unpack it and how did you do that?

Share this post


Link to post
Share on other sites
I unpacked the sonia binary and read through the strings contained in the binary.

What tools do have used to unpack it and how did you do that?

First i looked for strings in the packed sonia file:

strings sonia

While analysing the result i found the following lines:

$Info: This file is packed with the UPX executable packer http://upx.sf.net $
$Id: UPX 3.08 Copyright (C) 1996-2011 the UPX Team. All Rights Reserved. $

Then i googled a bit how to unpack a UPX packed file and found the solution:

apt install upx-ucl
upx -d sonia

The resulting file expands from originally 4MB to 12MB.

Then i searched again for contained strings and found a lot of them. To filter out the web API ones i used grep:

strings sonia | grep cgi-bin

Et voilà ...

Share this post


Link to post
Share on other sites

By the way, it is also the solution to find the hard coded telnet password. I mean the first part which you put in front of your self set password.

If you use the strings command on telnetd you find the following two lines:

Password:
7ujMko0

So whenever Dahua changes this (without changing the method to store it) we just need to unpack the firmware with the firmware-mod-kit and look into telnetd.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×