Wifi BLE Trailcam Investigation Part 2

Continued investigation, network packet capture, api reverse engineering and proof of concept

Continuing on from our previous investigation in part 1 of the Dsoon Wifi/BLE Trailcam..
After figuring out how to send a BLE command to the trailcam to enable “Wifi Mode”. Next thing to do, was to figure out the Android app communicate with the Trailcam and how the network communication works.

To accomplish this, I needed to get a network packet capture of the communication first.
The app of choice in this case was PCAPDroid.
PCAPDroid_SS
As described on the apps description:

“PCAPdroid is a privacy-friendly open source app which lets you track, analyze and block the connections made by the other apps in your device. It also allows you to export a PCAP dump of the traffic, extract metadata and much more!
PCAPdroid simulates a VPN in order to capture the network traffic without root. It does not use a remote VPN server. All the data is processed locally on the device.”

After installing the PCAPDroid app, and setting it up to capture the network traffic for the previously mentioned Dsoon Trailcam app, I proceeded to go through the trailcam’s app and tried to use every function possible to get a capture including all of the api data possible. Afterwards, I proceeded to download the pcap file and open it up in Wireshark.
PCAP_wifi_trailcam_Wireshark_SS
By filtering by “http” I was able to quickly get a list of all of the api requests along with the associated return data.

Next thing I did was go through this packet capture and do a “http request breakdown” document with each api request and the associated response data.
IE:

GET http://192.168.1.8/SetMode?Storage
-> OK
Data:
{  "Result" : 0  }

GET http://192.168.1.8/Storage?GetDirFileInfo
-> OK
Data:
{
"NumberOfDirs":1,
"NumberOfFiles":9,
"NumberOfJPG":6,
"NumberOfAVIS":3
}

GET http://192.168.1.8/Storage?GetFilePage=0&type=Photo
-> OK
Data:
{"number_of_files":6,"page":0,"fs":[{"n":"DSCF0001.JPG","t":1,"s":535405,"dt":1451168227,"fid":"000060C0000060C000400040"},{"n":"DSCF0002.JPG","t":1,"s":554528,"dt":1451168227,"fid":"000060C0000060C000600060"},{"n":"DSCF0004.JPG","t":1,"s":621909,"dt":1451168236,"fid":"000060C0000060C000A000A0"},{"n":"DSCF0005.JPG","t":1,"s":624228,"dt":1451168236,"fid":"000060C0000060C000C000C0"},{"n":"DSCF0007.JPG","t":1,"s":508852,"dt":1451296996,"fid":"000060C0000060C001000100"},{"n":"DSCF0008.JPG","t":1,"s":508877,"dt":1451296996,"fid":"000060C0000060C001200120"}]}
Jpeg file thumbnail requests notes:
User-Agent: Dalvik/2.1.0 (Linux; U; Android 7.1.1; SM-T350 Build/NMF26X)

GET http://192.168.1.8/Storage?GetFileThumb=000060C0000060C001000100
-> OK
Data:
JPEG FILE

GET http://192.168.1.8/Storage?GetFileThumb=000060C0000060C001200120
-> OK
Data:
JPEG FILE

GET http://192.168.1.8/Storage?Download=000060C0000060C000800080
-> OK
Data:
VIDEO/X-MSVIDEO File

GET http://192.168.1.8/Storage?Delete=000060C0000060C000E000E0
-> OK

Live Video Feed
GET http://192.168.1.8/SetMode?PhotoCapture
-> OK

GET http://192.168.1.8:8221/

Power off
GET http://192.168.1.8/Misc?PowerOff
-> OK

After going through an breaking down each unique api call / return data, I proceeded to make short summary document of all of the steps to enable wifi and use the api to perform different functions along with the details of the params.

1. To enable wifi, you need to send a command over bluetooth:
	Service:
		UUID: 0xFF00
		Characteristic:
			0xFF01
			Value:
				Hex: 42-54-5F-4B-65-79-5F-4f-6E
				ACII: "BT_Key_On"
				
