Saturday, July 1, 2017

Getting still image URL/URI of an ipcam OR just how to query onvif ip cameras

The net is full of to much TLDR info about ipcams...
Here is a short tutorial on running ONVIF queries to your ipcam to check which URLs do what.

ONVIF is a universal spec that tries to unify function calls to all supported ip cameras.
The problem is ONVIF organization is really the type of "we like to document a lot but not give short examples on how to use" type of org (maybe they should start thinking in the direction of open sourcing and supporting sites that try to explain their specs instead of hunting them down for posting a spec that is hidden in their own "membership" areas on their site)

So here is the short "Hello World" on ONVIF and ipcams:

Lets go through a learning experience - i have a cheap ali express ip cam and i want to figure out which cam URLs are used for streaming video and which cam URLs can give me a still image.

I want this because i want to port forward these specific ports and be able to access them directly and not via some P2P Chinese service app that wants all permissions on my android...(RTSP streaming video can be opened on many standard android apps and on vlc)

STEPS:

1. Connect

Physically connect the cam to the router on your home LAN using an ethernet cable - fairly easy
Note that there are wifi ipcams and ethernet ipcams - both have an option to connect an ethernet cable
The good ones will be pre-configured to get an IP from DHCP
The bad ones will have some preconfigured ip address, but they can be changed to DHCP, you just need to connect to their http address and change it (wait but i don't know their IP ....?! - try changing your router to 10.0.0.X subnet or 192.168.1.X subnet and connecting just a computer and your cam, then see next section on how to find them)

2. Discover ip/port 

Lets find the ip and port of the ONVIF service on the cam -
First, how to check i found the correct ip and port-
just enter in your browser and see a SOAP response like this:
for example enter: http://192.168.14.41:8899/

and get:

SOAP-ENV:ClientHTTP GET method not implemented

that means we found it (never mind about the error - we will see about that later)

So how to find the ip/port:
option A: if you know how to enter your router's http and check connected clients you can do that to find the IP, then you will have to scan that ip or try some well known ONVIF ports (e.g. 8899/1018)

option B: install "Fing" on your android cellphone - it will scan your local net and find it. again you will need to find the correct port

option C: install "Onvif device manager" or "iSpy" on your windows machine - they will scan your net and ports and find the ipcams and their onvif ports for you

3. Lets talk Onvif language with our cam-

Onvif speaks SOAP protocol - we will need a browser add-on to make life easier for us because we are too lazy to program stuff (or write long command lines with 'curl') -

In firefox, go to add-ons and click extensions, and add "RESTClient" extension +restart firefox.
Lets start by telling the device we want some general information -
lets assume my ip/port are 192.168.14.51:8899

Click on the RESTClient red rectangular button on the top of the browser and you will get this screen:


When you enter a URL in the browser address bar it uses http GET protocol. SOAP uses http POST protocol, which besides the URL has a "BODY" part too - so  we will use the add-on to sent the POST commands (this can be done in linux/windows command line using "curl" too).

change the "Method" to POST
in the URL put http://192.168.14.51:8899
in the BODY put:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
 xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
<SOAP-ENV:Body>
    <tds:GetDeviceInformation/>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>


 


click "SEND"

on the bottom part in "Response" change the tab to "Response Body (highlight)"
skip all the bloated SOAP-ENV xml shit, and in the bottom you will see something like:

<SOAP-ENV:Body>
 <tds:GetDeviceInformationResponse>
   <tds:Manufacturer>H264</tds:Manufacturer>
   <tds:Model>50H20L_S39</tds:Model>
   <tds:FirmwareVersion>V4.02.R11.00002520.10010.242900.ONVIF 2.4</tds:FirmwareVersion>
   <tds:SerialNumber>1b011f97f22424de</tds:SerialNumber>
   <tds:HardwareId>00001</tds:HardwareId>
 </tds:GetDeviceInformationResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>



Great ! it works ! (if not, then your ip/port are not correct or your ip camera 
does not support onvif)

4. Check video stream URLs

everything same as before just change the body:


<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:trt="http://www.onvif.org/ver10/media/wsdl">
   <soap:Body>
      <trt:GetProfiles/>
   </soap:Body>
</soap:Envelope>

  
    

click SEND

as usual, skip all the soap shit and got to the bottom of the response (in the response body tab not response headers tab!)

you will get a list a profiles with their tokens and resolutions etc...:

<SOAP-ENV:Body>
 <trt:GetProfilesResponse>
   <trt:Profiles fixed="true" token="000">
     <tt:Name>Profile_000</tt:Name>
     <tt:VideoSourceConfiguration token="000">
       <tt:Name>VideoS_000</tt:Name>
       <tt:UseCount>3</tt:UseCount>
       <tt:SourceToken>000</tt:SourceToken>
       <tt:Bounds height="1080" width="1920" y="0" x="0">
       </tt:Bounds>
     </tt:VideoSourceConfiguration>
     <tt:AudioSourceConfiguration token="000">
       <tt:Name>Audio_000</tt:Name>
       <tt:UseCount>2</tt:UseCount>
       <tt:SourceToken>000</tt:SourceToken>
     </tt:AudioSourceConfiguration>
     <tt:VideoEncoderConfiguration token="000">
       <tt:Name>VideoE_000</tt:Name>
       <tt:UseCount>1</tt:UseCount>
       <tt:Encoding>H264</tt:Encoding>
       <tt:Resolution>
         <tt:Width>1920</tt:Width>
         <tt:Height>1080</tt:Height>
       </tt:Resolution>
       <tt:Quality>4</tt:Quality>

:
<----cut ----="" here="" response="">

now lets get the URL of a specific profile token ("000"). Send this body:
 
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> <soap:Body> <trt:GetStreamUri> <trt:StreamSetup> <tt:Stream>RTP-Unicast</tt:Stream> <tt:Transport> <tt:Protocol>UDP</tt:Protocol> </Transport> </trt:StreamSetup> <trt:ProfileToken>000</trt:ProfileToken> </trt:GetStreamUri> </soap:Body> </soap:Envelope>

and you get this kind of response containing the URL:
<SOAP-ENV:Body>
  <trt:GetStreamUriResponse>
    <trt:MediaUri>
      <tt:Uri>rtsp://192.168.14.51:554/user=admin_password=1234_channel=1_stream=0.sdp?real_stream</tt:Uri>
      <tt:InvalidAfterConnect>false</tt:InvalidAfterConnect>
      <tt:InvalidAfterReboot>false</tt:InvalidAfterReboot>
      <tt:Timeout>PT10S</tt:Timeout>
    </trt:MediaUri>
  </trt:GetStreamUriResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>



lets test it:
open it (rtsp://192.168.14.51:554/user=admin_password=1234_channel=1_stream=0.sdp?real_stream)
in VLC (window/android) or some other RTSP Player (i like android VXG RTSP player)
it should show the live stream
(note vlc tends to crash some times. try a different app or VLC beta if this happens)

5. check still image (jpg) URL

send this body (update the profile token id to yours):
 
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> <soap:Body> <trt:GetSnapshotUri > <trt:ProfileToken>000</trt:ProfileToken> </trt:GetSnapshotUri> </soap:Body> </soap:Envelope>

you should get something like:

<SOAP-ENV:Body>
 <trt:GetSnapshotUriResponse>
   <trt:MediaUri>
     <tt:Uri>http://192.168.14.51/webcapture.jpg?command=snap&amp;channel=1</tt:Uri>
     <tt:InvalidAfterConnect>false</tt:InvalidAfterConnect>
     <tt:InvalidAfterReboot>false</tt:InvalidAfterReboot>
     <tt:Timeout>PT10S</tt:Timeout>
   </trt:MediaUri>
 </trt:GetSnapshotUriResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>





Paste the URL in the browser URL section it check if it works ... :)

6. Other cool stuff you can do with onvif

There are a lot of things you can do with onvif
A spec PDF can be found here:
http://www.openipcam.com/files/ONVIF/ONVIF_WG-APG-Application_Programmer's_Guide.pdf
(openipcam is a great resource site)
skip directly to "appendix B2" with the SOAP examples.
I am sure you will manage from there ...


7. Security

You ip cam is a basically a linux box. lately too many ip cams have been 
victims of hosting malware/botnet/viruses.

These cams can easily hide a program waiting for a C&C server to tell them to start blasting 
an IP with denial of service packets or just be used as proxy for hacking activities.

I recommend - reserve your ip cam a dedicated ip in your router or just assign it a 
static ip + set firewall rules in your router not to let any packet in/out (especially out)
if it is not on the port you are using.

Also change the defaul user/passwords

Also - from time to time bring up wireshark on your localnet and just look at the traffic.



 

18 comments:

  1. Super useful article, thank you :)

    I have a 'V380E' camera which this has helped me to get running with VLC.

    On the subject of blocking it from using the Internet - yes 100% agree. These things are a botnet-by-design - most of https://pierrekim.github.io/blog/2017-03-08-camera-goahead-0day.html still applies

    I blocked all traffic from and to mine, but then the time would always be stuck in 1970. I noticed with tcpdump that one of the many NTP servers it tries to reach is 'time.nasa.gov'.

    I set up a fake DNS entry on my local resolver for time.nasa.gov to point to an NTP server on the local network, and hey presto the time works again :)

    ReplyDelete
  2. Thanks this post help me a lot. I picked up a Rosewill SHIELDeye RSCM-121001W and didn't even know what ONVIF was until I went searching for the snapshot URL. A couple hints that might help others starting out as ignorant as me:

    The base URL for my camera is the view/manage webpage. The SOAP URL that responds to ONVIF queries is http://ip:port/onvif/device_service. I found this by temporarily installing ONVIF Device Manager.

    One I got that right all the queries still came back sender not authorized even though I had specified a username/password in RESTclient. A little more research and it seems ONVIF has its own security that was a little too complex for me to fake without some programming. Fortunately I stumbled on a network setting in my camera ONVIF checking that when disabled allowed things to work.

    Thanks again!

    ReplyDelete
  3. Where is the button to thumb it up? :)
    Thanks a lot.

    ReplyDelete
  4. Very good tutorial!! Congratulations

    ReplyDelete
  5. Great article, thank you for sharing information about querying onvif ip camera

    ReplyDelete
  6. Great guide, thanka a lot.

    Just a details to add: when you prepare the SOAP commands remeber to set the "body content type" to "application/xml".

    My cameras don't answer to the POST without it.
    Thanks again.

    ReplyDelete
  7. thanks for this post, through this i just realised that there is a way to access the stream to my cam without authentication! good i already had a firewall setup.

    ReplyDelete
  8. How to enter username and password for authentication. I've added authorization but still prompt to enter username/password

    ReplyDelete
    Replies
    1. user and password are parameters in the URL (See examples above) if you still get a popup requesting them then: 1) you did not use the correct user and password OR 2) you did not put them correctly in the URL (URL parameters are typically separated from the URL with '&' between them , while the first one is separated with '?')

      Delete
  9. Thanks for this pots. I have been perfect to understand the ONVIF protocol

    ReplyDelete
  10. Where do I have to enter onvif "user and password" intro de BODY, because I get response but I cannot access to the second part due to authorization

    ReplyDelete
  11. Where do I have to enter my onvif "user and password" into BODY because I get respones at the beggining but when I try second part I cannot access due to authorization

    ReplyDelete
  12. Thanks a lot for your article. I have a problem though. When I try to get the device profiles, I get "wsse:InvalidSecurity" error. I tried to add the soap:Header section with wsse:Security where I put my username and password but then I get "wsse:FailedAuthentication" error. I can't find any simple example of this authentication so I'm stuck here. The "ONVIF device manager" works well with this camera so I'm pretty sure there is a way.

    ReplyDelete
  13. Thank you so much to share and informative post.

    Here we will give you a guide on the best IP camera price in Pakistan

    ReplyDelete
  14. This just saved me a ton of time and gave me exactly what I was looking for so I can use my cameras in Home Assistant.

    Thanks very much for taking the time to put this out there!

    ReplyDelete
  15. Brilliant stuff. I had been searching for the Still Image url, to add my IP Cam into Home Assistant, so this found it for me

    ReplyDelete

Feel free to comment. No links/URLs allowed in comments.