2. Connect to Wifi Network "Trail Cam Pro ****" 
	Default Password: "12345678"

3. Summary of Wifi uri requests for DSOON Trail Cam Pro:
	Go into setup mode:
		GET http://192.168.1.8/SetMode?Setup
	
	Get Menu Options:
		GET http://192.168.1.8/Setup?GetMenuJson
	
	Go into "storage" mode:
		GET http://192.168.1.8/SetMode?Storage
	
	Get Directory File Info: (Summary # of available: Dirs, Files, JPEG Images, AVI Video Files)
		GET http://192.168.1.8/Storage?GetDirFileInfo
	
	Get File Page Data: (Detailed breakdown of: number of matching files for type, individual file breakdowns in nested list with file names: 'n', type: 't', size: 's', date/time: 'dt', file id: 'fid')
		GET http://192.168.1.8/Storage?GetFilePage=%page #=""%&type=%type%
			PAGE #: 0 delimited number
			TYPES: "Photo", "Video"
		
	Download File Thumbnail Image:
		GET http://192.168.1.8/Storage?GetFileThumb=%file id=""%
			FILE ID: matching 'fid' from file page data
		
	Download File:
		GET http://192.168.1.8/Storage?Download=%file id=""%
			FILE ID: matching 'fid' from file page data
	
	Delete File:
		GET http://192.168.1.8/Storage?Delete=%file id=""%
			FILE ID: matching 'fid' from file page data
	
	Enable Live Video Feed: (Live feed is available at http://192.168.1.8:8221/)
		GET http://192.168.1.8/SetMode?PhotoCapture
	
	Turn off WIFI
		GET http://192.168.1.8/Misc?PowerOff

By doing this, it helped me to map out functions and workout the next steps to trying to perform the tasks programmatically.

Finally, came the time to take the information gathered above and use it to interface with the Trailcam programmatically with using other devices.
For the first proof of concept of wanted to see if it would be possible to do so with the lowest cost solution I could find. Having a few ESP-32 wifi/bluetooth capable microcontrollers around, I figured why not give it a try.
esp32 microcontroller
I opened up the Arduino IDE and got to work. I started with the examples provided with the esp libraries and familiarized myself with how things worked and then broke the project into parts solving each step at a time to getting the files off of the camera.

After about a week of testing / iterating on each of the separate steps I managed to get a piece of code that could scan for the Trailcam’s Bluetooth device, connect to the Trailcam using BLE, remotely trigger “wifi” mode, scan wifi networks, find the Trailcam’s AP, connect and interact with the api, and disable the “wifi” mode when done, all while printing the debug info to the serial port.

Some of the limitations I ran into along the way:

  • The bluetooth and wifi scanning/connection needed to have additional error handling and retry logic to function reliably.
  • Using all of the libraries required was too large for the default partitioning scheme so I had to modify the settings in Arduino IDE to use partitioning scheme: “Huge APP (3MB No OTA/1MB SPIFFS)” in order to successfully build/upload the code to the ESP-32 mcu.
  • Since the files are relatively large, I would need to use an sd card module to actually do anything useful with the files.
  • Having only 1 network interface makes this impractical if I wanted to use it as true “bridge” device, they do make ESP-32 dev boards with a secondary Ethernet interface, but I am not sure if its practical with an sd card module.

Given all of the above limitations and the cost perspective, I came to the conclusion it may not make sense to try to engineer a bridge device using the ESP-32, so I just opted to stick with a basic proof of concept. The code is available up on my github here which pulls the a list of all of the file names / file ids from the trailcam and prints them out over serial.

Maybe It might be worth revisiting at some point, but I think a better solution may be a small single board computer or router. This extra power will allow us to extend the functionality of our final solution quite a bit.

In my next post on this investigation, I will go over how I solved this problem with a cost effective solution without a Raspberry Pi (given their current ridiculous markup), extended the functionality further and what I plan to do in the future to round out a solution.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.